Annotation of gcc/config/winnt/dirent.c, revision 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.