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

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.3 ! root        9: const char ScanDir_rcsid[] = "Hatari $Id: scandir.c,v 1.9 2008/05/04 20:03:34 thothy Exp $";
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:        }
                    193:        if ((len>1) && (d[-2]!='\\') && (d[-1]!='*'))
                    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.2   root      254:        
                    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 */

unix.superglobalmegacorp.com

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