456{
460 unsigned char *entry_buf =
NULL;
464
467
468 dprintf(1,
"-> handle_nfs41_dirquery(%s,%d,%d,%d)\n",
470
471 args->query_reply_len = 0;
472
473 if (
args->initial ||
args->restart) {
475 if (!
state->cookie.cookie)
476 dprintf(1,
"initializing the 1st readdir cookie\n");
477 else if (
args->restart)
478 dprintf(1,
"restarting; clearing previous cookie %llu\n",
479 state->cookie.cookie);
480 else if (
args->initial)
481 dprintf(1,
"*** initial; clearing previous cookie %llu!\n",
482 state->cookie.cookie);
483 }
else if (!
state->cookie.cookie) {
484 dprintf(1,
"handle_nfs41_readdir: EOF\n");
487 }
488
489 entry_buf =
calloc(max_buf_len,
sizeof(
unsigned char));
490 if (entry_buf ==
NULL) {
492 goto out_free_cookie;
493 }
494fetch_entries:
495 entry_buf_len = max_buf_len;
496
499
501
502
505
506 if (
args->filter[0] ==
'*' &&
args->filter[1] ==
'\0') {
508 entry_buf_len, &dots_len, &dots_next_offset);
510 goto out_free_cookie;
511 entry_buf_len -= dots_len;
512 }
513
514 if (dots_len &&
args->single) {
515 dprintf(2,
"skipping nfs41_readdir because the single query "
516 "will use . or ..\n");
517 entry_buf_len = 0;
519 } else {
520 dprintf(2,
"calling nfs41_readdir with cookie %llu\n",
521 state->cookie.cookie);
523 &attr_request, &
state->cookie, entry_buf + dots_len,
524 &entry_buf_len, &
eof);
526 dprintf(1,
"nfs41_readdir failed with %s\n",
529 goto out_free_cookie;
530 }
531 }
532
533 if (!entry_buf_len && dots_next_offset)
534 *dots_next_offset = 0;
535 entry_buf_len += dots_len;
536 } else {
537
542 entry->next_entry_offset = 0;
543
548 goto out_free_cookie;
549 }
550 entry_buf_len =
entry->name_len +
552
554 }
555
557
558 if (entry_buf_len) {
559 unsigned char *entry_pos = entry_buf;
560 unsigned char *dst_pos =
args->kbuf;
564
565 for (;;) {
568
569 dprintf(2,
"filter %s looking at %s with cookie %d\n",
574 dprintf(2,
"not enough space to copy entry %s (cookie %d)\n",
576 break;
577 }
580 }
582
583
584 if (!
entry->next_entry_offset)
585 break;
586
587
588 if (
args->single && last_offset) {
590 break;
591 }
592 entry_pos +=
entry->next_entry_offset;
593 }
594 args->query_reply_len =
args->buf_len - dst_len;
595 if (last_offset) {
596 *last_offset = 0;
598 dprintf(1,
"no entries matched; fetch more\n");
599 goto fetch_entries;
600 }
601 }
602
604 dprintf(1,
"we don't need to save a cookie\n");
605 goto out_free_cookie;
606 } else
607 dprintf(1,
"saving cookie %llu\n",
state->cookie.cookie);
608
609out_free_entry:
612 dprintf(1,
"<- handle_nfs41_dirquery(%s,%d,%d,%d) returning ",
617 dprintf(1,
"ERROR_FILE_NOT_FOUND.\n");
618 break;
620 dprintf(1,
"ERROR_NO_MORE_FILES.\n");
621 break;
625 break;
626 default:
628 break;
629 }
630 } else {
632 }
634out_free_cookie:
635 state->cookie.cookie = 0;
636 goto out_free_entry;
637}
ACPI_SIZE strlen(const char *String)
char * strchr(const char *String, int ch)
int nfs_to_windows_error(int status, int default_error)
const char * nfs_error_string(int status)
#define ERROR_FILE_NOT_FOUND
static __inline void nfs41_superblock_getattr_mask(IN const nfs41_superblock *superblock, OUT bitmap4 *attrs)
@ FATTR4_WORD0_RDATTR_ERROR
#define NFS41_MAX_COMPONENT_LEN
nfs41_updowncall_list upcall
int nfs41_readdir(IN nfs41_session *session, IN nfs41_path_fh *file, IN bitmap4 *attr_request, IN nfs41_readdir_cookie *cookie, OUT unsigned char *entries, IN OUT uint32_t *entries_len, OUT bool_t *eof_out)
static int readdir_filter(const char *filter, const char *name)
static int readdir_add_dots(IN readdir_upcall_args *args, IN OUT unsigned char *entry_buf, IN uint32_t entry_buf_len, OUT uint32_t *len_out, OUT uint32_t **last_offset)
static int readdir_copy_entry(IN readdir_upcall_args *args, IN nfs41_readdir_entry *entry, IN OUT unsigned char **dst_pos, IN OUT uint32_t *dst_len)
static int lookup_entry(IN nfs41_root *root, IN nfs41_session *session, IN nfs41_path_fh *parent, OUT nfs41_readdir_entry *entry)
_Check_return_ _CRTIMP int __cdecl __cdecl eof(_In_ int _FileHandle)
STRSAFEAPI StringCbCopyA(STRSAFE_LPSTR pszDest, size_t cbDest, STRSAFE_LPCSTR pszSrc)
#define FIELD_OFFSET(t, f)
DWORD WINAPI GetLastError(void)
#define ERROR_BUFFER_OVERFLOW
#define ERROR_BAD_NET_RESP
#define ERROR_NO_MORE_FILES