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>
28 /* opendir() - The case insensitive version of opendir */
30 opendir(const char *path)
35 WIN32_FIND_DATA tData;
38 (void)strcpy(tPath, path);
39 (void)strcat(tPath, "\\*");
40 tH = FindFirstFile(tPath, &tData);
42 if (tH == INVALID_HANDLE_VALUE) {
43 ntErr = GetLastError();
48 case ERROR_BAD_PATHNAME:
49 /* AFS NT client returns ERROR_BAD_PATHNAME where it should return
52 case ERROR_FILE_NOT_FOUND:
53 /* If at the "root" directory, then this can happen if it's empty.
57 size_t len = strlen(tPath) - 1;
59 if (len >= 2 && tPath[len - 2] != ':') {
60 tPath[len - 1] = '\0';
62 if (stat(tPath, &status) < 0) {
63 errno = nterr_nt2unix(GetLastError(), ENOENT);
66 if (!(status.st_mode & _S_IFDIR)) {
73 errno = nterr_nt2unix(GetLastError(), ENOENT);
78 tDir = (DIR *) malloc(sizeof(DIR));
82 memset((void *)tDir, 0, sizeof(*tDir));
92 if (!dir || !dir->h) {
97 if (dir->h != INVALID_HANDLE_VALUE)
110 return (struct dirent *)0;
114 if (dir->h == INVALID_HANDLE_VALUE)
115 return (struct dirent *)0;
120 while (rc = FindNextFile(dir->h, &dir->data)) {
121 if ((strcmp(dir->data.cFileName, ".") == 0)
122 || (strcmp(dir->data.cFileName, "..") == 0)) {
124 continue; /* skip "." and ".." */
126 break; /* found a non '.' or '..' entry. */
128 if (rc == 0) { /* FindNextFile() failed */
129 if (GetLastError() == ERROR_NO_MORE_FILES)
130 return (struct dirent *)0;
132 errno = nterr_nt2unix(GetLastError(), EBADF);
133 return (struct dirent *)0;
138 dir->cdirent.d_name = dir->data.cFileName;
139 return &dir->cdirent;