]>
git.ipfire.org Git - thirdparty/squid.git/blob - lib/dirent.c
1f575facf55d56f09ce1ff7b14ba0d959b6ccaae
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 */
54 #if defined(_SQUID_MSWIN_)
61 #define WIN32_LEAN_AND_MEAN
62 #include <windows.h> /* for GetFileAttributes */
71 * Returns a pointer to a DIR structure appropriately filled in to begin
72 * searching a directory.
75 opendir(const CHAR
* szPath
)
79 CHAR szFullPath
[MAX_PATH
];
87 if (szPath
[0] == '\0') {
91 /* Attempt to determine if the given path really is a directory. */
92 rc
= GetFileAttributes(szPath
);
93 if (rc
== (unsigned int) -1) {
94 /* call GetLastError for more error info */
98 if (!(rc
& FILE_ATTRIBUTE_DIRECTORY
)) {
99 /* Error, entry exists but not a directory. */
103 /* Make an absolute pathname. */
104 _fullpath(szFullPath
, szPath
, MAX_PATH
);
106 /* Allocate enough space to store DIR structure and the complete
107 * directory path given. */
108 nd
= (DIR *) malloc(sizeof(DIR) + (strlen(szFullPath
)
110 + strlen(SUFFIX
) + 1)
114 /* Error, out of memory. */
118 /* Create the search expression. */
119 strcpy(nd
->dd_name
, szFullPath
);
121 /* Add on a slash if the path does not end with one. */
122 if (nd
->dd_name
[0] != '\0'
123 && strchr(nd
->dd_name
, '/') != nd
->dd_name
124 + strlen(nd
->dd_name
) - 1
125 && strchr(nd
->dd_name
, '\\') != nd
->dd_name
126 + strlen(nd
->dd_name
) - 1) {
127 strcat(nd
->dd_name
, SLASH
);
129 /* Add on the search pattern */
130 strcat(nd
->dd_name
, SUFFIX
);
132 /* Initialize handle to -1 so that a premature closedir doesn't try
133 * to call _findclose on it. */
136 /* Initialize the status. */
139 /* Initialize the dirent structure. ino and reclen are invalid under
140 * Win32, and name simply points at the appropriate part of the
141 * findfirst_t structure. */
142 nd
->dd_dir
.d_ino
= 0;
143 nd
->dd_dir
.d_reclen
= 0;
144 nd
->dd_dir
.d_namlen
= 0;
145 memset(nd
->dd_dir
.d_name
, 0, FILENAME_MAX
);
154 * Return a pointer to a dirent structure filled with the information on the
155 * next entry in the directory.
158 readdir(DIR * dirp
) {
161 /* Check for valid DIR struct. */
164 return (struct dirent
*) 0;
166 if (dirp
->dd_stat
< 0) {
167 /* We have already returned all files in the directory
168 * (or the structure has an invalid dd_stat). */
169 return (struct dirent
*) 0;
170 } else if (dirp
->dd_stat
== 0) {
171 /* We haven't started the search yet. */
172 /* Start the search */
173 dirp
->dd_handle
= _findfirst(dirp
->dd_name
, &(dirp
->dd_dta
));
175 if (dirp
->dd_handle
== -1) {
176 /* Whoops! Seems there are no files in that
183 /* Get the next search entry. */
184 if (_findnext(dirp
->dd_handle
, &(dirp
->dd_dta
))) {
185 /* We are off the end or otherwise error.
186 * _findnext sets errno to ENOENT if no more file
188 DWORD winerr
= GetLastError();
189 if (winerr
== ERROR_NO_MORE_FILES
)
191 _findclose(dirp
->dd_handle
);
192 dirp
->dd_handle
= -1;
195 /* Update the status to indicate the correct
201 if (dirp
->dd_stat
> 0) {
202 /* Successfully got an entry. Everything about the file is
203 * already appropriately filled in except the length of the
205 dirp
->dd_dir
.d_namlen
= strlen(dirp
->dd_dta
.name
);
206 strcpy(dirp
->dd_dir
.d_name
, dirp
->dd_dta
.name
);
207 return &dirp
->dd_dir
;
209 return (struct dirent
*) 0;
216 * Frees up resources allocated by opendir.
230 if (dirp
->dd_handle
!= -1) {
231 rc
= _findclose(dirp
->dd_handle
);
233 /* Delete the dir structure. */
242 * Return to the beginning of the directory "stream". We simply call findclose
243 * and then reset things like an opendir.
246 rewinddir(DIR * dirp
)
254 if (dirp
->dd_handle
!= -1) {
255 _findclose(dirp
->dd_handle
);
257 dirp
->dd_handle
= -1;
264 * Returns the "position" in the "directory stream" which can be used with
265 * seekdir to go back to an old entry. We simply return the value in stat.
276 return dirp
->dd_stat
;
282 * Seek to an entry previously returned by telldir. We rewind the directory
283 * and call readdir repeatedly until either dd_stat is the position number
284 * or -1 (off the end). This is not perfect, in that the directory may
285 * have changed while we weren't looking. But that is probably the case with
289 seekdir(DIR * dirp
, long lPos
)
298 /* Seeking to an invalid position. */
301 } else if (lPos
== -1) {
303 if (dirp
->dd_handle
!= -1) {
304 _findclose(dirp
->dd_handle
);
306 dirp
->dd_handle
= -1;
309 /* Rewind and read forward to the appropriate index. */
312 while ((dirp
->dd_stat
< lPos
) && readdir(dirp
));
315 #endif /* _SQUID_MSWIN_ */