Annotation of hatari/src/scandir.c, revision 1.1.1.1

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 */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.