physfs.c
changeset 23 bd6ba9c8717c
parent 22 49f6101707b4
child 25 96b32c0fd7f3
equal deleted inserted replaced
22:49f6101707b4 23:bd6ba9c8717c
     9  */
     9  */
    10 
    10 
    11 #include <stdio.h>
    11 #include <stdio.h>
    12 #include <stdlib.h>
    12 #include <stdlib.h>
    13 #include <string.h>
    13 #include <string.h>
       
    14 #include <unistd.h>
    14 #include <assert.h>
    15 #include <assert.h>
    15 #include "physfs.h"
    16 #include "physfs.h"
    16 
    17 
    17 #define __PHYSICSFS_INTERNAL__
    18 #define __PHYSICSFS_INTERNAL__
    18 #include "physfs_internal.h"
    19 #include "physfs_internal.h"
   274 
   275 
   275     return(retval);
   276     return(retval);
   276 } /* calculateUserDir */
   277 } /* calculateUserDir */
   277 
   278 
   278 
   279 
       
   280 static int appendDirSep(char **dir)
       
   281 {
       
   282     const char *dirsep = PHYSFS_getDirSeparator();
       
   283     char *ptr;
       
   284 
       
   285     if (strcmp((*dir + strlen(*dir)) - strlen(dirsep), dirsep) == 0)
       
   286         return(1);
       
   287 
       
   288     ptr = realloc(*dir, strlen(*dir) + strlen(dirsep) + 1);
       
   289     if (!ptr)
       
   290     {
       
   291         free(*dir);
       
   292         return(0);
       
   293     } /* if */
       
   294 
       
   295     strcat(ptr, dirsep);
       
   296     *dir = ptr;
       
   297     return(1);
       
   298 } /* appendDirSep */
       
   299 
       
   300 
   279 static char *calculateBaseDir(const char *argv0)
   301 static char *calculateBaseDir(const char *argv0)
   280 {
   302 {
   281 assert(0); return(NULL);
   303     const char *dirsep = PHYSFS_getDirSeparator();
       
   304     char *retval;
       
   305     char *ptr;
       
   306     int allocSize = 0;
       
   307 
       
   308     /*
       
   309      * See if the platform driver wants to handle this for us...
       
   310      */
       
   311     retval = __PHYSFS_platformCalcBaseDir(argv0);
       
   312     if (retval != NULL)
       
   313         return(retval);
       
   314 
       
   315     /*
       
   316      * Determine if there's a path on argv0. If there is, that's the base dir.
       
   317      */
       
   318     ptr = strstr(argv0, dirsep);
       
   319     if (ptr != NULL)
       
   320     {
       
   321         char *p = ptr;
       
   322         size_t size;
       
   323         while (p != NULL)
       
   324         {
       
   325             ptr = p;
       
   326             p = strstr(p + 1, dirsep);
       
   327         } /* while */
       
   328 
       
   329         size = (size_t) (ptr - argv0);  /* !!! is this portable? */
       
   330         retval = (char *) malloc(size + 1);
       
   331         BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
       
   332         memcpy(retval, argv0, size);
       
   333         retval[size] = '\0';
       
   334         return(retval);
       
   335     } /* if */
       
   336 
       
   337     /*
       
   338      * Last ditch effort: it's the current working directory. (*shrug*)
       
   339      */
       
   340     do
       
   341     {
       
   342         allocSize += 100;
       
   343         ptr = (char *) realloc(retval, allocSize);
       
   344         if (ptr == NULL)
       
   345         {
       
   346             if (retval != NULL)
       
   347                 free(retval);
       
   348             BAIL_IF_MACRO(1, ERR_OUT_OF_MEMORY, NULL);
       
   349         } /* if */
       
   350 
       
   351         retval = ptr;
       
   352         ptr = getcwd(retval, allocSize);
       
   353     } while (ptr == NULL);
       
   354 
       
   355     return(retval);
   282 } /* calculateBaseDir */
   356 } /* calculateBaseDir */
   283 
   357 
   284 
   358 
   285 int PHYSFS_init(const char *argv0)
   359 int PHYSFS_init(const char *argv0)
   286 {
   360 {
   287     BAIL_IF_MACRO(initialized, ERR_IS_INITIALIZED, 0);
   361     BAIL_IF_MACRO(initialized, ERR_IS_INITIALIZED, 0);
   288     BAIL_IF_MACRO(argv0 == NULL, ERR_INVALID_ARGUMENT, 0);
   362     BAIL_IF_MACRO(argv0 == NULL, ERR_INVALID_ARGUMENT, 0);
   289 
   363 
   290     baseDir = calculateBaseDir(argv0);
   364     baseDir = calculateBaseDir(argv0);
   291     BAIL_IF_MACRO(baseDir == NULL, NULL, 0);
   365     BAIL_IF_MACRO(baseDir == NULL, NULL, 0);
       
   366     BAIL_IF_MACRO(!appendDirSep(&baseDir), NULL, 0);
   292 
   367 
   293     userDir = calculateUserDir();
   368     userDir = calculateUserDir();
   294     if (userDir == NULL)
   369     if ((userDir == NULL) || (!appendDirSep(&userDir)))
   295     {
   370     {
   296         free(baseDir);
   371         free(baseDir);
   297         baseDir = NULL;
   372         baseDir = NULL;
   298         return(0);
   373         return(0);
   299     } /* if */
   374     } /* if */
   448 
   523 
   449     BAIL_IF_MACRO(di == NULL, NULL, 0);
   524     BAIL_IF_MACRO(di == NULL, NULL, 0);
   450 
   525 
   451     if (appendToPath)
   526     if (appendToPath)
   452     {
   527     {
   453         di->next = searchPath;
       
   454         searchPath = di;
       
   455     } /* if */
       
   456     else
       
   457     {
       
   458         DirInfo *i = searchPath;
   528         DirInfo *i = searchPath;
   459         DirInfo *prev = NULL;
   529         DirInfo *prev = NULL;
   460 
   530 
   461         di->next = NULL;
   531         di->next = NULL;
   462         while (i != NULL)
   532         while (i != NULL)
       
   533         {
   463             prev = i;
   534             prev = i;
       
   535             i = i->next;
       
   536         } /* while */
   464 
   537 
   465         if (prev == NULL)
   538         if (prev == NULL)
   466             searchPath = di;
   539             searchPath = di;
   467         else
   540         else
   468             prev->next = di;
   541             prev->next = di;
       
   542     } /* if */
       
   543     else
       
   544     {
       
   545         di->next = searchPath;
       
   546         searchPath = di;
   469     } /* else */
   547     } /* else */
   470 
   548 
   471     return(1);
   549     return(1);
   472 } /* PHYSFS_addToSearchPath */
   550 } /* PHYSFS_addToSearchPath */
   473 
   551 
  1018 } /* PHYSFS_openAppend */
  1096 } /* PHYSFS_openAppend */
  1019 
  1097 
  1020 
  1098 
  1021 PHYSFS_file *PHYSFS_openRead(const char *fname)
  1099 PHYSFS_file *PHYSFS_openRead(const char *fname)
  1022 {
  1100 {
  1023     PHYSFS_file *retval = (PHYSFS_file *) malloc(sizeof (PHYSFS_file));
  1101     PHYSFS_file *retval;
  1024     FileHandle *rc = NULL;
  1102     FileHandle *rc = NULL;
  1025     FileHandleList *list;
  1103     FileHandleList *list;
  1026     DirInfo *i;
  1104     DirInfo *i;
  1027 
  1105 
       
  1106     retval = (PHYSFS_file *) malloc(sizeof (PHYSFS_file));
  1028     BAIL_IF_MACRO(!retval, ERR_OUT_OF_MEMORY, NULL);
  1107     BAIL_IF_MACRO(!retval, ERR_OUT_OF_MEMORY, NULL);
  1029     list = (FileHandleList *) malloc(sizeof (FileHandleList));
  1108     list = (FileHandleList *) malloc(sizeof (FileHandleList));
  1030     BAIL_IF_MACRO(!list, ERR_OUT_OF_MEMORY, NULL);
  1109     if (!list)
       
  1110     {
       
  1111         free(retval);
       
  1112         BAIL_IF_MACRO(1, ERR_OUT_OF_MEMORY, NULL);
       
  1113     } /* if */
  1031 
  1114 
  1032     for (i = searchPath; i != NULL; i = i->next)
  1115     for (i = searchPath; i != NULL; i = i->next)
  1033     {
  1116     {
  1034         DirHandle *h = i->dirHandle;
  1117         DirHandle *h = i->dirHandle;
  1035         if (__PHYSFS_verifySecurity(h, fname))
  1118         if (__PHYSFS_verifySecurity(h, fname))