Annotation of hatari/src/file.c, revision 1.1.1.10

1.1       root        1: /*
1.1.1.6   root        2:   Hatari - file.c
1.1       root        3: 
1.1.1.5   root        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: 
1.1.1.6   root        7:   Common file access functions.
1.1       root        8: */
1.1.1.10! root        9: const char File_rcsid[] = "Hatari $Id: file.c,v 1.33 2006/08/08 07:19:15 thothy Exp $";
1.1       root       10: 
1.1.1.10! root       11: #include <string.h>
        !            12: #include <strings.h>
1.1       root       13: #include <sys/types.h>
                     14: #include <sys/stat.h>
                     15: #include <fcntl.h>
1.1.1.6   root       16: #include <unistd.h>
                     17: 
                     18: #include <zlib.h>
1.1       root       19: 
                     20: #include "main.h"
1.1.1.7   root       21: #include "dialog.h"
1.1       root       22: #include "file.h"
                     23: #include "createBlankImage.h"
1.1.1.10! root       24: #include "zip.h"
1.1       root       25: 
1.1.1.2   root       26: 
                     27: /*-----------------------------------------------------------------------*/
1.1       root       28: /*
                     29:   Remove any '/'s from end of filenames, but keeps / intact
                     30: */
                     31: void File_CleanFileName(char *pszFileName)
                     32: {
1.1.1.10! root       33:        int len;
1.1.1.3   root       34: 
1.1.1.10! root       35:        len = strlen(pszFileName);
1.1.1.3   root       36: 
1.1.1.10! root       37:        /* Security length check: */
        !            38:        if (len > FILENAME_MAX)
        !            39:        {
        !            40:                pszFileName[FILENAME_MAX-1] = 0;
        !            41:                len = FILENAME_MAX;
        !            42:        }
        !            43: 
        !            44:        /* Remove end slash from filename! But / remains! Doh! */
        !            45:        if (len > 2 && pszFileName[len-1] == PATHSEP)
        !            46:                pszFileName[len-1] = 0;
1.1       root       47: }
                     48: 
1.1.1.2   root       49: 
                     50: /*-----------------------------------------------------------------------*/
1.1       root       51: /*
                     52:   Add '/' to end of filename
                     53: */
                     54: void File_AddSlashToEndFileName(char *pszFileName)
                     55: {
1.1.1.10! root       56:        int len;
        !            57: 
        !            58:        len = strlen(pszFileName);
        !            59: 
        !            60:        /* Check dir/filenames */
        !            61:        if (len != 0)
        !            62:        {
        !            63:                if (pszFileName[strlen(pszFileName)-1] != PATHSEP)
        !            64:                {
        !            65:                        pszFileName[len] = PATHSEP; /* Must use end slash */
        !            66:                        pszFileName[len+1] = 0;
        !            67:                }
        !            68:        }
1.1       root       69: }
                     70: 
1.1.1.3   root       71: 
1.1       root       72: /*-----------------------------------------------------------------------*/
                     73: /*
                     74:   Does filename extension match? If so, return TRUE
                     75: */
1.1.1.8   root       76: BOOL File_DoesFileExtensionMatch(const char *pszFileName, const char *pszExtension)
1.1       root       77: {
1.1.1.10! root       78:        if (strlen(pszFileName) < strlen(pszExtension))
        !            79:                return FALSE;
        !            80:        /* Is matching extension? */
        !            81:        if (!strcasecmp(&pszFileName[strlen(pszFileName)-strlen(pszExtension)], pszExtension))
        !            82:                return TRUE;
1.1       root       83: 
1.1.1.10! root       84:        /* No */
        !            85:        return FALSE;
1.1       root       86: }
                     87: 
1.1.1.2   root       88: 
                     89: /*-----------------------------------------------------------------------*/
1.1       root       90: /*
                     91:   Check if filename is from root
                     92:   
                     93:   Return TRUE if filename is '/', else give FALSE
                     94: */
                     95: BOOL File_IsRootFileName(char *pszFileName)
                     96: {
1.1.1.10! root       97:        if (pszFileName[0]=='\0')     /* If NULL string return! */
        !            98:                return FALSE;
1.1       root       99: 
1.1.1.10! root      100:        if (pszFileName[0]==PATHSEP)
        !           101:                return TRUE;
1.1       root      102: 
1.1.1.10! root      103: #ifdef WIN32
        !           104: 
        !           105:        if (pszFileName[1]==':')
        !           106:                return TRUE;
        !           107: #endif
        !           108: 
        !           109:        return FALSE;
1.1       root      110: }
                    111: 
