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