Fix various typos
[vlc/asuraparaju-public.git] / src / extras / dirent.c
blobd19b762890a5f4ee7dae03631116e4be719bab7d
1 /*
2 * dirent.c
4 * Derived from DIRLIB.C by Matt J. Weinstein
5 * This note appears in the DIRLIB.H
6 * DIRLIB.H by M. J. Weinstein Released to public domain 1-Jan-89
8 * Updated by Jeremy Bettis <jeremy@hksys.com>
9 * Significantly revised and rewinddir, seekdir and telldir added by Colin
10 * Peters <colin@fu.is.saga-u.ac.jp>
12 * $Revision: 1.6 $
13 * $Author: sam $
14 * $Date: 2002/11/13 20:51:04 $
18 #include "config.h"
20 #include <stdlib.h>
21 #include <stdio.h>
23 #include <errno.h>
24 #include <string.h>
25 #ifndef UNDER_CE
26 # include <io.h>
27 # include <direct.h>
28 #else
29 # define FILENAME_MAX (260)
30 #endif
32 #define WIN32_LEAN_AND_MEAN
33 #include <windows.h> /* for GetFileAttributes */
35 #include <tchar.h>
36 #define SUFFIX "*"
37 #define SLASH "\\"
39 struct dirent
41 long d_ino; /* Always zero. */
42 unsigned short d_reclen; /* Always zero. */
43 unsigned short d_namlen; /* Length of name in d_name. */
44 char d_name[FILENAME_MAX]; /* File name. */
47 typedef struct
49 /* disk transfer area for this dir */
50 WIN32_FIND_DATA dd_dta;
52 /* dirent struct to return from dir (NOTE: this makes this thread
53 * safe as long as only one thread uses a particular DIR struct at
54 * a time) */
55 struct dirent dd_dir;
57 /* findnext handle */
58 HANDLE dd_handle;
61 * Status of search:
62 * 0 = not started yet (next entry to read is first entry)
63 * -1 = off the end
64 * positive = 0 based index of next entry
66 int dd_stat;
68 /* given path for dir with search pattern (struct is extended) */
69 char dd_name[1];
70 } DIR;
73 * opendir
75 * Returns a pointer to a DIR structure appropriately filled in to begin
76 * searching a directory.
78 DIR *
79 vlc_opendir (const CHAR *szPath)
81 DIR *nd;
82 unsigned int rc;
83 CHAR szFullPath[MAX_PATH];
85 errno = 0;
87 if (!szPath)
89 errno = EFAULT;
90 return (DIR *) 0;
93 if (szPath[0] == '\0')
95 errno = ENOTDIR;
96 return (DIR *) 0;
99 /* Attempt to determine if the given path really is a directory. */
100 #ifdef UNICODE
102 wchar_t szPathTmp[MAX_PATH];
103 mbstowcs( szPathTmp, szPath, MAX_PATH );
104 szPathTmp[MAX_PATH-1] = 0;
105 rc = GetFileAttributes (szPathTmp);
107 #else
108 rc = GetFileAttributes (szPath);
109 #endif
110 if (rc == (unsigned int)-1)
112 /* call GetLastError for more error info */
113 errno = ENOENT;
114 return (DIR *) 0;
116 if (!(rc & FILE_ATTRIBUTE_DIRECTORY))
118 /* Error, entry exists but not a directory. */
119 errno = ENOTDIR;
120 return (DIR *) 0;
123 /* Make an absolute pathname. */
124 #if defined( UNDER_CE )
125 if (szPath[0] == '\\' || szPath[0] == '/')
127 sprintf (szFullPath, "%s", szPath);
128 szFullPath[0] = '\\';
130 else
132 wchar_t szFullPathTmp[MAX_PATH];
133 if (GetModuleFileName( NULL, szFullPathTmp, MAX_PATH ) )
135 wcstombs( szFullPath, szFullPathTmp, MAX_PATH );
136 szFullPath[MAX_PATH-1] = 0;
138 else
140 /* FIXME: if I wasn't lazy, I'd check for overflows here. */
141 sprintf (szFullPath, "\\%s", szPath );
144 #else
145 _fullpath (szFullPath, szPath, MAX_PATH);
146 #endif
148 /* Allocate enough space to store DIR structure and the complete
149 * directory path given. */
150 nd = (DIR *) malloc (sizeof (DIR) + strlen (szFullPath) + sizeof (SLASH) +
151 sizeof (SUFFIX));
153 if (!nd)
155 /* Error, out of memory. */
156 errno = ENOMEM;
157 return (DIR *) 0;
160 /* Create the search expression. */
161 strcpy (nd->dd_name, szFullPath);
163 /* Add on a slash if the path does not end with one. */
164 if (nd->dd_name[0] != '\0' &&
165 nd->dd_name[strlen (nd->dd_name) - 1] != '/' &&
166 nd->dd_name[strlen (nd->dd_name) - 1] != '\\')
168 strcat (nd->dd_name, SLASH);
171 /* Add on the search pattern */
172 strcat (nd->dd_name, SUFFIX);
174 /* Initialize handle so that a premature closedir doesn't try
175 * to call FindClose on it. */
176 nd->dd_handle = INVALID_HANDLE_VALUE;
178 /* Initialize the status. */
179 nd->dd_stat = 0;
181 /* Initialize the dirent structure. ino and reclen are invalid under
182 * Win32, and name simply points at the appropriate part of the
183 * findfirst_t structure. */
184 nd->dd_dir.d_ino = 0;
185 nd->dd_dir.d_reclen = 0;
186 nd->dd_dir.d_namlen = 0;
187 memset (nd->dd_dir.d_name, 0, FILENAME_MAX);
189 return nd;
194 * readdir
196 * Return a pointer to a dirent structure filled with the information on the
197 * next entry in the directory.
199 struct dirent *
200 vlc_readdir (DIR * dirp)
202 errno = 0;
204 /* Check for valid DIR struct. */
205 if (!dirp)
207 errno = EFAULT;
208 return (struct dirent *) 0;
211 if (dirp->dd_stat < 0)
213 /* We have already returned all files in the directory
214 * (or the structure has an invalid dd_stat). */
215 return (struct dirent *) 0;
217 else if (dirp->dd_stat == 0)
219 #ifdef UNICODE
220 wchar_t dd_name[MAX_PATH];
221 mbstowcs( dd_name, dirp->dd_name, MAX_PATH );
222 dd_name[MAX_PATH-1] = 0;
223 #else
224 char *dd_name = dirp->dd_name;
225 #endif
226 /* We haven't started the search yet. */
227 /* Start the search */
228 dirp->dd_handle = FindFirstFile (dd_name, &(dirp->dd_dta));
230 if (dirp->dd_handle == INVALID_HANDLE_VALUE)
232 /* Whoops! Seems there are no files in that
233 * directory. */
234 dirp->dd_stat = -1;
236 else
238 dirp->dd_stat = 1;
241 else
243 /* Get the next search entry. */
244 if (!FindNextFile ((HANDLE)dirp->dd_handle, &(dirp->dd_dta)))
246 /* We are off the end or otherwise error. */
247 FindClose ((HANDLE)dirp->dd_handle);
248 dirp->dd_handle = INVALID_HANDLE_VALUE;
249 dirp->dd_stat = -1;
251 else
253 /* Update the status to indicate the correct
254 * number. */
255 dirp->dd_stat++;
259 if (dirp->dd_stat > 0)
261 /* Successfully got an entry */
263 #ifdef UNICODE
264 char d_name[MAX_PATH];
265 wcstombs( d_name, dirp->dd_dta.cFileName, MAX_PATH );
266 d_name[MAX_PATH-1] = 0;
267 #else
268 char *d_name = dirp->dd_dta.cFileName;
269 #endif
271 strcpy (dirp->dd_dir.d_name, d_name);
272 dirp->dd_dir.d_namlen = strlen (dirp->dd_dir.d_name);
273 return &dirp->dd_dir;
276 return (struct dirent *) 0;
281 * closedir
283 * Frees up resources allocated by opendir.
286 vlc_closedir (DIR * dirp)
288 int rc;
290 errno = 0;
291 rc = 0;
293 if (!dirp)
295 errno = EFAULT;
296 return -1;
299 if (dirp->dd_handle != INVALID_HANDLE_VALUE)
301 rc = FindClose ((HANDLE)dirp->dd_handle);
304 /* Delete the dir structure. */
305 free (dirp);
307 return rc;
311 * rewinddir
313 * Return to the beginning of the directory "stream". We simply call findclose
314 * and then reset things like an opendir.
316 void
317 vlc_rewinddir (DIR * dirp)
319 errno = 0;
321 if (!dirp)
323 errno = EFAULT;
324 return;
327 if (dirp->dd_handle != INVALID_HANDLE_VALUE)
329 FindClose ((HANDLE)dirp->dd_handle);
332 dirp->dd_handle = INVALID_HANDLE_VALUE;
333 dirp->dd_stat = 0;