1 /*------------------------------------------------------------------------------
2 * Copyright (C) 2003-2006 Matt J. Weinstein
3 *
4 * Distributable under the terms of either the Apache License (Version 2.0) or
5 * the GNU Lesser General Public License, as specified in the COPYING file.
6 ------------------------------------------------------------------------------*/
7 #include "CLucene/StdHeader.h"
8
9 #if !defined(_CL_HAVE_DIRENT_H) && !defined(_CL_HAVE_SYS_NDIR_H) && !defined(_CL_HAVE_SYS_DIR_H) && !defined(_CL_HAVE_NDIR_H)
10 #include "dirent.h"
11
12 DIR *
opendir(const char * szPath)13 opendir (const char *szPath)
14 {
15 DIR *nd;
16 char szFullPath[CL_MAX_PATH];
17
18 errno = 0;
19
20 if (!szPath)
21 {
22 errno = EFAULT;
23 return NULL;
24 }
25
26 if (szPath[0] == '\0')
27 {
28 errno = ENOTDIR;
29 return NULL;
30 }
31
32 /* Attempt to determine if the given path really is a directory. */
33 struct _stat rcs;
34 if ( _stat(szPath,&rcs) == -1)
35 {
36 /* call GetLastError for more error info */
37 errno = ENOENT;
38 return NULL;
39 }
40 if (!(rcs.st_mode & _S_IFDIR))
41 {
42 /* Error, entry exists but not a directory. */
43 errno = ENOTDIR;
44 return NULL;
45 }
46
47 /* Make an absolute pathname. */
48 _realpath(szPath,szFullPath);
49
50 /* Allocate enough space to store DIR structure and the complete
51 * directory path given. */
52 //nd = (DIR *) malloc (sizeof (DIR) + _tcslen (szFullPath) + _tcslen (DIRENT_SLASH) +
53 // _tcslen (DIRENT_SEARCH_SUFFIX)+1);
54 nd = new DIR;
55
56 if (!nd)
57 {
58 /* Error, out of memory. */
59 errno = ENOMEM;
60 return NULL;
61 }
62
63 /* Create the search expression. */
64 strcpy (nd->dd_name, szFullPath);
65
66 /* Add on a slash if the path does not end with one. */
67 if (nd->dd_name[0] != '\0' &&
68 nd->dd_name[strlen (nd->dd_name) - 1] != '/' &&
69 nd->dd_name[strlen (nd->dd_name) - 1] != '\\')
70 {
71 strcat (nd->dd_name, DIRENT_SLASH);
72 }
73
74 /* Add on the search pattern */
75 strcat (nd->dd_name, DIRENT_SEARCH_SUFFIX);
76
77 /* Initialize handle to -1 so that a premature closedir doesn't try
78 * to call _findclose on it. */
79 nd->dd_handle = -1;
80
81 /* Initialize the status. */
82 nd->dd_stat = 0;
83
84 /* Initialize the dirent structure. ino and reclen are invalid under
85 * Win32, and name simply points at the appropriate part of the
86 * findfirst_t structure. */
87 //nd->dd_dir.d_ino = 0;
88 //nd->dd_dir.d_reclen = 0;
89 nd->dd_dir.d_namlen = 0;
90 nd->dd_dir.d_name = nd->dd_dta.name;
91
92 return nd;
93 }
94
95
readdir(DIR * dirp)96 struct dirent * readdir (DIR * dirp)
97 {
98 errno = 0;
99
100 /* Check for valid DIR struct. */
101 if (!dirp)
102 {
103 errno = EFAULT;
104 return NULL;
105 }
106
107 if (dirp->dd_dir.d_name != dirp->dd_dta.name)
108 {
109 /* The structure does not seem to be set up correctly. */
110 errno = EINVAL;
111 return NULL;
112 }
113
114 bool bCallFindNext = true;
115
116 if (dirp->dd_stat < 0)
117 {
118 /* We have already returned all files in the directory
119 * (or the structure has an invalid dd_stat). */
120 return NULL;
121 }
122 else if (dirp->dd_stat == 0)
123 {
124 /* We haven't started the search yet. */
125 /* Start the search */
126 dirp->dd_handle = _findfirst (dirp->dd_name, &(dirp->dd_dta));
127
128 if (dirp->dd_handle == -1)
129 {
130 /* Whoops! Seems there are no files in that
131 * directory. */
132 dirp->dd_stat = -1;
133 }
134 else
135 {
136 dirp->dd_stat = 1;
137 }
138
139 /* Dont call _findnext first time. */
140 bCallFindNext = false;
141 }
142
143 while (dirp->dd_stat > 0)
144 {
145 if (bCallFindNext)
146 {
147 /* Get the next search entry. */
148 if (_findnext (dirp->dd_handle, &(dirp->dd_dta)))
149 {
150 /* We are off the end or otherwise error. */
151 _findclose (dirp->dd_handle);
152 dirp->dd_handle = -1;
153 dirp->dd_stat = -1;
154 return NULL;
155 }
156 else
157 {
158 /* Update the status to indicate the correct
159 * number. */
160 dirp->dd_stat++;
161 }
162 }
163
164 /* Successfully got an entry. Everything about the file is
165 * already appropriately filled in except the length of the
166 * file name. */
167 dirp->dd_dir.d_namlen = strlen (dirp->dd_dir.d_name);
168
169 bool bThisFolderOrUpFolder = dirp->dd_dir.d_name[0] == '.' &&
170 (dirp->dd_dir.d_name[1] == 0 || (dirp->dd_dir.d_name[1] == '.' && dirp->dd_dir.d_name[2] == 0));
171
172 if (!bThisFolderOrUpFolder)
173 {
174 struct _stat buf;
175 char buffer[CL_MAX_DIR];
176 size_t bl = strlen(dirp->dd_name)-strlen(DIRENT_SEARCH_SUFFIX);
177 strncpy(buffer,dirp->dd_name,bl);
178 buffer[bl]=0;
179 strcat(buffer, dirp->dd_dir.d_name);
180 if ( _stat(buffer,&buf) == 0 )
181 {
182 /* Finally we have a valid entry. */
183 return &dirp->dd_dir;
184 }
185 }
186
187 /* Allow to find next file. */
188 bCallFindNext = true;
189 }
190
191 return NULL;
192 }
193
194
195
196 int32_t
closedir(DIR * dirp)197 closedir (DIR * dirp)
198 {
199 int32_t rc;
200
201 errno = 0;
202 rc = 0;
203
204 if (!dirp)
205 {
206 errno = EFAULT;
207 return -1;
208 }
209
210 if (dirp->dd_handle != -1)
211 {
212 rc = _findclose (dirp->dd_handle);
213 }
214
215 /* Delete the dir structure. */
216 _CLVDELETE(dirp);
217
218 return rc;
219 }
220 #endif //HAVE_DIRENT_H
221
222