2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
11 * readdir.c - A minimal implementation of readdir to ease porting of AFS to
12 * NT. Include dirent.h to pickup the required structs and prototypes.
14 * Implemented routines:
19 #include <afsconfig.h>
20 #include <afs/param.h>
24 #include <afs/errmap_nt.h>
31 /* opendir() - The case insensitive version of opendir */
33 opendir(const char *path)
38 WIN32_FIND_DATA tData;
41 (void)strcpy(tPath, path);
42 (void)strcat(tPath, "\\*");
43 tH = FindFirstFile(tPath, &tData);
45 if (tH == INVALID_HANDLE_VALUE) {
46 ntErr = GetLastError();
51 case ERROR_BAD_PATHNAME:
52 /* AFS NT client returns ERROR_BAD_PATHNAME where it should return
55 case ERROR_FILE_NOT_FOUND:
56 /* If at the "root" directory, then this can happen if it's empty.
60 size_t len = strlen(tPath) - 1;
62 if (len >= 2 && tPath[len - 2] != ':') {
63 tPath[len - 1] = '\0';
65 if (stat(tPath, &status) < 0) {
66 errno = nterr_nt2unix(GetLastError(), ENOENT);
69 if (!(status.st_mode & _S_IFDIR)) {
76 errno = nterr_nt2unix(GetLastError(), ENOENT);
81 tDir = (DIR *) malloc(sizeof(DIR));
85 memset((void *)tDir, 0, sizeof(*tDir));
95 if (!dir || !dir->h) {
100 if (dir->h != INVALID_HANDLE_VALUE)
113 return (struct dirent *)0;
117 if (dir->h == INVALID_HANDLE_VALUE)
118 return (struct dirent *)0;
123 while (rc = FindNextFile(dir->h, &dir->data)) {
124 if ((strcmp(dir->data.cFileName, ".") == 0)
125 || (strcmp(dir->data.cFileName, "..") == 0)) {
127 continue; /* skip "." and ".." */
129 break; /* found a non '.' or '..' entry. */
131 if (rc == 0) { /* FindNextFile() failed */
132 if (GetLastError() == ERROR_NO_MORE_FILES)
133 return (struct dirent *)0;
135 errno = nterr_nt2unix(GetLastError(), EBADF);
136 return (struct dirent *)0;
141 dir->cdirent.d_name = dir->data.cFileName;
142 return &dir->cdirent;