misc/libphysfs/platform_unix.c
author nemo
Mon, 11 May 2015 13:53:08 -0400
changeset 10942 5d7dd938dedc
parent 9799 a3fe81c3bc02
child 12213 bb5522e88ab2
permissions -rw-r--r--
This probably fixes bug #839 - mine time was hardcoded to 3000 in Attack, instead of using the "0 as undefined" input that other places were using. When re653e96b0ec3 started paying attention to the input parameter, this previously ignored value became a problem.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
7768
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     1
/*
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     2
 * Unix support routines for PhysicsFS.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     3
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     4
 * Please see the file LICENSE.txt in the source's root directory.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     5
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     6
 *  This file written by Ryan C. Gordon.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     7
 */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     8
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     9
#define __PHYSICSFS_INTERNAL__
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    10
#include "physfs_platforms.h"
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    11
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    12
#ifdef PHYSFS_PLATFORM_UNIX
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    13
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    14
#include <ctype.h>
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    15
#include <unistd.h>
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    16
#include <sys/types.h>
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    17
#include <pwd.h>
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    18
#include <sys/stat.h>
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    19
#include <sys/param.h>
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    20
#include <dirent.h>
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    21
#include <time.h>
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    22
#include <errno.h>
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    23
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    24
#if PHYSFS_PLATFORM_LINUX && !defined(PHYSFS_HAVE_MNTENT_H)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    25
#define PHYSFS_HAVE_MNTENT_H 1
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    26
#elif PHYSFS_PLATFORM_SOLARIS && !defined(PHYSFS_HAVE_SYS_MNTTAB_H)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    27
#define PHYSFS_HAVE_SYS_MNTTAB_H 1
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    28
#elif PHYSFS_PLATFORM_BSD && !defined(PHYSFS_HAVE_SYS_UCRED_H)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    29
#define PHYSFS_HAVE_SYS_UCRED_H 1
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    30
#endif
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    31
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    32
#ifdef PHYSFS_HAVE_SYS_UCRED_H
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    33
#  ifdef PHYSFS_HAVE_MNTENT_H
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    34
#    undef PHYSFS_HAVE_MNTENT_H /* don't do both... */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    35
#  endif
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    36
#  include <sys/mount.h>
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    37
#  include <sys/ucred.h>
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    38
#endif
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    39
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    40
#ifdef PHYSFS_HAVE_MNTENT_H
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    41
#include <mntent.h>
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    42
#endif
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    43
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    44
#ifdef PHYSFS_HAVE_SYS_MNTTAB_H
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    45
#include <sys/mnttab.h>
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    46
#endif
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    47
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    48
#include "physfs_internal.h"
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    49
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    50
int __PHYSFS_platformInit(void)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    51
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    52
    return 1;  /* always succeed. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    53
} /* __PHYSFS_platformInit */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    54
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    55
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    56
int __PHYSFS_platformDeinit(void)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    57
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    58
    return 1;  /* always succeed. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    59
} /* __PHYSFS_platformDeinit */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    60
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    61
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    62
/* Stub version for platforms without CD-ROM support. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    63
void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    64
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    65
#if (defined PHYSFS_NO_CDROM_SUPPORT)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    66
    /* no-op. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    67
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    68
#elif (defined PHYSFS_HAVE_SYS_UCRED_H)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    69
    int i;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    70
    struct statfs *mntbufp = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    71
    int mounts = getmntinfo(&mntbufp, MNT_WAIT);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    72
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    73
    for (i = 0; i < mounts; i++)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    74
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    75
        int add_it = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    76
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    77
        if (strcmp(mntbufp[i].f_fstypename, "iso9660") == 0)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    78
            add_it = 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    79
        else if (strcmp( mntbufp[i].f_fstypename, "cd9660") == 0)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    80
            add_it = 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    81
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    82
        /* add other mount types here */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    83
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    84
        if (add_it)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    85
            cb(data, mntbufp[i].f_mntonname);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    86
    } /* for */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    87
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    88
#elif (defined PHYSFS_HAVE_MNTENT_H)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    89
    FILE *mounts = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    90
    struct mntent *ent = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    91
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    92
    mounts = setmntent("/etc/mtab", "r");
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    93
    BAIL_IF_MACRO(mounts == NULL, PHYSFS_ERR_IO, /*return void*/);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    94
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    95
    while ( (ent = getmntent(mounts)) != NULL )
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    96
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    97
        int add_it = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    98
        if (strcmp(ent->mnt_type, "iso9660") == 0)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    99
            add_it = 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   100
        else if (strcmp(ent->mnt_type, "udf") == 0)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   101
            add_it = 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   102
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   103
        /* !!! FIXME: these might pick up floppy drives, right? */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   104
        else if (strcmp(ent->mnt_type, "auto") == 0)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   105
            add_it = 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   106
        else if (strcmp(ent->mnt_type, "supermount") == 0)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   107
            add_it = 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   108
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   109
        /* !!! FIXME: udf? automount? */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   110
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   111
        /* add other mount types here */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   112
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   113
        if (add_it)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   114
            cb(data, ent->mnt_dir);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   115
    } /* while */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   116
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   117
    endmntent(mounts);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   118
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   119
#elif (defined PHYSFS_HAVE_SYS_MNTTAB_H)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   120
    FILE *mounts = fopen(MNTTAB, "r");
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   121
    struct mnttab ent;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   122
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   123
    BAIL_IF_MACRO(mounts == NULL, PHYSFS_ERR_IO, /*return void*/);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   124
    while (getmntent(mounts, &ent) == 0)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   125
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   126
        int add_it = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   127
        if (strcmp(ent.mnt_fstype, "hsfs") == 0)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   128
            add_it = 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   129
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   130
        /* add other mount types here */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   131
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   132
        if (add_it)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   133
            cb(data, ent.mnt_mountp);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   134
    } /* while */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   135
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   136
    fclose(mounts);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   137
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   138
#else
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   139
#error Unknown platform. Should have defined PHYSFS_NO_CDROM_SUPPORT, perhaps.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   140
#endif
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   141
} /* __PHYSFS_platformDetectAvailableCDs */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   142
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   143
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   144
/*
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   145
 * See where program (bin) resides in the $PATH specified by (envr).
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   146
 *  returns a copy of the first element in envr that contains it, or NULL
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   147
 *  if it doesn't exist or there were other problems. PHYSFS_SetError() is
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   148
 *  called if we have a problem.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   149
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   150
 * (envr) will be scribbled over, and you are expected to allocator.Free() the
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   151
 *  return value when you're done with it.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   152
 */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   153
