Started to implement Issue #30. XDG folder structure. All weaknesses from the old system are still there:

HOME must be defined: Not a regression
Only one level of mkdir: Not a regression (but might be more relevant)

com_homepath is not fully implemented and it will need to be set to "openarena" instead of ".openarena". But that just makes it like Mac.
This commit is contained in:
sago007
2016-12-28 15:28:19 +01:00
parent 6aab9a0fb6
commit 4209b06c26
4 changed files with 134 additions and 3 deletions

View File

@@ -32,6 +32,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define CLIENT_WINDOW_TITLE "OpenArena"
#define CLIENT_WINDOW_MIN_TITLE "OA"
#define HOMEPATH_NAME_UNIX ".openarena"
#define HOMEPATH_NAME_XDG "openarena"
#define HOMEPATH_NAME_WIN "OpenArena"
#define HOMEPATH_NAME_MACOSX HOMEPATH_NAME_WIN
#define GAMENAME_FOR_MASTER "Quake3Arena" // must NOT contain whitespace. No servers show up if you use "openarena"

View File

@@ -1110,7 +1110,7 @@ char *Sys_DefaultAppPath(void);
#endif
void Sys_SetDefaultHomePath(const char *path);
char *Sys_DefaultHomePath(void);
const char *Sys_DefaultHomePath(void);
const char *Sys_Dirname( char *path );
const char *Sys_Basename( char *path );
char *Sys_ConsoleInput(void);

View File

@@ -44,12 +44,138 @@ qboolean stdinIsATTY;
// Used to determine where to store user-specific files
static char homePath[ MAX_OSPATH ] = { 0 };
/* Contains the XDG home path. Typically $HOME/.local/share/openarena */
static char homeXdg[ MAX_OSPATH ] = { 0 };
/* Contains the classic home path. Typically $HOME/.openarena */
static char homeClassic[ MAX_OSPATH ] = { 0 };
static const char* getHome(void) {
return getenv("HOME");
}
/**
* Concatenates the XDG pathname. Normally "openarena".
* @param dest Buffer to concatenate "openarea" to.
* @param n Size of buffer
*/
static void Sys_ConcatXdgHomepathName(char* dest, size_t n) {
if(com_homepath->string[0])
Q_strcat(dest, n, com_homepath->string);
else
Q_strcat(dest, n, HOMEPATH_NAME_XDG);
}
/**
* Assignes a buffer with the value of the Xdg home.
* Normally: "$HOME/.local/share/openarena"
* If it failes the destination buffer will be the empty string.
* @param dest Buffer to place the value into
* @param n Size of buffer
*/
static void Sys_SetXdgDataHomePath(char* dest, size_t n) {
const char* xdgDataPath = getenv("XDG_DATA_HOME");
dest[0] = '\0';
if (xdgDataPath) {
Com_sprintf(dest, n, "%s/", xdgDataPath);
Sys_ConcatXdgHomepathName(dest, n);
return;
}
const char* homeFolder = getHome();
if (homeFolder) {
Com_sprintf(dest, n, "%s/.local/share/", homeFolder);
Sys_ConcatXdgHomepathName(dest, n);
}
}
/**
* Sets the global variables homeClassic and home Xdg.
*/
static void Sys_SetHomePaths( void ) {
Sys_SetXdgDataHomePath(homeXdg, sizeof(homeXdg));
const char* p = getHome();
Com_sprintf(homeClassic, sizeof(homeClassic), "%s%c", p, PATH_SEP);
Q_strcat(homeClassic, sizeof(homeClassic), HOMEPATH_NAME_UNIX);
}
/**
* Retruns true if the file exists and is a symbolic link
* @param path The path to the file.
* @return True if it is a confirmed symbolic link, false otherwise.
*/
static qboolean Sys_IsSymbolic(const char* path) {
struct stat buf;
int errCode = lstat(path, &buf);
return (errCode == 0);
}
/**
* Checks if a given file exists and is a directory.
* @param path Path to the file
* @return True if it is a directory and false otherwise.
*/
static qboolean Sys_IsDir(const char* path) {
struct stat buf;
int errCode = stat(path, &buf);
if (errCode != 0) {
return qfalse;
}
return S_ISDIR(buf.st_mode);
}
/**
* Deletes a symbolic link if it does not point to a directory.
* Otherwise: Do nothing.
* @param path Path to the symlink.
*/
static void Sys_RemoveInvalidSymlinkToDir(const char* path) {
if (Sys_IsSymbolic(path) && !Sys_IsDir(path)) {
//If the file is symbolic but does not a dir then it must either be invalid or point to something not a dir.
unlink(path);
}
}
static void CreateXDGPathAndMisc( void ) {
Sys_SetHomePaths();
Sys_RemoveInvalidSymlinkToDir(homeXdg);
Sys_RemoveInvalidSymlinkToDir(homeClassic);
if (Sys_IsDir(homeXdg) && Sys_IsDir(homeClassic)) {
//Both classic and xdg homedirs both exists.
//In the future only test on homeXdg.
return;
}
if (Sys_IsDir(homeClassic) && !Sys_IsDir(homeXdg) ) {
//Try to move the old home dir to the new location.
int errCode = rename(homeClassic, homeXdg);
if (errCode) {
Com_Printf("Failed to move \"%s\" to \"%s\". Error code: %d. Non fatal.", homeClassic, homeXdg, errCode);
}
}
if (Sys_IsDir(homeXdg)) {
int errCode = Sys_Mkdir(homeXdg);
if (errCode) {
Com_Printf("Failed to create \"%s\". Error code: %d. This is quite bad.", homeXdg, errCode);
}
}
if (Sys_IsDir(homeXdg) && !Sys_IsDir(homeClassic)) {
int errCode = symlink(homeXdg, homeClassic);
if (errCode) {
Com_Printf("Failed to create symbolic link \"%s\". Error code: %d. This is quite bad.", homeClassic, errCode);
}
}
if (!Sys_IsDir(homeXdg) && Sys_IsDir(homeClassic)) {
int errCode = symlink(homeClassic, homeXdg);
if (errCode) {
Com_Printf("Failed to create symbolic link \"%s\". Error code: %d. This is quite bad.", homeXdg, errCode);
}
}
}
/*
==================
Sys_DefaultHomePath
==================
*/
char *Sys_DefaultHomePath(void)
const char *Sys_DefaultHomePath(void)
{
char *p;
@@ -67,10 +193,14 @@ char *Sys_DefaultHomePath(void)
else
Q_strcat(homePath, sizeof(homePath), HOMEPATH_NAME_MACOSX);
#else
#if 0
if(com_homepath->string[0])
Q_strcat(homePath, sizeof(homePath), com_homepath->string);
else
Q_strcat(homePath, sizeof(homePath), HOMEPATH_NAME_UNIX);
#endif
CreateXDGPathAndMisc();
Com_sprintf(homePath, sizeof(homePath), "%s", homeXdg);
#endif
}
}

View File

@@ -92,7 +92,7 @@ void Sys_SetFloatEnv(void)
Sys_DefaultHomePath
================
*/
char *Sys_DefaultHomePath( void )
const char *Sys_DefaultHomePath( void )
{
TCHAR szPath[MAX_PATH];
FARPROC qSHGetFolderPath;