PRIVATE char* expandTilde ( const char* destBuff, char** srcPtrPtr, const size_t destBuffSize ) { register char* dstPtr = (char*)destBuff; register char* srcPtr; ASSERT_RTN (destBuff != NULL, "expandTilde: no destBuff", NULL); ASSERT_RTN (srcPtrPtr != NULL, "expandTilde: no srcPtrPtr", NULL); ASSERT_RTN (destBuffSize > 0, "expandTilde: no destBuffSize", NULL); if ((destBuff == NULL) || (srcPtrPtr == NULL) || (destBuffSize == 0)) { return (NULL); } srcPtr = *srcPtrPtr; ASSERT_RTN (srcPtr != NULL, "expandTilde: no srcPtr", NULL); if (srcPtr == NULL) return (NULL); if ((*srcPtr == '~') && (destBuffSize > 0)) { ++srcPtr; if ((*srcPtr == '/') || (*srcPtr == '\0')) { /* expand `~' to this user's home directory. */ dstPtr = getHomeDir (dstPtr, destBuffSize); } else { /* Buggy: we assume we have a username at srcPtr. */ /* expand `~<username>' to some <username>'s home directory. */ int index; char* userName; register char* tmpDst; if ((userName=(char*)CSC_MALLOC_FUNC(1,80)) != NULL) /* bug #1 */ { tmpDst = userName; index = 79; while ((*srcPtr != '/') && (*srcPtr != '\0') && (index-- > 0)) { *tmpDst++ = *srcPtr++; } *tmpDst = '\0'; dstPtr = getUserHomeDir (dstPtr, userName, destBuffSize); (void)CSC_FREE_FUNC (userName); } } } *srcPtrPtr = srcPtr; return (dstPtr); }
PUBLIC char* (CSCfileGetUserHomeDir) ( const char* const userName, const size_t pathSize, CSCmemListType const memList, int memTag ) { char* userDirPath = NULL; ASSERT_RTN (userName != NULL, "CSCfileGetUserHomeDir: no userName", NULL); ASSERT_RTN (pathSize > 0, "CSCfileGetUserHomeDir: no pathSize", NULL); ASSERT_RTN (memList != NULL, "cscFileGetUserHomeDir: NULL memList", NULL); if ((userName == NULL) || (pathSize == 0) || (memList == NULL)) { return (NULL); } if (CSCmemAlloc(memList,(void**)&userDirPath,1,pathSize,memTag) == CSC_OK) { userDirPath = getUserHomeDir (userDirPath, (char*)userName, pathSize); } return (userDirPath); }
/* Find the directory in which FontForge places all of its configurations and * save files. On Unix-likes, the argument `dir` (see the below case switch, * enum in inc/gfile.h) determines which directory is returned according to the * XDG Base Directory Specification. On Windows, the argument is ignored--the * home directory as obtained by getUserHomeDir() appended with "/FontForge" is * returned. On error, NULL is returned. * * http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html */ char *getFontForgeUserDir(int dir) { const char *def; const char *home, *xdg; char *buf = NULL; /* find home directory first, it is needed if any of the xdg env vars are * not set */ if (!(home = getUserHomeDir())) { /* if getUserHomeDir returns NULL, pass NULL to calling function */ fprintf(stderr, "%s\n", "cannot find home directory"); return NULL; } #if defined(__MINGW32__) /* Allow for preferences to be saved locally in a 'portable' configuration. */ if (getenv("FF_PORTABLE") != NULL) { buf = smprintf("%s/preferences/", getShareDir()); } else { buf = smprintf("%s/FontForge/", home); } return buf; #else /* Home directory exists, so check for environment variables. For each of * XDG_{CACHE,CONFIG,DATA}_HOME, assign `def` as the corresponding fallback * for if the environment variable does not exist. */ switch(dir) { case Cache: xdg = getenv("XDG_CACHE_HOME"); def = ".cache"; break; case Config: xdg = getenv("XDG_CONFIG_HOME"); def = ".config"; break; case Data: xdg = getenv("XDG_DATA_HOME"); def = ".local/share"; break; default: /* for an invalid argument, return NULL */ fprintf(stderr, "%s\n", "invalid input"); return NULL; } if(xdg != NULL) /* if, for example, XDG_CACHE_HOME exists, assign the value * "$XDG_CACHE_HOME/fontforge" */ buf = smprintf("%s/fontforge", xdg); else /* if, for example, XDG_CACHE_HOME does not exist, instead assign * the value "$HOME/.cache/fontforge" */ buf = smprintf("%s/%s/fontforge", home, def); if(buf != NULL) { /* try to create buf. If creating the directory fails, return NULL * because nothing will get saved into an inaccessible directory. */ if(mkdir_p(buf, 0755) != EXIT_SUCCESS) return NULL; return buf; } return NULL; #endif }