static char *findBinaryInPath(const char *bin, char *envr)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   154
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   155
    size_t alloc_size = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   156
    char *exe = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   157
    char *start = envr;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   158
    char *ptr;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   159
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   160
    assert(bin != NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   161
    assert(envr != NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   162
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   163
    do
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   164
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   165
        size_t size;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   166
        size_t binlen;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   167
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   168
        ptr = strchr(start, ':');  /* find next $PATH separator. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   169
        if (ptr)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   170
            *ptr = '\0';
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   171
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   172
        binlen = strlen(bin);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   173
        size = strlen(start) + binlen + 2;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   174
        if (size > alloc_size)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   175
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   176
            char *x = (char *) allocator.Realloc(exe, size);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   177
            if (!x)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   178
            {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   179
                if (exe != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   180
                    allocator.Free(exe);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   181
                BAIL_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   182
            } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   183
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   184
            alloc_size = size;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   185
            exe = x;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   186
        } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   187
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   188
        /* build full binary path... */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   189
        strcpy(exe, start);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   190
        if ((exe[0] == '\0') || (exe[strlen(exe) - 1] != '/'))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   191
            strcat(exe, "/");
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   192
        strcat(exe, bin);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   193
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   194
        if (access(exe, X_OK) == 0)  /* Exists as executable? We're done. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   195
        {
9799
a3fe81c3bc02 Fix off-by-one in physfs
Dmitry Marakasov <amdmi3@amdmi3.ru>
parents: 8524
diff changeset
   196
            exe[size - binlen - 1] = '\0'; /* chop off filename, leave '/' */
7768
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   197
            return exe;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   198
        } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   199
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   200
        start = ptr + 1;  /* start points to beginning of next element. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   201
    } while (ptr != NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   202
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   203
    if (exe != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   204
        allocator.Free(exe);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   205
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   206
    return NULL;  /* doesn't exist in path. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   207
} /* findBinaryInPath */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   208
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   209
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   210
static char *readSymLink(const char *path)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   211
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   212
    ssize_t len = 64;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   213
    ssize_t rc = -1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   214
    char *retval = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   215
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   216
    while (1)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   217
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   218
         char *ptr = (char *) allocator.Realloc(retval, (size_t) len);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   219
         if (ptr == NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   220
             break;   /* out of memory. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   221
         retval = ptr;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   222
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   223
         rc = readlink(path, retval, len);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   224
         if (rc == -1)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   225
             break;  /* not a symlink, i/o error, etc. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   226
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   227
         else if (rc < len)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   228
         {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   229
             retval[rc] = '\0';  /* readlink doesn't null-terminate. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   230
             return retval;  /* we're good to go. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   231
         } /* else if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   232
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   233
         len *= 2;  /* grow buffer, try again. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   234
    } /* while */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   235
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   236
    if (retval != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   237
        allocator.Free(retval);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   238
    return NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   239
} /* readSymLink */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   240
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   241
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   242
char *__PHYSFS_platformCalcBaseDir(const char *argv0)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   243
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   244
    char *retval = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   245
    const char *envr = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   246
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   247
    /*
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   248
     * Try to avoid using argv0 unless forced to. If there's a Linux-like
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   249
     *  /proc filesystem, you can get the full path to the current process from
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   250
     *  the /proc/self/exe symlink.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   251
     */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   252
    retval = readSymLink("/proc/self/exe");
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   253
    if (retval == NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   254
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   255
        /* older kernels don't have /proc/self ... try PID version... */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   256
        const unsigned long long pid = (unsigned long long) getpid();
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   257
        char path[64];
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   258
        const int rc = (int) snprintf(path,sizeof(path),"/proc/%llu/exe",pid);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   259
        if ( (rc > 0) && (rc < sizeof(path)) )
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   260
            retval = readSymLink(path);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   261
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   262
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   263
    if (retval != NULL)  /* chop off filename. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   264
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   265
        char *ptr = strrchr(retval, '/');
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   266
        if (ptr != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   267
            *(ptr+1) = '\0';
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   268
        else  /* shouldn't happen, but just in case... */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   269
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   270
            allocator.Free(retval);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   271
            retval = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   272
        } /* else */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   273
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   274
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   275
    /* No /proc/self/exe, but we have an argv[0] we can parse? */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   276
    if ((retval == NULL) && (argv0 != NULL))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   277
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   278
        /* fast path: default behaviour can handle this. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   279
        if (strchr(argv0, '/') != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   280
            return NULL;  /* higher level parses out real path from argv0. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   281
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   282
        /* If there's no dirsep on argv0, then look through $PATH for it. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   283
        envr = getenv("PATH");
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   284
        if (envr != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   285
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   286
            char *path = (char *) __PHYSFS_smallAlloc(strlen(envr) + 1);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   287
            BAIL_IF_MACRO(!path, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   288
            strcpy(path, envr);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   289
            retval = findBinaryInPath(argv0, path);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   290
            __PHYSFS_smallFree(path);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   291
        } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   292
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   293
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   294
    if (retval != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   295
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   296
        /* try to shrink buffer... */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   297
        char *ptr = (char *) allocator.Realloc(retval, strlen(retval) + 1);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   298
        if (ptr != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   299
            retval = ptr;  /* oh well if it failed. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   300
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   301
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   302
    return retval;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   303
} /* __PHYSFS_platformCalcBaseDir */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   304
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   305
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   306
char *__PHYSFS_platformCalcPrefDir(const char *org, const char *app)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   307
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   308
    /*
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   309
     * We use XDG's base directory spec, even if you're not on Linux.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   310
     *  This isn't strictly correct, but the results are relatively sane
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   311
     *  in any case.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   312
     *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   313
     * http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   314
     */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   315
    const char *envr = getenv("XDG_DATA_HOME");
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   316
    const char *append = "/";
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   317
    char *retval = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   318
    size_t len = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   319
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   320
    if (!envr)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   321
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   322
        /* You end up with "$HOME/.local/share/Game Name 2" */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   323
        envr = __PHYSFS_getUserDir();
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   324
        BAIL_IF_MACRO(!envr, ERRPASS, NULL);  /* oh well. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   325
        append = ".local/share/";
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   326
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   327
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   328
    len = strlen(envr) + strlen(append) + strlen(app) + 2;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   329
    retval = (char *) allocator.Malloc(len);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   330
    BAIL_IF_MACRO(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   331
    snprintf(retval, len, "%s%s%s/", envr, append, app);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   332
    return retval;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   333
} /* __PHYSFS_platformCalcPrefDir */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   334
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   335
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   336
int __PHYSFS_platformSetDefaultAllocator(PHYSFS_Allocator *a)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   337
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   338
    return 0;  /* just use malloc() and friends. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   339
} /* __PHYSFS_platformSetDefaultAllocator */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   340
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   341
#endif /* PHYSFS_PLATFORM_UNIX */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   342
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   343
/* end of unix.c ... */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   344