1.1.1.2   root      112: 
                    113: /*-----------------------------------------------------------------------*/
1.1       root      114: /*
                    115:   Return string, to remove 'C:' part of filename
                    116: */
1.1.1.8   root      117: const char *File_RemoveFileNameDrive(const char *pszFileName)
1.1       root      118: {
1.1.1.10! root      119:        if ( (pszFileName[0]!='\0') && (pszFileName[1]==':') )
        !           120:                return &pszFileName[2];
        !           121:        else
        !           122:                return pszFileName;
1.1       root      123: }
                    124: 
                    125: 
1.1.1.2   root      126: /*-----------------------------------------------------------------------*/
1.1       root      127: /*
                    128:   Check if filename end with a '/'
                    129:   
                    130:   Return TRUE if filename ends with '/'
                    131: */
                    132: BOOL File_DoesFileNameEndWithSlash(char *pszFileName)
                    133: {
1.1.1.10! root      134:        if (pszFileName[0] == '\0')    /* If NULL string return! */
        !           135:                return FALSE;
1.1       root      136: 
1.1.1.10! root      137:        /* Does string end in a '/'? */
        !           138:        if (pszFileName[strlen(pszFileName)-1] == PATHSEP)
        !           139:                return TRUE;
1.1       root      140: 
1.1.1.10! root      141:        return FALSE;
1.1       root      142: }
                    143: 
                    144: 
1.1.1.2   root      145: /*-----------------------------------------------------------------------*/
1.1       root      146: /*
1.1.1.9   root      147:   Read file from disk into memory, allocate memory for it if need to (pass
1.1.1.6   root      148:   Address as NULL).
1.1       root      149: */
1.1.1.10! root      150: void *File_Read(char *pszFileName, void *pAddress, long *pFileSize, const char * const ppszExts[])
1.1       root      151: {
1.1.1.10! root      152:        void *pFile = NULL;
        !           153:        long FileSize = 0;
1.1       root      154: 
1.1.1.10! root      155:        /* Does the file exist? If not, see if can scan for other extensions and try these */
        !           156:        if (!File_Exists(pszFileName) && ppszExts)
        !           157:        {
        !           158:                /* Try other extensions, if suceeds correct filename is now in 'pszFileName' */
        !           159:                File_FindPossibleExtFileName(pszFileName, ppszExts);
        !           160:        }
        !           161: 
        !           162:        /* Is it a gzipped file? */
        !           163:        if (File_DoesFileExtensionMatch(pszFileName, ".gz"))
        !           164:        {
        !           165:                gzFile hGzFile;
        !           166:                /* Open and read gzipped file */
        !           167:                hGzFile = gzopen(pszFileName, "rb");
        !           168:                if (hGzFile != NULL)
        !           169:                {
        !           170:                        /* Find size of file: */
        !           171:                        do
        !           172:                        {
        !           173:                                /* Seek through the file until we hit the end... */
        !           174:                                gzseek(hGzFile, 1024, SEEK_CUR);
        !           175:                        }
        !           176:                        while (!gzeof(hGzFile));
        !           177:                        FileSize = gztell(hGzFile);
        !           178:                        gzrewind(hGzFile);
        !           179:                        /* Find pointer to where to load, allocate memory if pass NULL */
        !           180:                        if (pAddress)
        !           181:                                pFile = pAddress;
        !           182:                        else
        !           183:                                pFile = malloc(FileSize);
        !           184:                        /* Read in... */
        !           185:                        if (pFile)
        !           186:                                FileSize = gzread(hGzFile, pFile, FileSize);
        !           187: 
        !           188:                        gzclose(hGzFile);
        !           189:                }
        !           190:        }
        !           191:        else if (File_DoesFileExtensionMatch(pszFileName, ".zip"))
        !           192:        {
        !           193:                /* It is a .ZIP file! -> Try to load the first file in the archive */
        !           194:                pFile = ZIP_ReadFirstFile(pszFileName, &FileSize, ppszExts);
        !           195:                if (pFile && pAddress)
        !           196:                {
        !           197:                        memcpy(pAddress, pFile, FileSize);
        !           198:                        free(pFile);
        !           199:                        pFile = pAddress;
        !           200:                }
        !           201:        }
        !           202:        else          /* It is a normal file */
        !           203:        {
        !           204:                FILE *hDiskFile;
        !           205:                /* Open and read normal file */
        !           206:                hDiskFile = fopen(pszFileName, "rb");
        !           207:                if (hDiskFile != NULL)
        !           208:                {
        !           209:                        /* Find size of file: */
        !           210:                        fseek(hDiskFile, 0, SEEK_END);
        !           211:                        FileSize = ftell(hDiskFile);
        !           212:                        fseek(hDiskFile, 0, SEEK_SET);
        !           213:                        /* Find pointer to where to load, allocate memory if pass NULL */
        !           214:                        if (pAddress)
        !           215:                                pFile = pAddress;
        !           216:                        else
        !           217:                                pFile = malloc(FileSize);
        !           218:                        /* Read in... */
        !           219:                        if (pFile)
        !           220:                                FileSize = fread(pFile, 1, FileSize, hDiskFile);
        !           221: 
        !           222:                        fclose(hDiskFile);
        !           223:                }
        !           224:        }
        !           225: 
        !           226:        /* Store size of file we read in (or 0 if failed) */
        !           227:        if (pFileSize)
        !           228:                *pFileSize = FileSize;
1.1       root      229: 
1.1.1.10! root      230:        return pFile;        /* Return to where read in/allocated */
1.1       root      231: }
                    232: 
