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>
25 #include <afs/errmap_nt.h>
32 /* opendir() - The case insensitive version of opendir */
33 DIR *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 int len = strlen(tPath) - 1;
62 if (len >= 2 && tPath[len-2] != ':') {
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));
86 memset((void*)tDir, 0, sizeof(*tDir));
93 int closedir(DIR *dir)
95 if (!dir || !dir->h) {
100 if (dir->h != INVALID_HANDLE_VALUE)
106 struct dirent *readdir(DIR *dir)
112 return (struct dirent*)0;
116 if (dir->h == INVALID_HANDLE_VALUE)
117 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;