Annotation of gcc/config/winnt/dirent.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * @(#)msd_dir.c 1.4 87/11/06  Public Domain.
                      3:  *
                      4:  *  A public domain implementation of BSD directory routines for
                      5:  *  MS-DOS.  Written by Michael Rendell ({uunet,utai}michael@garfield),
                      6:  *  August 1897
                      7:  *
                      8:  *  Modified by Ian Stewartson, Data Logic ([email protected]).
                      9:  *
                     10:  *  Updates:  1.  To support OS/2 1.x
                     11:  *           2.  To support HPFS long filenames
                     12:  *           3.  To support OS/2 2.x
                     13:  *           4.  To support TurboC
                     14:  *           5.  To support Windows NT
                     15:  */
                     16: 
                     17: #include <sys/types.h>
                     18: #include <sys/stat.h>
                     19: #include <stdio.h>
                     20: #include <stdlib.h>
                     21: 
                     22: #include <malloc.h>
                     23: 
                     24: #include <string.h>
                     25: #include <limits.h>
                     26: #include <ctype.h>
                     27: #include <errno.h>
                     28: #include <dirent.h>
                     29: 
                     30: 
                     31: #define WIN32_LEAN_AND_MEAN
                     32: #include <windows.h>
                     33: 
                     34: #define FILE_NAME_E            cFileName
                     35: #define OS_CloseFH(a)          FindClose (a)
                     36: #define FIND_BUFFER            WIN32_FIND_DATA
                     37: #define DISABLE_HARD_ERRORS    SetErrorMode (0)
                     38: #define ENABLE_HARD_ERRORS     SetErrorMode (SEM_FAILCRITICALERRORS | \
                     39:                                              SEM_NOOPENFILEERRORBOX);
                     40: 
                     41: #  define ERROR_EMPTY_DIR      ERROR_FILE_NOT_FOUND
                     42: 
                     43: #  define ATTRIBUTES           (_A_SUBDIR | _A_HIDDEN | _A_SYSTEM | \
                     44:                                 _A_NORMAL | _A_RDONLY | _A_ARCH)
                     45: 
                     46: /*
                     47:  * missing ??
                     48:  */
                     49: 
                     50: #ifndef ENOTDIR
                     51: #  define ENOTDIR      120     /* Not a directory                      */
                     52: #endif
                     53: 
                     54: #ifndef S_IFMT
                     55: #  define      S_IFMT  0xf000  /* type of file                         */
                     56: #endif
                     57: 
                     58: #ifndef S_ISDIR
                     59: #  define S_ISDIR(m)   ((((m) & S_IFMT) == S_IFDIR))
                     60: #endif
                     61: 
                     62: /*
                     63:  * Internals
                     64:  */
                     65: 
                     66: typedef struct _dircontents    DIRCONT;
                     67: static void                    free_dircontents (DIRCONT *);
                     68: 
                     69: /*
                     70:  * Open the directory stream
                     71:  */
                     72: 
                     73: DIR *
                     74: opendir (name)
                     75:     const char *name;
                     76: {
                     77:     struct stat                statb;
                     78:     DIR                        *dirp;
                     79:     char               *last;
                     80:     DIRCONT            *dp;
                     81:     char               *nbuf;
                     82:     int                        len = strlen (name);
                     83:     unsigned long      rc;
                     84:     FIND_BUFFER                dtabuf;
                     85:     HANDLE             d_handle;
                     86:     bool               HPFS = FALSE;
                     87: 
                     88:     if (!len)
                     89:     {
                     90:        errno = ENOTDIR;
                     91:        return (DIR *)NULL;
                     92:     }
                     93: 
                     94:     if ((nbuf = malloc (len + 5)) == (char *)NULL)
                     95:        return (DIR *) NULL;
                     96: 
                     97:     strcpy (nbuf, name);
                     98:     last = &nbuf[len - 1];
                     99: 
                    100: /* Ok, DOS is very picky about its directory names.  The following are
                    101:  * valid.
                    102:  *
                    103:  *  c:/
                    104:  *  c:.
                    105:  *  c:name/name1
                    106:  *
                    107:  *  c:name/ is not valid
                    108:  */
                    109: 
                    110:     if (((*last == '\\') || (*last == '/')) && (len > 1) &&
                    111:        (!((len == 3) && (name[1] == ':'))))
                    112:        *(last--) = 0;
                    113: 
                    114: /* Check its a directory */
                    115: 
                    116:     DISABLE_HARD_ERRORS;
                    117:     rc = stat (nbuf, &statb);
                    118:     ENABLE_HARD_ERRORS;
                    119: 
                    120:     if (rc)
                    121:     {
                    122:        free (nbuf);
                    123:        return (DIR *) NULL;
                    124:     }
                    125: 
                    126:     if (!S_ISDIR (statb.st_mode))
                    127:     {
                    128:        free (nbuf);
                    129:        errno = ENOTDIR;
                    130:        return (DIR *)NULL;
                    131:     }
                    132: 
                    133:     if ((dirp = (DIR *) malloc (sizeof (DIR))) == (DIR *) NULL)
                    134:     {
                    135:        free (nbuf);
                    136:        return (DIR *) NULL;
                    137:     }
                    138: 
                    139: /* Set up to find everything */
                    140: 
                    141:     if ((*last != '\\') && (*last != '/'))
                    142:        strcat (last, "/");
                    143: 
                    144:     strcat (last, "*.*");
                    145: 
                    146: /* Find the file system type */
                    147: 
                    148:     HPFS = IsHPFSFileSystem (nbuf);
                    149: 
                    150:     dirp->dd_loc      = 0;
                    151:     dirp->dd_cp       = (DIRCONT *) NULL;
                    152:     dirp->dd_contents = (DIRCONT *) NULL;
                    153: 
                    154:     DISABLE_HARD_ERRORS;
                    155: 
                    156:     d_handle = FindFirstFile (nbuf, &dtabuf);
                    157:     rc = (d_handle == INVALID_HANDLE_VALUE) ? GetLastError () : 0;
                    158: 
                    159:     ENABLE_HARD_ERRORS;
                    160: 
                    161: /* Check for errors */
                    162: 
                    163:     if (rc)
                    164:     {
                    165:        free (nbuf);
                    166: 
                    167: /* Empty directory */
                    168: 
                    169: #if defined (ERROR_EMPTY_DIR)
                    170:        if (rc == ERROR_EMPTY_DIR)
                    171:            return dirp;
                    172: #endif
                    173: 
                    174:        free (dirp);
                    175:        return (DIR *) NULL;
                    176:     }
                    177: 
                    178: /* Process the directory */
                    179: 
                    180:     do
                    181:     {
                    182:        if (((dp = (DIRCONT *) malloc (sizeof (DIRCONT))) == (DIRCONT *)NULL) ||
                    183:            ((dp->_d_entry = strdup (dtabuf.FILE_NAME_E)) == (char *) NULL))
                    184:        {
                    185:            if (dp->_d_entry != (char *)NULL)
                    186:                free ((char *)dp);
                    187: 
                    188:            free (nbuf);
                    189:            free_dircontents (dirp->dd_contents);
                    190: 
                    191:            OS_CloseFH (d_handle);
                    192:            return (DIR *) NULL;
                    193:        }
                    194: 
                    195:        if (!HPFS)
                    196:            strlwr (dp->_d_entry);
                    197: 
                    198:        if (dirp->dd_contents != (DIRCONT *) NULL)
                    199:            dirp->dd_cp = dirp->dd_cp->_d_next = dp;
                    200: 
                    201:        else
                    202:            dirp->dd_contents = dirp->dd_cp = dp;
                    203: 
                    204:        dp->_d_next = (DIRCONT *) NULL;
                    205: 
                    206:     } while (FindNextFile (d_handle, &dtabuf));
                    207: 
                    208:     dirp->dd_cp = dirp->dd_contents;
                    209:     free (nbuf);
                    210: 
                    211:     OS_CloseFH (d_handle);
                    212:     return dirp;
                    213: }
                    214: 
                    215: 
                    216: /*
                    217:  * Close the directory stream
                    218:  */
                    219: 
                    220: int
                    221: closedir (dirp)
                    222:     DIR *dirp;
                    223: {
                    224:     if (dirp != (DIR *)NULL)
                    225:     {
                    226:        free_dircontents (dirp->dd_contents);
                    227:        free ((char *)dirp);
                    228:     }
                    229: 
                    230:     return 0;
                    231: }
                    232: 
                    233: /*
                    234:  * Read the next record from the stream
                    235:  */
                    236: 
                    237: struct dirent *
                    238: readdir (dirp)
                    239:     DIR        *dirp;
                    240: {
                    241:     static struct dirent       dp;
                    242: 
                    243:     if ((dirp == (DIR *)NULL) || (dirp->dd_cp == (DIRCONT *) NULL))
                    244:        return (struct dirent *) NULL;
                    245: 
                    246:     dp.d_reclen = strlen (strcpy (dp.d_name, dirp->dd_cp->_d_entry));
                    247:     dp.d_off    = dirp->dd_loc * 32;
                    248:     dp.d_ino    = (ino_t)++dirp->dd_loc;
                    249:     dirp->dd_cp = dirp->dd_cp->_d_next;
                    250: 
                    251:     return &dp;
                    252: }
                    253: 
                    254: /*
                    255:  * Restart the directory stream
                    256:  */
                    257: 
                    258: void
                    259: rewinddir (dirp)
                    260:     DIR *dirp;
                    261: {
                    262:     seekdir (dirp, (off_t)0);
                    263: }
                    264: 
                    265: /*
                    266:  * Move to a know position in the stream
                    267:  */
                    268: 
                    269: void
                    270: seekdir (dirp, off)
                    271:     DIR *dirp;
                    272:     off_t off;
                    273: {
                    274:     long       i = off;
                    275:     DIRCONT    *dp;
                    276: 
                    277:     if ((dirp == (DIR *)NULL) || (off < 0L))
                    278:        return;
                    279: 
                    280:     for (dp = dirp->dd_contents; (--i >= 0) && (dp != (DIRCONT *)NULL);
                    281:         dp = dp->_d_next)
                    282:        ;
                    283: 
                    284:     dirp->dd_loc = off - (i + 1);
                    285:     dirp->dd_cp = dp;
                    286: }
                    287: 
                    288: /*
                    289:  * Get the current position
                    290:  */
                    291: 
                    292: off_t
                    293: telldir(dirp)
                    294:     DIR *dirp;
                    295: {
                    296:     return (dirp == (DIR *)NULL) ? (off_t) -1 : dirp->dd_loc;
                    297: }
                    298: 
                    299: /*
                    300:  * Release the internal structure
                    301:  */
                    302: 
                    303: static void
                    304: free_dircontents (dp)
                    305:     DIRCONT *dp;
                    306: {
                    307:     DIRCONT    *odp;
                    308: 
                    309:     while ((odp = dp) != (DIRCONT *)NULL)
                    310:     {
                    311:        if (dp->_d_entry != (char *)NULL)
                    312:            free (dp->_d_entry);
                    313: 
                    314:        dp = dp->_d_next;
                    315:        free ((char *)odp);
                    316:     }
                    317: }
                    318: 
                    319: 
                    320: /*
                    321:  * Windows NT version
                    322:  */
                    323: 
                    324: bool
                    325: IsHPFSFileSystem (directory)
                    326:     char *directory;
                    327: {
                    328:     char               bName[4];
                    329:     DWORD              flags;
                    330:     DWORD              maxname;
                    331:     BOOL               rc;
                    332:     unsigned int       nDrive;
                    333:     char               szCurDir [MAX_PATH];
                    334: 
                    335:     if (isalpha (directory[0]) && (directory[1] == ':'))
                    336:        nDrive = toupper (directory[0]) - '@';
                    337: 
                    338:     else
                    339:     {
                    340:        GetCurrentDirectory (MAX_PATH, szCurDir);
                    341:        nDrive = szCurDir[0] - 'A' + 1;
                    342:     }
                    343: 
                    344: /* Set up the drive name */
                    345: 
                    346:     strcpy (bName, "x:\\");
                    347:     bName[0] = (char) (nDrive + '@');
                    348: 
                    349: /* Read the volume info, if we fail - assume non-HPFS */
                    350: 
                    351:     DISABLE_HARD_ERRORS;
                    352: 
                    353:     rc = GetVolumeInformation (bName, (LPTSTR)NULL, 0, (LPDWORD)NULL,
                    354:                               &maxname, &flags, (LPTSTR)NULL, 0);
                    355:     ENABLE_HARD_ERRORS;
                    356: 
                    357:     return ((rc) && (flags & (FS_CASE_SENSITIVE | FS_CASE_IS_PRESERVED)))
                    358:                ? TRUE : FALSE;
                    359: }
                    360: 

unix.superglobalmegacorp.com

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