2
/* Replacement scandir implementations to be used if Autoconf does not find scandir on */
3
/* host platform - taken from Hatari project at Sourceforge - only modification is the */
4
/* #ifndef HAVE_SCANDIR. */
6
/* We only need to compile this file if the host platform doesn't have scandir(): */
13
This file is distributed under the GNU Public License, version 2 or at
14
your option any later version. Read the file gpl.txt for details.
16
scandir function for BEOS, SunOS etc..
18
const char ScanDir_rcsid[] = "Hatari $Id: scandir.c,v 1.3 2007/01/16 18:42:59 thothy Exp $";
24
#include <sys/types.h>
31
/*-----------------------------------------------------------------------
32
* Here come alphasort and scandir for BeOS/Haiku and SunOS
33
*-----------------------------------------------------------------------*/
34
#if defined(__BEOS__) || defined(__HAIKU__) || (defined(__sun) && defined(__SVR4))
39
((sizeof(struct dirent) - sizeof(dp)->d_name) + \
40
(((dp)->d_reclen + 1 + 3) &~ 3))
42
#if defined(__sun) && defined(__SVR4)
43
# define dirfd(d) ((d)->dd_fd)
44
#elif defined(__BEOS__)
47
# define dirfd(d) ((d)->fd)
52
/*-----------------------------------------------------------------------*/
54
* Alphabetic order comparison routine.
56
int alphasort(const void *d1, const void *d2)
58
return strcmp((*(struct dirent * const *)d1)->d_name, (*(struct dirent * const *)d2)->d_name);
62
/*-----------------------------------------------------------------------*/
64
* Scan a directory for all its entries
66
int scandir(const char *dirname, struct dirent ***namelist, int (*sdfilter)(struct dirent *), int (*dcomp)(const void *, const void *))
68
struct dirent *d, *p, **names;
74
if ((dirp = opendir(dirname)) == NULL)
77
if (fstat(dirfd(dirp), &stb) < 0)
81
* estimate the array size by taking the size of the directory file
82
* and dividing it by a multiple of the minimum size entry.
84
arraysz = (stb.st_size / 24);
86
names = (struct dirent **)malloc(arraysz * sizeof(struct dirent *));
92
while ((d = readdir(dirp)) != NULL)
95
if (sdfilter != NULL && !(*sdfilter)(d))
96
continue; /* just selected names */
99
* Make a minimum size copy of the data
102
p = (struct dirent *)malloc(DIRSIZ(d));
107
p->d_reclen = d->d_reclen;
108
/*p->d_namlen = d->d_namlen;*/
109
memcpy(p->d_name, d->d_name, p->d_reclen + 1);
112
* Check to make sure the array has space left and
113
* realloc the maximum size.
116
if (++nitems >= arraysz)
119
if (fstat(dirfd(dirp), &stb) < 0)
120
return(-1); /* just might have grown */
122
arraysz = stb.st_size / 12;
124
names = (struct dirent **)realloc((char *)names, arraysz * sizeof(struct dirent *));
134
if (nitems && dcomp != NULL)
135
qsort(names, nitems, sizeof(struct dirent *), dcomp);
143
#endif /* __BEOS__ || __sun */
146
/*-----------------------------------------------------------------------
147
* Here come alphasort and scandir for Windows
148
*-----------------------------------------------------------------------*/
151
#undef DATADIR // stupid windows.h defines DATADIR, too
154
/*-----------------------------------------------------------------------*/
156
* Alphabetic order comparison routine.
158
int alphasort(const void *d1, const void *d2)
160
return stricmp((*(struct dirent * const *)d1)->d_name, (*(struct dirent * const *)d2)->d_name);
163
/*-----------------------------------------------------------------------*/
165
* Scan a directory for all its entries
167
int scandir(const char *dirname, struct dirent ***namelist, int (*sdfilter)(struct dirent *), int (*dcomp)(const void *, const void *))
171
WIN32_FIND_DATA find;
173
int nDir = 0, NDir = 0;
174
struct dirent **dir = 0, *selectDir;
177
len = strlen(dirname);
178
findIn = (char *)malloc(len+5);
179
strcpy(findIn, dirname);
180
printf("scandir : findIn orign=%s\n", findIn);
181
for (d = findIn; *d; d++)
186
strcpy(findIn, ".\\*");
188
if ((len==1)&& (d[-1]=='.'))
190
strcpy(findIn, ".\\*");
192
if ((len>0) && (d[-1]=='\\'))
197
if ((len>1) && (d[-1]=='.') && (d[-2]=='\\'))
201
if ((len>1) && (d[-2]!='\\') && (d[-1]!='*'))
208
printf("scandir : findIn processed=%s\n", findIn);
209
if ((h=FindFirstFile(findIn, &find))==INVALID_HANDLE_VALUE)
211
printf("scandir : FindFirstFile error\n");
212
ret = GetLastError();
213
if (ret != ERROR_NO_MORE_FILES)
215
// TODO: return some error code
222
printf("scandir : findFile=%s\n", find.cFileName);
223
selectDir=(struct dirent*)malloc(sizeof(struct dirent)+strlen(find.cFileName));
224
strcpy(selectDir->d_name, find.cFileName);
225
if (!sdfilter || (*sdfilter)(selectDir))
229
struct dirent **tempDir = (struct dirent **)calloc(sizeof(struct dirent*), NDir+33);
231
memcpy(tempDir, dir, sizeof(struct dirent*)*NDir);
237
dir[nDir] = selectDir;
246
while (FindNextFile(h, &find));
247
ret = GetLastError();
248
if (ret != ERROR_NO_MORE_FILES)
250
// TODO: return some error code
257
qsort (dir, nDir, sizeof(*dir),dcomp);
264
#endif /* HAVE_SCANDIR */