mirror of
https://git.zap.org.au/git/trader.git
synced 2024-12-04 14:46:45 -05:00
Use the XDG Base Directory Specification for storing game files
This commit is contained in:
parent
88dc3b54a5
commit
b132686a63
8
NEWS
8
NEWS
@ -25,6 +25,14 @@ __ https://www.zap.org.au/
|
||||
Version 7.15 (not yet released)
|
||||
-------------------------------
|
||||
|
||||
Changed the default location where game files are saved from `~/.trader`
|
||||
to `~/.local/share/trader`, so as to follow the `XDG Base Directory
|
||||
Specification`__. If set, the ``XDG_DATA_HOME`` environment variable
|
||||
will override this location. If the `~/.trader` directory is already
|
||||
present, it will continue to be used. Updated the manual page to suit.
|
||||
|
||||
__ https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
|
||||
|
||||
Updated to GNU Gettext 0.20 or later. Updated to the latest snapshot of
|
||||
the Gnulib GNU Portability Library. Also updated the `INSTALL` file to
|
||||
list the latest tested versions of operating systems, including a new
|
||||
|
23
doc/trader.6
23
doc/trader.6
@ -154,6 +154,15 @@ Or, if you prefer the old amber screens of yesteryear:
|
||||
.\" *********************************************************************
|
||||
.SH ENVIRONMENT
|
||||
.TP
|
||||
.BR XDG_DATA_HOME ", " HOME
|
||||
If \fBXDG_DATA_HOME\fR is set to an absolute pathname (that is, a path
|
||||
that starts with \*(lq\fI/\fR\*(rq), Star Traders will use that
|
||||
directory, with a subdirectory \fItrader\fR, to store game files. If
|
||||
this environment variable is not set or does not start with
|
||||
\*(lq\fI/\fR\*(rq, \fI\(ti/.local/share/trader\fR will be used instead,
|
||||
where \*(lq\fI\(ti\fR\*(rq represents your home directory, as contained
|
||||
in the \fBHOME\fR environment variable.
|
||||
.TP
|
||||
.BR LINES ", " COLUMNS
|
||||
Star Traders uses the Curses library for displaying text on the screen.
|
||||
As such, it will access these two environment variables if the underlying
|
||||
@ -177,11 +186,17 @@ manual pages for more details on locale settings.
|
||||
.\" *********************************************************************
|
||||
.SH FILES
|
||||
.TP
|
||||
.IB \(ti/.local/share/trader/game N
|
||||
Star Traders stores saved game files in the \fI.local/share/trader\fR
|
||||
subdirectory in your home directory (unless overriden by the
|
||||
\fBXDG_DATA_HOME\fR environment variable). \fIN\fR is a number between
|
||||
\fB1\fR and \fB9\fR inclusive. The game file is scrambled to prevent you
|
||||
or others from casually cheating!
|
||||
.TP
|
||||
.IB \(ti/.trader/game N
|
||||
Star Traders stores saved game files in the \fI.trader\fR subdirectory in
|
||||
your home directory. \fIN\fR is a number between \fB1\fR and \fB9\fR
|
||||
inclusive. The game file is scrambled to prevent you or others from
|
||||
casually cheating!
|
||||
If the \fI\(ti/.trader\fR directory exists, game files will be read from
|
||||
and saved to this location instead. This is for compatibility with
|
||||
versions of Star Traders prior to version 7.15.
|
||||
.\" *********************************************************************
|
||||
.SH BUGS
|
||||
None yet known...
|
||||
|
84
src/utils.c
84
src/utils.c
@ -53,6 +53,10 @@ wchar_t *mon_thousands_sep; // Locale's monetary thousands separator
|
||||
* Module-specific constants and macros *
|
||||
************************************************************************/
|
||||
|
||||
#define DIRSEP "/" // Directory separator
|
||||
#define HIDDEN_PATH "." // Hidden file start char
|
||||
#define XDG_DATA_DEFAULT ".local" DIRSEP "share"
|
||||
|
||||
#define GAME_FILENAME_PROTO "game%d"
|
||||
#define GAME_FILENAME_BUFSIZE 16
|
||||
|
||||
@ -306,10 +310,15 @@ void init_program_name (const char *argv0)
|
||||
/* This implementation assumes a POSIX environment with an ASCII-safe
|
||||
character encoding (such as ASCII or UTF-8). */
|
||||
|
||||
const char *dirsep = DIRSEP;
|
||||
|
||||
|
||||
assert(strlen(dirsep) == 1);
|
||||
|
||||
if (argv0 == NULL || *argv0 == '\0') {
|
||||
program_name = PACKAGE;
|
||||
} else {
|
||||
char *p = strrchr(argv0, '/');
|
||||
char *p = strrchr(argv0, dirsep[0]);
|
||||
|
||||
if (p != NULL && *++p != '\0') {
|
||||
program_name = xstrdup(p);
|
||||
@ -343,21 +352,74 @@ const char *home_directory (void)
|
||||
|
||||
const char *data_directory (void)
|
||||
{
|
||||
/* This implementation assumes a POSIX environment by using "/" as
|
||||
/* This implementation assumes a POSIX environment by using DIRSEP as
|
||||
the directory separator. It also assumes a dot-starting directory
|
||||
name is permissible (again, true on POSIX systems) and that the
|
||||
character encoding is ASCII-safe. */
|
||||
|
||||
const char *dirsep = DIRSEP;
|
||||
const char *dirsep_hiddenpath = DIRSEP HIDDEN_PATH;
|
||||
const char *datahome_part = DIRSEP XDG_DATA_DEFAULT DIRSEP;
|
||||
|
||||
struct stat statbuf;
|
||||
|
||||
|
||||
assert(strlen(dirsep) == 1);
|
||||
|
||||
if (data_directory_str == NULL) {
|
||||
const char *home = home_directory();
|
||||
const char *xdg_data_home = getenv("XDG_DATA_HOME");
|
||||
|
||||
if (program_name != NULL && home != NULL) {
|
||||
char *p = xmalloc(strlen(home) + strlen(program_name) + 3);
|
||||
if (program_name != NULL) {
|
||||
int len_program_name = strlen(program_name);
|
||||
|
||||
strcpy(p, home);
|
||||
strcat(p, "/.");
|
||||
strcat(p, program_name);
|
||||
data_directory_str = p;
|
||||
if (home != NULL) {
|
||||
char *p = xmalloc(strlen(home) + strlen(dirsep_hiddenpath)
|
||||
+ len_program_name + 1);
|
||||
|
||||
strcpy(p, home);
|
||||
strcat(p, dirsep_hiddenpath);
|
||||
strcat(p, program_name);
|
||||
|
||||
if (stat(p, &statbuf) == 0 && S_ISDIR(statbuf.st_mode)) {
|
||||
// Directory "$HOME/.trader" exists: use that
|
||||
data_directory_str = p;
|
||||
} else {
|
||||
free(p);
|
||||
}
|
||||
}
|
||||
|
||||
if (data_directory_str == NULL && xdg_data_home != NULL
|
||||
&& *xdg_data_home != '\0' && *xdg_data_home == dirsep[0]) {
|
||||
// Use directory "$XDG_DATA_HOME/trader"
|
||||
|
||||
/* Note that the XDG Base Directory Specification v0.7
|
||||
requires XDG_DATA_HOME to contain an absolute path:
|
||||
the variable must be ignored if it does not start with
|
||||
the directory separator DIRSEP ("/") */
|
||||
|
||||
char *p = xmalloc(strlen(xdg_data_home) + strlen(DIRSEP)
|
||||
+ len_program_name + 1);
|
||||
|
||||
strcpy(p, xdg_data_home);
|
||||
strcat(p, dirsep);
|
||||
strcat(p, program_name);
|
||||
|
||||
data_directory_str = p;
|
||||
}
|
||||
|
||||
if (data_directory_str == NULL && home != NULL) {
|
||||
// Use directory "$HOME/.local/share/trader"
|
||||
|
||||
char *p = xmalloc(strlen(home) + strlen(datahome_part)
|
||||
+ len_program_name + 1);
|
||||
|
||||
strcpy(p, home);
|
||||
strcat(p, datahome_part);
|
||||
strcat(p, program_name);
|
||||
|
||||
data_directory_str = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -373,6 +435,8 @@ char *game_filename (int gamenum)
|
||||
/* This implementation assumes a POSIX environment and an ASCII-safe
|
||||
character encoding. */
|
||||
|
||||
const char *dirsep = DIRSEP;
|
||||
|
||||
char buf[GAME_FILENAME_BUFSIZE]; // Buffer for part of filename
|
||||
const char *dd; // Data directory
|
||||
|
||||
@ -387,10 +451,10 @@ char *game_filename (int gamenum)
|
||||
if (dd == NULL) {
|
||||
return xstrdup(buf);
|
||||
} else {
|
||||
char *p = xmalloc(strlen(dd) + strlen(buf) + 2);
|
||||
char *p = xmalloc(strlen(dd) + strlen(dirsep) + strlen(buf) + 1);
|
||||
|
||||
strcpy(p, dd);
|
||||
strcat(p, "/");
|
||||
strcat(p, dirsep);
|
||||
strcat(p, buf);
|
||||
return p;
|
||||
}
|
||||
|
18
src/utils.h
18
src/utils.h
@ -99,12 +99,18 @@ extern const char *home_directory (void);
|
||||
Parameters: (none)
|
||||
Returns: const char * - Pointer to data directory
|
||||
|
||||
This function returns the full pathname to a potentially-writable
|
||||
subdirectory within the user's home directory. Essentially, this
|
||||
function returns home_directory() + "/." + program_name. Note that
|
||||
this path is NOT created by this function, nor is the ability to write
|
||||
to this path checked. NULL is returned if this path cannot be
|
||||
determined.
|
||||
This function returns the full pathname to a potentially-writable data
|
||||
directory, usually within the user's home directory.
|
||||
|
||||
Assuming program_name is set to "trader", if "$HOME/.trader" exists,
|
||||
that directory is returned as the data directory. Otherwise, if the
|
||||
environment variable XDG_DATA_HOME is set and contains an absolute
|
||||
pathname, "$XDG_DATA_HOME/trader" is returned. Otherwise,
|
||||
"$HOME/.local/share/trader" is returned.
|
||||
|
||||
Note that the returned path is NOT created by this function, nor is the
|
||||
ability to read from or write to this path checked. NULL is returned
|
||||
if the path cannot be determined.
|
||||
*/
|
||||
extern const char *data_directory (void);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user