]>
git.ipfire.org Git - thirdparty/squid.git/blob - lib/dirent.c
4 * Implement dirent-style opendir(), readdir(), closedir(), rewinddir(),
5 * seekdir() and telldir on Windows - Based on mingw-runtime package sources.
6 * AUTHOR: Guido Serassio <serassio@squid-cache.org>
8 * SQUID Web Proxy Cache http://www.squid-cache.org/
9 * ----------------------------------------------------------
11 * Squid is the result of efforts by numerous individuals from
12 * the Internet community; see the CONTRIBUTORS file for full
13 * details. Many organizations have provided support for Squid's
14 * development; see the SPONSORS file for full details. Squid is
15 * Copyrighted (C) 2001 by the Regents of the University of
16 * California; see the COPYRIGHT file for full details. Squid
17 * incorporates software developed and/or copyrighted by other
18 * sources; see the CREDITS file for full details.
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
34 * Original file info follow:
37 * This file has no copyright assigned and is placed in the Public Domain.
38 * This file is a part of the mingw-runtime package.
39 * No warranty is given; refer to the file DISCLAIMER within the package.
41 * Derived from DIRLIB.C by Matt J. Weinstein
42 * This note appears in the DIRLIB.H
43 * DIRLIB.H by M. J. Weinstein Released to public domain 1-Jan-89
45 * Updated by Jeremy Bettis <jeremy@hksys.com>
46 * Significantly revised and rewinddir, seekdir and telldir added by Colin
47 * Peters <colin@fu.is.saga-u.ac.jp>
53 /* The following code section is part of the native Windows Squid port */
63 #define WIN32_LEAN_AND_MEAN
64 #include <windows.h> /* for GetFileAttributes */
73 * Returns a pointer to a DIR structure appropriately filled in to begin
74 * searching a directory.
77 opendir(const CHAR
* szPath
)
81 CHAR szFullPath
[MAX_PATH
];
89 if (szPath
[0] == '\0') {
93 /* Attempt to determine if the given path really is a directory. */
94 rc
= GetFileAttributes(szPath
);
95 if (rc
== (unsigned int) -1) {
96 /* call GetLastError for more error info */
100 if (!(rc
& FILE_ATTRIBUTE_DIRECTORY
)) {
101 /* Error, entry exists but not a directory. */
105 /* Make an absolute pathname. */
106 _fullpath(szFullPath
, szPath
, MAX_PATH
);
108 /* Allocate enough space to store DIR structure and the complete
109 * directory path given. */
110 nd
= (DIR *) malloc(sizeof(DIR) + (strlen(szFullPath
)
112 + strlen(SUFFIX
) + 1)
116 /* Error, out of memory. */
120 /* Create the search expression. */
121 strcpy(nd
->dd_name
, szFullPath
);
123 /* Add on a slash if the path does not end with one. */
124 if (nd
->dd_name
[0] != '\0'
125 && strchr(nd
->dd_name
, '/') != nd
->dd_name
126 + strlen(nd
->dd_name
) - 1
127 && strchr(nd
->dd_name
, '\\') != nd
->dd_name
128 + strlen(nd
->dd_name
) - 1) {
129 strcat(nd
->dd_name
, SLASH
);
131 /* Add on the search pattern */
132 strcat(nd
->dd_name
, SUFFIX
);
134 /* Initialize handle to -1 so that a premature closedir doesn't try
135 * to call _findclose on it. */
138 /* Initialize the status. */
141 /* Initialize the dirent structure. ino and reclen are invalid under
142 * Win32, and name simply points at the appropriate part of the
143 * findfirst_t structure. */
144 nd
->dd_dir
.d_ino
= 0;
145 nd
->dd_dir
.d_reclen
= 0;
146 nd
->dd_dir
.d_namlen
= 0;
147 memset(nd
->dd_dir
.d_name
, 0, FILENAME_MAX
);
156 * Return a pointer to a dirent structure filled with the information on the
157 * next entry in the directory.
160 readdir(DIR * dirp
) {
163 /* Check for valid DIR struct. */
166 return (struct dirent
*) 0;
168 if (dirp
->dd_stat
< 0) {
169 /* We have already returned all files in the directory
170 * (or the structure has an invalid dd_stat). */
171 return (struct dirent
*) 0;
172 } else if (dirp
->dd_stat
== 0) {
173 /* We haven't started the search yet. */
174 /* Start the search */
175 dirp
->dd_handle
= _findfirst(dirp
->dd_name
, &(dirp
->dd_dta
));
177 if (dirp
->dd_handle
== -1) {
178 /* Whoops! Seems there are no files in that
185 /* Get the next search entry. */
186 if (_findnext(dirp
->dd_handle
, &(dirp
->dd_dta
))) {
187 /* We are off the end or otherwise error.
188 * _findnext sets errno to ENOENT if no more file
190 DWORD winerr
= GetLastError();
191 if (winerr
== ERROR_NO_MORE_FILES
)
193 _findclose(dirp
->dd_handle
);
194 dirp
->dd_handle
= -1;
197 /* Update the status to indicate the correct
203 if (dirp
->dd_stat
> 0) {
204 /* Successfully got an entry. Everything about the file is
205 * already appropriately filled in except the length of the
207 dirp
->dd_dir
.d_namlen
= strlen(dirp
->dd_dta
.name
);
208 strcpy(dirp
->dd_dir
.d_name
, dirp
->dd_dta
.name
);
209 return &dirp
->dd_dir
;
211 return (struct dirent
*) 0;
218 * Frees up resources allocated by opendir.
232 if (dirp
->dd_handle
!= -1) {
233 rc
= _findclose(dirp
->dd_handle
);
235 /* Delete the dir structure. */
244 * Return to the beginning of the directory "stream". We simply call findclose
245 * and then reset things like an opendir.
248 rewinddir(DIR * dirp
)
256 if (dirp
->dd_handle
!= -1) {
257 _findclose(dirp
->dd_handle
);
259 dirp
->dd_handle
= -1;
266 * Returns the "position" in the "directory stream" which can be used with
267 * seekdir to go back to an old entry. We simply return the value in stat.
278 return dirp
->dd_stat
;
284 * Seek to an entry previously returned by telldir. We rewind the directory
285 * and call readdir repeatedly until either dd_stat is the position number
286 * or -1 (off the end). This is not perfect, in that the directory may
287 * have changed while we weren't looking. But that is probably the case with
291 seekdir(DIR * dirp
, long lPos
)
300 /* Seeking to an invalid position. */
303 } else if (lPos
== -1) {
305 if (dirp
->dd_handle
!= -1) {
306 _findclose(dirp
->dd_handle
);
308 dirp
->dd_handle
= -1;
311 /* Rewind and read forward to the appropriate index. */
314 while ((dirp
->dd_stat
< lPos
) && readdir(dirp
));
317 #endif /* _SQUID_MSWIN_ */