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:
@@ -32,6 +32,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||||||
#define CLIENT_WINDOW_TITLE "OpenArena"
|
#define CLIENT_WINDOW_TITLE "OpenArena"
|
||||||
#define CLIENT_WINDOW_MIN_TITLE "OA"
|
#define CLIENT_WINDOW_MIN_TITLE "OA"
|
||||||
#define HOMEPATH_NAME_UNIX ".openarena"
|
#define HOMEPATH_NAME_UNIX ".openarena"
|
||||||
|
#define HOMEPATH_NAME_XDG "openarena"
|
||||||
#define HOMEPATH_NAME_WIN "OpenArena"
|
#define HOMEPATH_NAME_WIN "OpenArena"
|
||||||
#define HOMEPATH_NAME_MACOSX HOMEPATH_NAME_WIN
|
#define HOMEPATH_NAME_MACOSX HOMEPATH_NAME_WIN
|
||||||
#define GAMENAME_FOR_MASTER "Quake3Arena" // must NOT contain whitespace. No servers show up if you use "openarena"
|
#define GAMENAME_FOR_MASTER "Quake3Arena" // must NOT contain whitespace. No servers show up if you use "openarena"
|
||||||
|
@@ -1110,7 +1110,7 @@ char *Sys_DefaultAppPath(void);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void Sys_SetDefaultHomePath(const char *path);
|
void Sys_SetDefaultHomePath(const char *path);
|
||||||
char *Sys_DefaultHomePath(void);
|
const char *Sys_DefaultHomePath(void);
|
||||||
const char *Sys_Dirname( char *path );
|
const char *Sys_Dirname( char *path );
|
||||||
const char *Sys_Basename( char *path );
|
const char *Sys_Basename( char *path );
|
||||||
char *Sys_ConsoleInput(void);
|
char *Sys_ConsoleInput(void);
|
||||||
|
@@ -44,12 +44,138 @@ qboolean stdinIsATTY;
|
|||||||
// Used to determine where to store user-specific files
|
// Used to determine where to store user-specific files
|
||||||
static char homePath[ MAX_OSPATH ] = { 0 };
|
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
|
Sys_DefaultHomePath
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
char *Sys_DefaultHomePath(void)
|
const char *Sys_DefaultHomePath(void)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
@@ -67,10 +193,14 @@ char *Sys_DefaultHomePath(void)
|
|||||||
else
|
else
|
||||||
Q_strcat(homePath, sizeof(homePath), HOMEPATH_NAME_MACOSX);
|
Q_strcat(homePath, sizeof(homePath), HOMEPATH_NAME_MACOSX);
|
||||||
#else
|
#else
|
||||||
|
#if 0
|
||||||
if(com_homepath->string[0])
|
if(com_homepath->string[0])
|
||||||
Q_strcat(homePath, sizeof(homePath), com_homepath->string);
|
Q_strcat(homePath, sizeof(homePath), com_homepath->string);
|
||||||
else
|
else
|
||||||
Q_strcat(homePath, sizeof(homePath), HOMEPATH_NAME_UNIX);
|
Q_strcat(homePath, sizeof(homePath), HOMEPATH_NAME_UNIX);
|
||||||
|
#endif
|
||||||
|
CreateXDGPathAndMisc();
|
||||||
|
Com_sprintf(homePath, sizeof(homePath), "%s", homeXdg);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -92,7 +92,7 @@ void Sys_SetFloatEnv(void)
|
|||||||
Sys_DefaultHomePath
|
Sys_DefaultHomePath
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
char *Sys_DefaultHomePath( void )
|
const char *Sys_DefaultHomePath( void )
|
||||||
{
|
{
|
||||||
TCHAR szPath[MAX_PATH];
|
TCHAR szPath[MAX_PATH];
|
||||||
FARPROC qSHGetFolderPath;
|
FARPROC qSHGetFolderPath;
|
||||||
|
Reference in New Issue
Block a user