1.1.1.2   root      233: 
                    234: /*-----------------------------------------------------------------------*/
1.1       root      235: /*
1.1.1.9   root      236:   Save file to disk, return FALSE if errors
1.1       root      237: */
1.1.1.10! root      238: BOOL File_Save(char *pszFileName, const void *pAddress, size_t Size, BOOL bQueryOverwrite)
1.1       root      239: {
1.1.1.10! root      240:        BOOL bRet = FALSE;
1.1       root      241: 
1.1.1.10! root      242:        /* Check if need to ask user if to overwrite */
        !           243:        if (bQueryOverwrite)
        !           244:        {
        !           245:                /* If file exists, ask if OK to overwrite */
        !           246:                if (!File_QueryOverwrite(pszFileName))
        !           247:                        return FALSE;
        !           248:        }
        !           249: 
        !           250:        /* Normal file or gzipped file? */
        !           251:        if (File_DoesFileExtensionMatch(pszFileName, ".gz"))
        !           252:        {
        !           253:                gzFile hGzFile;
        !           254:                /* Create a gzipped file: */
        !           255:                hGzFile = gzopen(pszFileName, "wb");
        !           256:                if (hGzFile != NULL)
        !           257:                {
        !           258:                        /* Write data, set success flag */
        !           259:                        if (gzwrite(hGzFile, pAddress, Size) == (int)Size)
        !           260:                                bRet = TRUE;
        !           261: 
        !           262:                        gzclose(hGzFile);
        !           263:                }
        !           264:        }
        !           265:        else
        !           266:        {
        !           267:                FILE *hDiskFile;
        !           268:                /* Create a normal file: */
        !           269:                hDiskFile = fopen(pszFileName, "wb");
        !           270:                if (hDiskFile != NULL)
        !           271:                {
        !           272:                        /* Write data, set success flag */
        !           273:                        if (fwrite(pAddress, 1, Size, hDiskFile) == Size)
        !           274:                                bRet = TRUE;
        !           275: 
        !           276:                        fclose(hDiskFile);
        !           277:                }
        !           278:        }
1.1       root      279: 
1.1.1.10! root      280:        return bRet;
1.1       root      281: }
                    282: 
1.1.1.2   root      283: 
                    284: /*-----------------------------------------------------------------------*/
1.1       root      285: /*
                    286:   Return size of file, -1 if error
                    287: */
1.1.1.8   root      288: int File_Length(const char *pszFileName)
1.1       root      289: {
1.1.1.10! root      290:        FILE *hDiskFile;
        !           291:        int FileSize;
1.1.1.9   root      292: 
1.1.1.10! root      293:        hDiskFile = fopen(pszFileName, "rb");
        !           294:        if (hDiskFile!=NULL)
        !           295:        {
        !           296:                fseek(hDiskFile, 0, SEEK_END);
        !           297:                FileSize = ftell(hDiskFile);
        !           298:                fseek(hDiskFile, 0, SEEK_SET);
        !           299:                fclose(hDiskFile);
        !           300:                return FileSize;
        !           301:        }
1.1       root      302: 
1.1.1.10! root      303:        return -1;
1.1       root      304: }
                    305: 
