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

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

unix.superglobalmegacorp.com

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