|
|
1.1 root 1: /*
2: Hatari - scandir.c
3:
4: This file is distributed under the GNU Public License, version 2 or at
5: your option any later version. Read the file gpl.txt for details.
6:
7: scandir function for BEOS, SunOS etc..
8: */
1.1.1.5 ! root 9: const char ScanDir_fileid[] = "Hatari scandir.c : " __DATE__ " " __TIME__;
1.1 root 10:
11: #include <string.h>
12: #include <stdio.h>
1.1.1.2 root 13: #include <stdlib.h>
1.1 root 14: #include <sys/types.h>
15: #include <sys/stat.h>
16: #include <fcntl.h>
17: #include <unistd.h>
18:
19: #include "scandir.h"
1.1.1.2 root 20: #include "log.h"
1.1 root 21:
22: /*-----------------------------------------------------------------------
23: * Here come alphasort and scandir for BeOS and SunOS
24: *-----------------------------------------------------------------------*/
25: #if defined(__BEOS__) || (defined(__sun) && defined(__SVR4))
26:
27: #undef DIRSIZ
28:
29: #define DIRSIZ(dp) \
30: ((sizeof(struct dirent) - sizeof(dp)->d_name) + \
31: (((dp)->d_reclen + 1 + 3) &~ 3))
32:
1.1.1.2 root 33: #if (defined(__sun) && defined(__SVR4)) || defined(__CEGCC__)
1.1 root 34: # define dirfd(d) ((d)->dd_fd)
35: #elif defined(__BEOS__)
36: # define dirfd(d) ((d)->fd)
37: #endif
38:
39:
40: /*-----------------------------------------------------------------------*/
1.1.1.2 root 41: /**
42: * Alphabetic order comparison routine.
43: */
1.1 root 44: int alphasort(const void *d1, const void *d2)
45: {
46: return strcmp((*(struct dirent * const *)d1)->d_name, (*(struct dirent * const *)d2)->d_name);
47: }
48:
49:
50: /*-----------------------------------------------------------------------*/
1.1.1.2 root 51: /**
52: * Scan a directory for all its entries
53: */
1.1 root 54: int scandir(const char *dirname, struct dirent ***namelist, int (*sdfilter)(struct dirent *), int (*dcomp)(const void *, const void *))
55: {
56: struct dirent *d, *p, **names;
57: struct stat stb;
58: size_t nitems;
59: size_t arraysz;
60: DIR *dirp;
61:
62: if ((dirp = opendir(dirname)) == NULL)
63: return(-1);
64:
65: if (fstat(dirfd(dirp), &stb) < 0)
66: return(-1);
67:
68: /*
69: * estimate the array size by taking the size of the directory file
70: * and dividing it by a multiple of the minimum size entry.
71: */
72: arraysz = (stb.st_size / 24);
73:
74: names = (struct dirent **)malloc(arraysz * sizeof(struct dirent *));
75: if (names == NULL)
76: return(-1);
77:
78: nitems = 0;
79:
80: while ((d = readdir(dirp)) != NULL)
81: {
82:
83: if (sdfilter != NULL && !(*sdfilter)(d))
84: continue; /* just selected names */
85:
86: /*
87: * Make a minimum size copy of the data
88: */
89:
90: p = (struct dirent *)malloc(DIRSIZ(d));
91: if (p == NULL)
92: return(-1);
93:
94: p->d_ino = d->d_ino;
95: p->d_reclen = d->d_reclen;
96: /*p->d_namlen = d->d_namlen;*/
97: memcpy(p->d_name, d->d_name, p->d_reclen + 1);
98:
99: /*
100: * Check to make sure the array has space left and
101: * realloc the maximum size.
102: */
103:
104: if (++nitems >= arraysz)
105: {
106:
107: if (fstat(dirfd(dirp), &stb) < 0)
108: return(-1); /* just might have grown */
109:
110: arraysz = stb.st_size / 12;
111:
112: names = (struct dirent **)realloc((char *)names, arraysz * sizeof(struct dirent *));
113: if (names == NULL)
114: return(-1);
115: }
116:
117: names[nitems-1] = p;
118: }
119:
120: closedir(dirp);
121:
122: if (nitems && dcomp != NULL)
123: qsort(names, nitems, sizeof(struct dirent *), dcomp);
124:
125: *namelist = names;
126:
127: return nitems;
128: }
129:
130:
131: #endif /* __BEOS__ || __sun */
132:
133:
134: /*-----------------------------------------------------------------------
135: * Here come alphasort and scandir for Windows
136: *-----------------------------------------------------------------------*/
1.1.1.2 root 137: #if defined(WIN32) || defined(__CEGCC__)
1.1 root 138:
139: #include <windows.h>
1.1.1.2 root 140: #include <wchar.h>
1.1 root 141:
142: /*-----------------------------------------------------------------------*/
1.1.1.2 root 143: /**
144: * Alphabetic order comparison routine.
145: */
1.1 root 146: int alphasort(const void *d1, const void *d2)
147: {
148: return stricmp((*(struct dirent * const *)d1)->d_name, (*(struct dirent * const *)d2)->d_name);
149: }
150:
151: /*-----------------------------------------------------------------------*/
1.1.1.2 root 152: /**
153: * Scan a directory for all its entries
154: */
1.1 root 155: int scandir(const char *dirname, struct dirent ***namelist, int (*sdfilter)(struct dirent *), int (*dcomp)(const void *, const void *))
156: {
157: int len;
158: char *findIn, *d;
159: WIN32_FIND_DATA find;
160: HANDLE h;
161: int nDir = 0, NDir = 0;
162: struct dirent **dir = 0, *selectDir;
163: unsigned long ret;
164:
165: len = strlen(dirname);
166: findIn = (char *)malloc(len+5);
1.1.1.2 root 167: if (!findIn)
168: return -1;
169:
1.1 root 170: strcpy(findIn, dirname);
1.1.1.2 root 171: Log_Printf(LOG_DEBUG, "scandir : findIn orign='%s'\n", findIn);
172:
1.1 root 173: for (d = findIn; *d; d++)
174: if (*d=='/')
175: *d='\\';
176: if ((len==0))
177: {
178: strcpy(findIn, ".\\*");
179: }
180: if ((len==1)&& (d[-1]=='.'))
181: {
182: strcpy(findIn, ".\\*");
183: }
184: if ((len>0) && (d[-1]=='\\'))
185: {
186: *d++ = '*';
187: *d = 0;
188: }
189: if ((len>1) && (d[-1]=='.') && (d[-2]=='\\'))
190: {
191: d[-1] = '*';
192: }
1.1.1.5 ! root 193: if ((len>1) && !(d[-2]=='\\' && d[-1]=='*') )
1.1 root 194: {
195: *d++ = '\\';
196: *d++ = '*';
197: *d = 0;
198: }
199:
1.1.1.2 root 200: Log_Printf(LOG_DEBUG, "scandir : findIn processed='%s'\n", findIn);
201:
202: #if defined(__CEGCC__)
203: void *findInW = NULL;
204: findInW = malloc((len+6)*2);
205: if (!findInW)
206: return -1;
207: mbstowcs(findInW, findIn, len+6);
208: h = FindFirstFileW(findInW, &find);
209: #else
210: h = FindFirstFile(findIn, &find);
211: #endif
212:
213: if (h == INVALID_HANDLE_VALUE)
1.1 root 214: {
1.1.1.2 root 215: Log_Printf(LOG_DEBUG, "scandir : FindFirstFile error\n");
1.1 root 216: ret = GetLastError();
217: if (ret != ERROR_NO_MORE_FILES)
218: {
219: // TODO: return some error code
220: }
221: *namelist = dir;
222: return nDir;
223: }
1.1.1.2 root 224:
1.1 root 225: do
226: {
1.1.1.2 root 227: selectDir=(struct dirent*)malloc(sizeof(struct dirent)+lstrlen(find.cFileName)+1);
228: #if defined(__CEGCC__)
229: wcstombs(selectDir->d_name, find.cFileName, lstrlen(find.cFileName)+1);
230: #else
1.1 root 231: strcpy(selectDir->d_name, find.cFileName);
1.1.1.2 root 232: #endif
233: //Log_Printf(LOG_DEBUG, "scandir : findFile='%s'\n", selectDir->d_name);
1.1 root 234: if (!sdfilter || (*sdfilter)(selectDir))
235: {
236: if (nDir==NDir)
237: {
238: struct dirent **tempDir = (struct dirent **)calloc(sizeof(struct dirent*), NDir+33);
239: if (NDir)
240: memcpy(tempDir, dir, sizeof(struct dirent*)*NDir);
241: if (dir)
242: free(dir);
243: dir = tempDir;
244: NDir += 32;
245: }
246: dir[nDir] = selectDir;
247: nDir++;
248: dir[nDir] = 0;
249: }
250: else
251: {
252: free(selectDir);
253: }
1.1.1.5 ! root 254:
1.1.1.2 root 255: #if defined(__CEGCC__)
256: ret = FindNextFileW(h, &find);
257: #else
258: ret = FindNextFile(h, &find);
259: #endif
1.1 root 260: }
1.1.1.2 root 261: while (ret);
262:
1.1 root 263: ret = GetLastError();
264: if (ret != ERROR_NO_MORE_FILES)
265: {
266: // TODO: return some error code
1.1.1.3 root 267: Log_Printf(LOG_DEBUG, "scandir: last error = %ld\n", ret);
1.1 root 268: }
1.1.1.2 root 269:
1.1 root 270: FindClose(h);
271:
1.1.1.2 root 272: free(findIn);
273:
274: #if defined(__CEGCC__)
275: free(findInW);
276: #endif
1.1 root 277:
278: if (dcomp)
279: qsort (dir, nDir, sizeof(*dir),dcomp);
280:
281: *namelist = dir;
282: return nDir;
283: }
284:
285: #endif /* WIN32 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.