1.1.1.2   root      306: 
                    307: /*-----------------------------------------------------------------------*/
1.1       root      308: /*
                    309:   Return TRUE if file exists
                    310: */
1.1.1.8   root      311: BOOL File_Exists(const char *pszFileName)
1.1       root      312: {
1.1.1.10! root      313:        FILE *hDiskFile;
1.1       root      314: 
1.1.1.10! root      315:        /* Attempt to open file */
        !           316:        hDiskFile = fopen(pszFileName, "rb");
        !           317:        if (hDiskFile!=NULL)
        !           318:        {
        !           319:                fclose(hDiskFile);
        !           320:                return TRUE;
        !           321:        }
        !           322:        return FALSE;
1.1       root      323: }
                    324: 
1.1.1.2   root      325: 
                    326: /*-----------------------------------------------------------------------*/
1.1       root      327: /*
                    328:   Find if file exists, and if so ask user if OK to overwrite
                    329: */
1.1.1.8   root      330: BOOL File_QueryOverwrite(const char *pszFileName)
1.1       root      331: {
1.1.1.10! root      332:        char szString[FILENAME_MAX + 26];
1.1       root      333: 
1.1.1.10! root      334:        /* Try and find if file exists */
        !           335:        if (File_Exists(pszFileName))
        !           336:        {
        !           337:                /* File does exist, are we OK to overwrite? */
        !           338:                snprintf(szString, sizeof(szString), "File '%s' exists, overwrite?", pszFileName);
        !           339:                fprintf(stderr, "%s\n", szString);
        !           340:                return DlgAlert_Query(szString);
        !           341:        }
1.1       root      342: 
1.1.1.10! root      343:        return TRUE;
1.1       root      344: }
                    345: 
1.1.1.2   root      346: 
                    347: /*-----------------------------------------------------------------------*/
1.1       root      348: /*
                    349:   Try filename with various extensions and check if file exists - if so return correct name
                    350: */
1.1.1.10! root      351: BOOL File_FindPossibleExtFileName(char *pszFileName, const char * const ppszExts[])
1.1       root      352: {
1.1.1.10! root      353:        char *szSrcDir, *szSrcName, *szSrcExt;
        !           354:        char *szTempFileName;
        !           355:        int i = 0;
        !           356:        BOOL bFileExists = FALSE;
        !           357: 
        !           358:        /* Allocate temporary memory for strings: */
        !           359:        szTempFileName = malloc(4 * FILENAME_MAX);
        !           360:        if (!szTempFileName)
        !           361:        {
        !           362:                perror("File_FindPossibleExtFileName");
        !           363:                return FALSE;
        !           364:        }
        !           365:        szSrcDir = szTempFileName + FILENAME_MAX;
        !           366:        szSrcName = szSrcDir + FILENAME_MAX;
        !           367:        szSrcExt = szSrcName + FILENAME_MAX;
        !           368: 
        !           369:        /* Split filename into parts */
        !           370:        File_splitpath(pszFileName, szSrcDir, szSrcName, szSrcExt);
        !           371: 
        !           372:        /* Scan possible extensions */
        !           373:        while(ppszExts[i] && !bFileExists)
        !           374:        {
        !           375:                /* Re-build with new file extension */
        !           376:                File_makepath(szTempFileName, szSrcDir, szSrcName, ppszExts[i]);
        !           377:                /* Does this file exist? */
        !           378:                if (File_Exists(szTempFileName))
        !           379:                {
        !           380:                        /* Copy name for return */
        !           381:                        strcpy(pszFileName, szTempFileName);
        !           382:                        bFileExists = TRUE;
        !           383:                }
        !           384: 
        !           385:                /* Next one */
        !           386:                i++;
        !           387:        }
1.1.1.3   root      388: 
1.1.1.10! root      389:        free(szTempFileName);
1.1.1.8   root      390: 
1.1.1.10! root      391:        return bFileExists;
1.1       root      392: }
1.1.1.3   root      393: 
                    394: 
                    395: /*-----------------------------------------------------------------------*/
                    396: /*
                    397:   Split a complete filename into path, filename and extension.
                    398:   If pExt is NULL, don't split the extension from the file name!
                    399: */
