1 #ifndef ZZIP_INTERNAL_DIRENT_H
2 #define ZZIP_INTERNAL_DIRENT_H
6 * DO NOT USE THIS CODE.
8 * It is an internal header file for zziplib that carries some inline
9 * functions (or just static members) and a few defines, simply to be
10 * able to reuse these across - and have everything in a specific place.
12 * Copyright (c) 2002,2003 Guido Draheim
13 * All rights reserved,
14 * use under the restrictions of the
15 * Lesser GNU General Public License
16 * or alternatively the restrictions
17 * of the Mozilla Public License 1.1
20 #ifdef ZZIP_HAVE_DIRENT_H
23 #define _zzip_opendir opendir
24 #define _zzip_readdir readdir
25 #define _zzip_closedir closedir
26 #define _zzip_rewinddir rewinddir
27 #define _zzip_telldir telldir
28 #define _zzip_seekdir seekdir
33 #elif defined ZZIP_HAVE_WINBASE_H
36 #define _zzip_opendir win32_opendir
37 #define _zzip_readdir win32_readdir
38 #define _zzip_closedir win32_closedir
39 #define _zzip_rewinddir win32_rewinddir
40 #define _zzip_telldir win32_telldir
41 #define _zzip_seekdir win32_seekdir
45 * DIRENT.H (formerly DIRLIB.H)
47 * by M. J. Weinstein Released to public domain 1-Jan-89
49 * Because I have heard that this feature (opendir, readdir, closedir)
50 * it so useful for programmers coming from UNIX or attempting to port
51 * UNIX code, and because it is reasonably light weight, I have included
52 * it in the Mingw32 package. I have also added an implementation of
53 * rewinddir, seekdir and telldir.
54 * - Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
56 * This code is distributed in the hope that is will be useful but
57 * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
58 * DISCLAMED. This includeds but is not limited to warranties of
59 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
67 long d_ino
; /* Always zero. */
68 unsigned short d_reclen
; /* Always zero. */
69 unsigned short d_namlen
; /* Length of name in d_name. */
70 char* d_name
; /* File name. */
71 /* NOTE: The name in the dirent structure points to the name in the
72 * finddata_t structure in the DIR. */
76 * This is an internal data structure. Good programmers will not use it
77 * except as an argument to one of the functions below.
81 /* disk transfer area for this dir */
82 struct _finddata_t dd_dta
;
84 /* dirent struct to return from dir (NOTE: this makes this thread
85 * safe as long as only one thread uses a particular DIR struct at
89 /* _findnext handle */
94 * 0 = not started yet (next entry to read is first entry)
96 * positive = 0 based index of next entry
100 /* given path for dir with search pattern (struct is extended) */
107 * Derived from DIRLIB.C by Matt J. Weinstein
108 * This note appears in the DIRLIB.H
109 * DIRLIB.H by M. J. Weinstein Released to public domain 1-Jan-89
111 * Updated by Jeremy Bettis <jeremy@hksys.com>
112 * Significantly revised and rewinddir, seekdir and telldir added by Colin
113 * Peters <colin@fu.is.saga-u.ac.jp>
121 #include <sys/stat.h>
123 #define win32_SUFFIX "*"
124 #define win32_SLASH "\\"
127 #define S_ISDIR(m) ((m & S_IFMT) == S_IFDIR) /* is a directory */
134 Returns a pointer to a DIR structure appropriately filled in to begin
135 searching a directory.
138 win32_opendir (const char *szPath
)
141 struct _stat statDir
;
150 if (szPath
[0] == '\0') {
155 /* Attempt to determine if the given path really is a directory. */
156 if (_stat (szPath
, &statDir
)) {
157 /* Error, stat should have set an error value. */
161 if (!S_ISDIR (statDir
.st_mode
)) {
162 /* Error, stat reports not a directory. */
167 /* Allocate enough space to store DIR structure and the complete *
168 directory path given. */
169 nd
= (DIR *) calloc (1, sizeof (DIR) + strlen (szPath
)
170 + strlen (win32_SLASH
) + strlen (win32_SUFFIX
));
173 /* Error, out of memory. */
178 /* Create the search expression. */
179 strcpy (nd
->dd_name
, szPath
);
181 /* Add on a slash if the path does not end with one. */
182 if (nd
->dd_name
[0] != '\0' &&
183 nd
->dd_name
[strlen (nd
->dd_name
) - 1] != '/' &&
184 nd
->dd_name
[strlen (nd
->dd_name
) - 1] != '\\') {
185 strcat (nd
->dd_name
, win32_SLASH
);
188 /* Add on the search pattern */
189 strcat (nd
->dd_name
, win32_SUFFIX
);
191 /* Initialize handle to -1 so that a premature closedir doesn't try * to
192 call _findclose on it. */
195 /* Initialize the status. */
198 /* Initialize the dirent structure. ino and reclen are invalid under *
199 Win32, and name simply points at the appropriate part of the *
200 findfirst_t structure. */
201 nd
->dd_dir
.d_ino
= 0;
202 nd
->dd_dir
.d_reclen
= 0;
203 nd
->dd_dir
.d_namlen
= 0;
204 nd
->dd_dir
.d_name
= nd
->dd_dta
.name
;
212 Return a pointer to a dirent structure filled with the information on the
213 next entry in the directory.
215 static struct dirent
*
216 win32_readdir (DIR * dirp
)
220 /* Check for valid DIR struct. */
223 return (struct dirent
*) 0;
226 if (dirp
->dd_dir
.d_name
!= dirp
->dd_dta
.name
) {
227 /* The structure does not seem to be set up correctly. */
229 return (struct dirent
*) 0;
232 if (dirp
->dd_stat
< 0) {
233 /* We have already returned all files in the directory * (or the
234 structure has an invalid dd_stat). */
235 return (struct dirent
*) 0;
236 } else if (dirp
->dd_stat
== 0) {
237 /* We haven't started the search yet. */
238 /* Start the search */
239 dirp
->dd_handle
= _findfirst (dirp
->dd_name
, &(dirp
->dd_dta
));
241 if (dirp
->dd_handle
== -1) {
242 /* Whoops! Seems there are no files in that * directory. */
248 /* Get the next search entry. */
249 if (_findnext (dirp
->dd_handle
, &(dirp
->dd_dta
))) {
250 /* We are off the end or otherwise error. */
251 _findclose (dirp
->dd_handle
);
252 dirp
->dd_handle
= -1;
255 /* Update the status to indicate the correct * number. */
260 if (dirp
->dd_stat
> 0) {
261 /* Successfully got an entry. Everything about the file is * already
262 appropriately filled in except the length of the * file name. */
263 dirp
->dd_dir
.d_namlen
= (unsigned short) strlen (dirp
->dd_dir
.d_name
);
264 return &dirp
->dd_dir
;
267 return (struct dirent
*) 0;
273 Frees up resources allocated by opendir.
276 win32_closedir (DIR * dirp
)
288 if (dirp
->dd_handle
!= -1) {
289 rc
= _findclose (dirp
->dd_handle
);
292 /* Delete the dir structure. */
301 Return to the beginning of the directory "stream". We simply call findclose
302 and then reset things like an opendir.
305 win32_rewinddir (DIR * dirp
)
314 if (dirp
->dd_handle
!= -1) {
315 _findclose (dirp
->dd_handle
);
318 dirp
->dd_handle
= -1;
325 Returns the "position" in the "directory stream" which can be used with
326 seekdir to go back to an old entry. We simply return the value in stat.
329 win32_telldir (DIR * dirp
)
337 return dirp
->dd_stat
;
343 Seek to an entry previously returned by telldir. We rewind the directory
344 and call readdir repeatedly until either dd_stat is the position number
345 or -1 (off the end). This is not perfect, in that the directory may
346 have changed while we weren't looking. But that is probably the case with
350 win32_seekdir (DIR * dirp
, long lPos
)
360 /* Seeking to an invalid position. */
363 } else if (lPos
== -1) {
365 if (dirp
->dd_handle
!= -1) {
366 _findclose (dirp
->dd_handle
);
368 dirp
->dd_handle
= -1;
371 /* Rewind and read forward to the appropriate index. */
372 win32_rewinddir (dirp
);
374 while ((dirp
->dd_stat
< lPos
) && win32_readdir (dirp
));
381 #define _zzip_opendir(_N_) 0
382 #define _zzip_readdir(_D_) 0
383 #define _zzip_closedir(_D_) /* omit return code */
384 #define _zzip_rewinddir(_D_)
385 #define _zzip_telldir(_D_) 0
386 #define _zzip_seekdir(_D_,_V_) /* omit return code */
387 #define _zzip_DIR void*
389 /* end of DIRENT implementation */