Annotation of hatari/src/paths.c, revision 1.1.1.4

1.1       root        1: /*
                      2:   Hatari - paths.c
                      3: 
                      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: 
                      7:   Set up the various path strings.
                      8: */
1.1.1.4 ! root        9: const char Paths_fileid[] = "Hatari paths.c : " __DATE__ " " __TIME__;
1.1       root       10: 
                     11: #include <unistd.h>
                     12: #include <sys/stat.h>
                     13: #include <sys/types.h>
                     14: 
                     15: #include "config.h"
                     16: #include "main.h"
                     17: #include "file.h"
                     18: #include "paths.h"
                     19: 
1.1.1.2   root       20: #ifdef WIN32
                     21: #define mkdir(name,mode) mkdir(name)
                     22: #endif  /* WIN32 */
                     23: 
1.1.1.3   root       24: static char sWorkingDir[FILENAME_MAX];    /* Working directory */
1.1       root       25: static char sDataDir[FILENAME_MAX];       /* Directory where data files of Hatari can be found */
                     26: static char sUserHomeDir[FILENAME_MAX];   /* User's home directory ($HOME) */
                     27: static char sHatariHomeDir[FILENAME_MAX]; /* Hatari's home directory ($HOME/.hatari/) */
                     28: 
                     29: 
                     30: /**
                     31:  * Return pointer to current working directory string
                     32:  */
                     33: const char *Paths_GetWorkingDir(void)
                     34: {
                     35:        return sWorkingDir;
                     36: }
                     37: 
                     38: /**
                     39:  * Return pointer to data directory string
                     40:  */
                     41: const char *Paths_GetDataDir(void)
                     42: {
                     43:        return sDataDir;
                     44: }
                     45: 
                     46: /**
                     47:  * Return pointer to user's home directory string
                     48:  */
                     49: const char *Paths_GetUserHome(void)
                     50: {
                     51:        return sUserHomeDir;
                     52: }
                     53: 
                     54: /**
                     55:  * Return pointer to Hatari's home directory string
                     56:  */
                     57: const char *Paths_GetHatariHome(void)
                     58: {
                     59:        return sHatariHomeDir;
                     60: }
                     61: 
                     62: 
                     63: /**
                     64:  * Explore the PATH environment variable to see where our executable is
                     65:  * installed.
                     66:  */
1.1.1.3   root       67: static void Paths_GetExecDirFromPATH(const char *argv0, char *pExecDir, int nMaxLen)
1.1       root       68: {
                     69:        char *pPathEnv;
                     70:        char *pAct;
                     71:        char *pTmpName;
                     72:        const char *pToken;
                     73: 
                     74:        /* Get the PATH environment string */
                     75:        pPathEnv = getenv("PATH");
                     76:        if (!pPathEnv)
                     77:                return;
                     78:        /* Duplicate the string because strtok destroys it later */
                     79:        pPathEnv = strdup(pPathEnv);
                     80:        if (!pPathEnv)
                     81:                return;
                     82: 
                     83:        pTmpName = malloc(FILENAME_MAX);
                     84:        if (!pTmpName)
                     85:                return;
                     86: 
                     87:        /* If there is a semicolon in the PATH, we assume it is the PATH
                     88:         * separator token (like on Windows), otherwise we use a colon. */
                     89:        if (strchr((pPathEnv), ';'))
                     90:                pToken = ";";
                     91:        else
                     92:                pToken = ":";
                     93: 
                     94:        pAct = strtok (pPathEnv, pToken);
                     95:        while (pAct)
                     96:        {
                     97:                snprintf(pTmpName, FILENAME_MAX, "%s%c%s",
                     98:                         pAct, PATHSEP, argv0);
                     99:                if (File_Exists(pTmpName))
                    100:                {
                    101:                        /* Found the executable - so use the corresponding path: */
                    102:                        strncpy(pExecDir, pAct, nMaxLen);
                    103:                        pExecDir[nMaxLen-1] = 0;
                    104:                        break;
                    105:                }
                    106:                pAct = strtok (0, pToken);
                    107:        }
                    108: 
                    109:        free(pPathEnv);
                    110:        free(pTmpName);
                    111: }
                    112: 
                    113: 
                    114: /**
                    115:  * Locate the directory where the hatari executable resides
                    116:  */
