Annotation of previous_trunk/src/paths.c, revision 1.1

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

unix.superglobalmegacorp.com

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