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
= calloc(1, sizeof(DIR));
91 if (!dir
|| !dir
->h
) {
96 if (dir
->h
!= INVALID_HANDLE_VALUE
)
109 return (struct dirent
*)0;
113 if (dir
->h
== INVALID_HANDLE_VALUE
)
114 return (struct dirent
*)0;
119 while (rc
= FindNextFile(dir
->h
, &dir
->data
)) {
120 if ((strcmp(dir
->data
.cFileName
, ".") == 0)
121 || (strcmp(dir
->data
.cFileName
, "..") == 0)) {
123 continue; /* skip "." and ".." */
125 break; /* found a non '.' or '..' entry. */
127 if (rc
== 0) { /* FindNextFile() failed */
128 if (GetLastError() == ERROR_NO_MORE_FILES
)
129 return (struct dirent
*)0;
131 errno
= nterr_nt2unix(GetLastError(), EBADF
);
132 return (struct dirent
*)0;
137 dir
->cdirent
.d_name
= dir
->data
.cFileName
;
138 return &dir
->cdirent
;