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

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

unix.superglobalmegacorp.com

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