1.1.1.3   root      117: static char *Paths_InitExecDir(const char *argv0)
1.1       root      118: {
                    119:        char *psExecDir;  /* Path string where the hatari executable can be found */
                    120: 
                    121:        /* Allocate memory for storing the path string of the executable */
                    122:        psExecDir = malloc(FILENAME_MAX);
                    123:        if (!psExecDir)
                    124:        {
                    125:                fprintf(stderr, "Out of memory (Paths_Init)\n");
                    126:                exit(-1);
                    127:        }
                    128: 
                    129:        /* Determine the bindir...
                    130:         * Start with empty string, then try to use OS specific functions,
                    131:         * and finally analyze the PATH variable if it has not been found yet. */
                    132:        psExecDir[0] = '\0';
                    133: 
                    134: #if defined(__linux__)
                    135:        {
                    136:                int i;
                    137:                /* On Linux, we can analyze the symlink /proc/self/exe */
                    138:                i = readlink("/proc/self/exe", psExecDir, FILENAME_MAX);
                    139:                if (i > 0)
                    140:                {
                    141:                        char *p;
                    142:                        psExecDir[i] = '\0';
                    143:                        p = strrchr(psExecDir, '/');    /* Search last slash */
                    144:                        if (p)
                    145:                                *p = 0;                     /* Strip file name from path */
                    146:                }
                    147:        }
                    148: //#elif defined(WIN32) || defined(__CEGCC__)
                    149: //     /* On Windows we can use GetModuleFileName for getting the exe path */
                    150: //     GetModuleFileName(NULL, psExecDir, FILENAME_MAX);
                    151: #endif
                    152: 
                    153:        /* If we do not have the execdir yet, analyze argv[0] and the PATH: */
                    154:        if (psExecDir[0] == 0)
                    155:        {
                    156:                if (strchr(argv0, PATHSEP) == 0)
                    157:                {
                    158:                        /* No separator in argv[0], we have to explore PATH... */
                    159:                        Paths_GetExecDirFromPATH(argv0, psExecDir, FILENAME_MAX);
                    160:                }
                    161:                else
                    162:                {
                    163:                        /* There was a path separator in argv[0], so let's assume a
                    164:                         * relative or absolute path to the current directory in argv[0] */
                    165:                        char *p;
                    166:                        strncpy(psExecDir, argv0, FILENAME_MAX);
                    167:                        psExecDir[FILENAME_MAX-1] = 0;
                    168:                        p = strrchr(psExecDir, PATHSEP);  /* Search last slash */
                    169:                        if (p)
                    170:                                *p = 0;                       /* Strip file name from path */
                    171:                }
                    172:        }
                    173: 
                    174:        return psExecDir;
                    175: }
                    176: 
                    177: 
                    178: /**
                    179:  * Initialize the users home directory string
                    180:  * and Hatari's home directory (~/.hatari)
                    181:  */
                    182: static void Paths_InitHomeDirs(void)
                    183: {
                    184:        char *psHome;
                    185: 
                    186:        psHome = getenv("HOME");
                    187:        if (!psHome)
                    188:        {
                    189:                /* $HOME not set, so let's use current working dir as home */
                    190:                strcpy(sUserHomeDir, sWorkingDir);
                    191:                strcpy(sHatariHomeDir, sWorkingDir);
                    192:        }
                    193:        else
                    194:        {
                    195:                strncpy(sUserHomeDir, psHome, FILENAME_MAX);
                    196:                sUserHomeDir[FILENAME_MAX-1] = 0;
                    197: 
                    198:                /* Try to use a .hatari directory in the users home directory */
                    199:                snprintf(sHatariHomeDir, FILENAME_MAX, "%s%c.hatari",
                    200:                         sUserHomeDir, PATHSEP);
                    201:                if (!File_DirectoryExists(sHatariHomeDir))
                    202:                {
                    203:                        /* Hatari home directory does not exists yet...
                    204:                         * ...so let's try to create it: */
                    205:                        if (mkdir(sHatariHomeDir, 0755) != 0)
                    206:                        {
                    207:                                /* Failed to create, so use user's home dir instead */
                    208:                                strcpy(sHatariHomeDir, sUserHomeDir);
                    209:                        }
                    210:                }
                    211:        }
                    212: }
                    213: 
                    214: 
                    215: /**
                    216:  * Initialize directory names
                    217:  *
                    218:  * The datadir will be initialized relative to the bindir (where the executable
                    219:  * has been installed to). This means a lot of additional effort since we first
                    220:  * have to find out where the executable is. But thanks to this effort, we get
                    221:  * a relocatable package (we don't have any absolute path names in the program)!
                    222:  */
1.1.1.3   root      223: void Paths_Init(const char *argv0)
1.1       root      224: {
                    225:        char *psExecDir;  /* Path string where the hatari executable can be found */
                    226: 
                    227:        /* Init working directory string */
                    228:        getcwd(sWorkingDir, FILENAME_MAX);
                    229: 
                    230:        /* Init the user's home directory string */
                    231:        Paths_InitHomeDirs();
                    232: 
                    233:        /* Get the directory where the executable resides */
                    234:        psExecDir = Paths_InitExecDir(argv0);
                    235: 
                    236:        /* Now create the datadir path name from the bindir path name: */
                    237:        if (psExecDir && strlen(psExecDir) > 0)
                    238:        {
                    239:                snprintf(sDataDir, sizeof(sDataDir), "%s%c%s",
                    240:                         psExecDir, PATHSEP, BIN2DATADIR);
                    241:        }
                    242:        else
                    243:        {
                    244:                /* bindir could not be determined, let's assume datadir is relative
                    245:                 * to current working directory... */
                    246:                strcpy(sDataDir, BIN2DATADIR);
                    247:        }
                    248: 
                    249:        /* And finally make a proper absolute path out of datadir: */
                    250:        File_MakeAbsoluteName(sDataDir);
                    251: 
                    252:        free(psExecDir);
                    253: 
                    254:        /* fprintf(stderr, " WorkingDir = %s\n DataDir = %s\n UserHomeDir = %s\n HatariHomeDir = %s\n",
                    255:                sWorkingDir, sDataDir, sUserHomeDir, sHatariHomeDir); */
                    256: }

unix.superglobalmegacorp.com

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