1.1.1.8   root      400: void File_splitpath(const char *pSrcFileName, char *pDir, char *pName, char *pExt)
1.1.1.3   root      401: {
1.1.1.10! root      402:        char *ptr1, *ptr2;
1.1.1.3   root      403: 
1.1.1.10! root      404:        /* Build pathname: */
        !           405:        ptr1 = strrchr(pSrcFileName, PATHSEP);
        !           406:        if (ptr1)
        !           407:        {
        !           408:                strcpy(pDir, pSrcFileName);
        !           409:                strcpy(pName, ptr1+1);
        !           410:                pDir[ptr1-pSrcFileName+1] = 0;
        !           411:        }
        !           412:        else
        !           413:        {
        !           414:                sprintf(pDir, ".%c", PATHSEP);
        !           415:                strcpy(pName, pSrcFileName);
        !           416:        }
        !           417: 
        !           418:        /* Build the raw filename: */
        !           419:        if (pExt != NULL)
        !           420:        {
        !           421:                ptr2 = strrchr(pName+1, '.');
        !           422:                if (ptr2)
        !           423:                {
        !           424:                        pName[ptr2-pName] = 0;
        !           425:                        /* Copy the file extension: */
        !           426:                        strcpy(pExt, ptr2+1);
        !           427:                }
        !           428:                else
        !           429:                        pExt[0] = 0;
        !           430:        }
1.1.1.3   root      431: }
                    432: 
                    433: 
                    434: /*-----------------------------------------------------------------------*/
                    435: /*
                    436:   Build a complete filename from path, filename and extension.
                    437:   pExt can also be NULL.
                    438: */
1.1.1.8   root      439: void File_makepath(char *pDestFileName, const char *pDir, const char *pName, const char *pExt)
1.1.1.3   root      440: {
1.1.1.10! root      441:        int len;
        !           442: 
        !           443:        strcpy(pDestFileName, pDir);
        !           444:        len = strlen(pDestFileName);
        !           445: 
        !           446:        if (len == 0)
        !           447:                sprintf(pDestFileName, ".%c", PATHSEP);
        !           448:        else if (pDestFileName[len-1] != PATHSEP)
        !           449:        {
        !           450:                pDestFileName[len] = PATHSEP;
        !           451:                pDestFileName[len+1] = 0;
        !           452:        }
        !           453: 
        !           454:        strcat(pDestFileName, pName);
        !           455: 
        !           456:        if (pExt != NULL)
        !           457:        {
        !           458:                if (strlen(pExt) > 0 && pExt[0] != '.')
        !           459:                        strcat(pDestFileName, ".");
        !           460:                strcat(pDestFileName, pExt);
        !           461:        }
1.1.1.3   root      462: }
                    463: 
                    464: 
                    465: /*-----------------------------------------------------------------------*/
                    466: /*
                    467:   Shrink a file name to a certain length and insert some dots if we cut
                    468:   something away (usefull for showing file names in a dialog).
                    469: */
                    470: void File_ShrinkName(char *pDestFileName, char *pSrcFileName, int maxlen)
                    471: {
1.1.1.10! root      472:        int srclen = strlen(pSrcFileName);
        !           473:        if (srclen < maxlen)
        !           474:                strcpy(pDestFileName, pSrcFileName);  /* It fits! */
        !           475:        else
        !           476:        {
        !           477:                strncpy(pDestFileName, pSrcFileName, maxlen/2);
        !           478:                if (maxlen&1)  /* even or uneven? */
        !           479:                        pDestFileName[maxlen/2-1] = 0;
        !           480:                else
        !           481:                        pDestFileName[maxlen/2-2] = 0;
        !           482:                strcat(pDestFileName, "...");
        !           483:                strcat(pDestFileName, &pSrcFileName[strlen(pSrcFileName)-maxlen/2+1]);
        !           484:        }
1.1.1.3   root      485: }
                    486: 
