Updates to Tomato RAF including NGINX && PHP
[tomato.git] / release / src / router / php / win32 / readdir.c
blob9525fc0d6b4995dbcad79e1c93548e83bed91a4f
1 #include <malloc.h>
2 #include <string.h>
3 #include <errno.h>
5 #include "php.h"
6 #include "readdir.h"
7 #include "TSRM.h"
8 /**********************************************************************
9 * Implement dirent-style opendir/readdir/rewinddir/closedir on Win32
11 * Functions defined are opendir(), readdir(), rewinddir() and
12 * closedir() with the same prototypes as the normal dirent.h
13 * implementation.
15 * Does not implement telldir(), seekdir(), or scandir(). The dirent
16 * struct is compatible with Unix, except that d_ino is always 1 and
17 * d_off is made up as we go along.
19 * The DIR typedef is not compatible with Unix.
20 **********************************************************************/
22 DIR *opendir(const char *dir)
24 DIR *dp;
25 char *filespec;
26 HANDLE handle;
27 int index;
28 char resolved_path_buff[MAXPATHLEN];
29 TSRMLS_FETCH();
31 if (!VCWD_REALPATH(dir, resolved_path_buff)) {
32 return NULL;
35 filespec = (char *)malloc(strlen(resolved_path_buff) + 2 + 1);
36 if (filespec == NULL) {
37 return NULL;
39 strcpy(filespec, resolved_path_buff);
40 index = strlen(filespec) - 1;
41 if (index >= 0 && (filespec[index] == '/' ||
42 (filespec[index] == '\\' && (index == 0 || !IsDBCSLeadByte(filespec[index-1])))))
43 filespec[index] = '\0';
44 strcat(filespec, "\\*");
46 dp = (DIR *) malloc(sizeof(DIR));
47 if (dp == NULL) {
48 return NULL;
50 dp->offset = 0;
51 dp->finished = 0;
53 if ((handle = FindFirstFile(filespec, &(dp->fileinfo))) == INVALID_HANDLE_VALUE) {
54 DWORD err = GetLastError();
55 if (err == ERROR_NO_MORE_FILES || err == ERROR_FILE_NOT_FOUND) {
56 dp->finished = 1;
57 } else {
58 free(dp);
59 free(filespec);
60 return NULL;
63 dp->dir = strdup(resolved_path_buff);
64 dp->handle = handle;
65 free(filespec);
67 return dp;
70 struct dirent *readdir(DIR *dp)
72 if (!dp || dp->finished)
73 return NULL;
75 if (dp->offset != 0) {
76 if (FindNextFile(dp->handle, &(dp->fileinfo)) == 0) {
77 dp->finished = 1;
78 return NULL;
81 dp->offset++;
83 strlcpy(dp->dent.d_name, dp->fileinfo.cFileName, _MAX_FNAME+1);
84 dp->dent.d_ino = 1;
85 dp->dent.d_reclen = strlen(dp->dent.d_name);
86 dp->dent.d_off = dp->offset;
88 return &(dp->dent);
91 int readdir_r(DIR *dp, struct dirent *entry, struct dirent **result)
93 if (!dp || dp->finished) {
94 *result = NULL;
95 return 0;
98 if (dp->offset != 0) {
99 if (FindNextFile(dp->handle, &(dp->fileinfo)) == 0) {
100 dp->finished = 1;
101 *result = NULL;
102 return 0;
105 dp->offset++;
107 strlcpy(dp->dent.d_name, dp->fileinfo.cFileName, _MAX_FNAME+1);
108 dp->dent.d_ino = 1;
109 dp->dent.d_reclen = strlen(dp->dent.d_name);
110 dp->dent.d_off = dp->offset;
112 memcpy(entry, &dp->dent, sizeof(*entry));
114 *result = &dp->dent;
116 return 0;
119 int closedir(DIR *dp)
121 if (!dp)
122 return 0;
123 /* It is valid to scan an empty directory but we have an invalid
124 handle in this case (no first file found). */
125 if (dp->handle != INVALID_HANDLE_VALUE) {
126 FindClose(dp->handle);
128 if (dp->dir)
129 free(dp->dir);
130 if (dp)
131 free(dp);
133 return 0;
136 int rewinddir(DIR *dp)
138 /* Re-set to the beginning */
139 char *filespec;
140 HANDLE handle;
141 int index;
143 FindClose(dp->handle);
145 dp->offset = 0;
146 dp->finished = 0;
148 filespec = (char *)malloc(strlen(dp->dir) + 2 + 1);
149 if (filespec == NULL) {
150 return -1;
153 strcpy(filespec, dp->dir);
154 index = strlen(filespec) - 1;
155 if (index >= 0 && (filespec[index] == '/' ||
156 (filespec[index] == '\\' && (index == 0 || !IsDBCSLeadByte(filespec[index-1])))))
157 filespec[index] = '\0';
158 strcat(filespec, "/*");
160 if ((handle = FindFirstFile(filespec, &(dp->fileinfo))) == INVALID_HANDLE_VALUE) {
161 dp->finished = 1;
164 dp->handle = handle;
165 free(filespec);
167 return 0;