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