1.1.1.6   root      487: 
                    488: /*-----------------------------------------------------------------------*/
                    489: /*
                    490:   Create a clean absolute file name from a (possibly) relative file name.
                    491:   I.e. filter out all occurancies of "./" and "../".
                    492:   pFileName needs to point to a buffer of at least FILENAME_MAX bytes.
                    493: */
                    494: void File_MakeAbsoluteName(char *pFileName)
                    495: {
1.1.1.10! root      496:        char *pTempName;
        !           497:        int inpos, outpos;
1.1.1.6   root      498: 
1.1.1.10! root      499:        inpos = 0;
        !           500:        pTempName = malloc(FILENAME_MAX);
        !           501:        if (!pTempName)
        !           502:        {
        !           503:                perror("File_MakeAbsoluteName - malloc");
        !           504:                return;
        !           505:        }
        !           506: 
        !           507:        /* Is it already an absolute name? */
        !           508:        if (File_IsRootFileName(pFileName))
        !           509:        {
        !           510:                outpos = 0;
        !           511:        }
        !           512:        else
        !           513:        {
        !           514:                if (!getcwd(pTempName, FILENAME_MAX))
        !           515:                {
        !           516:                        perror("File_MakeAbsoluteName - getcwd");
        !           517:                        free(pTempName);
        !           518:                        return;
        !           519:                }
        !           520:                File_AddSlashToEndFileName(pTempName);
        !           521:                outpos = strlen(pTempName);
        !           522:        }
        !           523: 
        !           524:        /* Now filter out the relative paths "./" and "../" */
        !           525:        while (pFileName[inpos] != 0 && outpos < FILENAME_MAX)
        !           526:        {
        !           527:                if (pFileName[inpos] == '.' && pFileName[inpos+1] == PATHSEP)
        !           528:                {
        !           529:                        /* Ignore "./" */
        !           530:                        inpos += 2;
        !           531:                }
        !           532:                else if (pFileName[inpos] == '.' && pFileName[inpos+1] == '.' && pFileName[inpos+2] == PATHSEP)
        !           533:                {
        !           534:                        /* Handle "../" */
        !           535:                        char *pSlashPos;
        !           536:                        inpos += 3;
        !           537:                        pTempName[outpos - 1] = 0;
        !           538:                        pSlashPos = strrchr(pTempName, PATHSEP);
        !           539:                        if (pSlashPos)
        !           540:                        {
        !           541:                                *(pSlashPos + 1) = 0;
        !           542:                                outpos = strlen(pTempName);
        !           543:                        }
        !           544:                        else
        !           545:                        {
        !           546:                                pTempName[0] = PATHSEP;
        !           547:                                outpos = 1;
        !           548:                        }
        !           549:                }
        !           550:                else
        !           551:                {
        !           552:                        /* Copy until next slash or end of input string */
        !           553:                        while (pFileName[inpos] != 0 && outpos < FILENAME_MAX)
        !           554:                        {
        !           555:                                pTempName[outpos++] = pFileName[inpos++];
        !           556:                                if (pFileName[inpos - 1] == PATHSEP)
        !           557:                                        break;
        !           558:                        }
        !           559:                }
        !           560:        }
1.1.1.6   root      561: 
1.1.1.10! root      562:        pTempName[outpos] = 0;
1.1.1.6   root      563: 
1.1.1.10! root      564:        strcpy(pFileName, pTempName);          /* Copy back */
        !           565:        free(pTempName);
1.1.1.8   root      566: }
                    567: 
                    568: 
                    569: /*-----------------------------------------------------------------------*/
                    570: /*
                    571:   Create a valid path name from a possibly invalid name by erasing invalid
                    572:   path parts at the end of the string.
                    573:   pPathName needs to point to a buffer of at least FILENAME_MAX bytes.
                    574: */
                    575: void File_MakeValidPathName(char *pPathName)
                    576: {
1.1.1.10! root      577:        struct stat dirstat;
        !           578:        char *pLastSlash;
1.1.1.8   root      579: 
1.1.1.10! root      580:        do
        !           581:        {
        !           582:                /* Check for a valid path */
        !           583:                if (stat(pPathName, &dirstat) == 0 && S_ISDIR(dirstat.st_mode))
        !           584:                {
        !           585:                        break;
        !           586:                }
        !           587: 
        !           588:                pLastSlash = strrchr(pPathName, PATHSEP);
        !           589:                if (pLastSlash)
        !           590:                {
        !           591:                        /* Erase the (probably invalid) part after the last slash */
        !           592:                        *pLastSlash = 0;
        !           593:                }
        !           594:                else
        !           595:                {
        !           596:                        /* Path name seems to be completely invalid -> set to root directory */
        !           597:                        pPathName[0] = PATHSEP;
        !           598:                        pPathName[1] = 0;
        !           599:                }
        !           600:        }
        !           601:        while (pLastSlash);
1.1.1.6   root      602: }

unix.superglobalmegacorp.com

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