From 8ab2aa9fd51a89e06d92a4f7c3792aaa4a08cc71 Mon Sep 17 00:00:00 2001 Message-Id: <8ab2aa9fd51a89e06d92a4f7c3792aaa4a08cc71.1714761992.git.mdw@distorted.org.uk> From: Mark Wooding Date: Thu, 4 Jun 2020 20:22:02 +0100 Subject: [PATCH] lib/configuration.c, lib/home.c: Introduce environment variables. Organization: Straylight/Edgeware From: Mark Wooding The places where DisOrder looks for configuration can now be overridden using environment variables. * `$DISORDER_CONFIG' is the master configuration file -- defaults to `PKGCONFDIR/config', where `PKGCONFDIR' is set at compile time (e.g., `/etc/disorder'. * `$DISORDER_PRIVCONFIG' is the private configuration file -- defaults to `$DISORDER_CONFIG.private'. * `$DISORDER_HOME' is the user's `profile directory' for DisOrder things -- defaults to `$HOME/.disorder' on Unix, or `%APPDATA%/DisOrder' (i.e., in the roaming profile directory) on Windows. * `$DISORDER_USERCONFIG' is the user's configuration file -- defaults to `$DISORDER_HOME/passwd'. * `$DISORDER_USERCONFIG_SYS' is the per-user system configuration file -- defaults to `$DISORDER_CONFIG.USERNAME'. The primary motivation for all of this is to make it easier to run clients -- particularly Disobedience and its `disorder-playrtp' inferiors -- against multiple servers simultaneously. Setting configuration on the command line works rather badly for clients, since that overrides the /system/ configuration, which the user can't edit anyway -- the client programs still read `$HOME/passwd' unconditionally. This is clearly a bug, but changing the behaviour now is a bad idea; besides, changing `-c' (or introducing a new option) to override the `passwd' file, doesn't actually help much unless Disobedience in turn passes the necessary option on to `disorder-playrtp'. Environment variables solve all of these problems much more simply. --- doc/disobedience.1.in | 3 +++ doc/disorder-dump.8.in | 2 ++ doc/disorder-playrtp.1.in | 3 +++ doc/disorder.1.in | 27 +++++++++++++++++++++++++++ doc/disorder_config.5.in | 21 +++++++++++++++++++++ doc/disorderd.8.in | 11 +++++++++++ lib/configuration.c | 13 ++++++++++--- lib/home.c | 36 ++++++++++++++++++++---------------- 8 files changed, 97 insertions(+), 19 deletions(-) diff --git a/doc/disobedience.1.in b/doc/disobedience.1.in index 4462237..ea983f3 100644 --- a/doc/disobedience.1.in +++ b/doc/disobedience.1.in @@ -31,6 +31,9 @@ be found at dochtmldir/index.html. .B \-\-config \fIPATH\fR, \fB\-c \fIPATH Set the configuration file. The default is +given by the +.B DISORDER_CONFIG +environment variable, defaulting to .IR pkgconfdir/config . .TP .B \-\-debug\fR, \fB\-d diff --git a/doc/disorder-dump.8.in b/doc/disorder-dump.8.in index d29562f..aaf90ef 100644 --- a/doc/disorder-dump.8.in +++ b/doc/disorder-dump.8.in @@ -58,6 +58,8 @@ In normal use such tracks are all aliases. .B \-\-config \fIPATH\fR, \fB\-c \fIPATH Set the configuration file. The default is +.B DISORDER_CONFIG +environment variable, defaulting to .IR /etc/disorder/config . .TP .B \-\-no\-setuid diff --git a/doc/disorder-playrtp.1.in b/doc/disorder-playrtp.1.in index d453dcb..24ad03f 100644 --- a/doc/disorder-playrtp.1.in +++ b/doc/disorder-playrtp.1.in @@ -107,6 +107,9 @@ control. .B \-\-config \fIPATH\fR, \fB\-C \fIPATH Set the configuration file. The default is +given by the +.B DISORDER_CONFIG +environment variable, defaulting to .IR pkgconfdir/config . .TP .B \-\-socket \fIPATH\fR, \fB\-s \fIPATH diff --git a/doc/disorder.1.in b/doc/disorder.1.in index b61a825..5899ab5 100644 --- a/doc/disorder.1.in +++ b/doc/disorder.1.in @@ -42,6 +42,9 @@ and \fBdisorder_config\fR (5) for documentation of the configuration file. .B \-\-config \fIPATH\fR, \fB\-c \fIPATH Set the configuration file. The default is +given by the +.B DISORDER_CONFIG +environment variable, defaulting to .IR pkgconfdir/config . .TP .B \-\-debug\fR, \fB\-d @@ -380,6 +383,30 @@ The README recommends using \fBjukebox\fR for this purpose but it could be different locally. .SH ENVIRONMENT .TP +.B DISORDER_CONFIG +Main configuration file to use instead of +.IR pkgconfdir/config . +Overridden by the +.B \-c +.RB ( \-\-config ) +command-line option. +.TP +.B DISORDER_HOME +Per-user configuration and state directory to use instead of +.BR $HOME/.disorder . +.TP +.B DISORDER_PRIVCONFIG +Private configuration file to use instead of +.IR pkgconfdir/config.private . +.TP +.B DISORDER_USERCONFIG +Per-user configuration file to use instead of +.BR $DISORDER_HOME/passwd . +.TP +.B DISORDER_USERCONFIG_SYS +System-provided per-user configuration file to use instead of +.BR $DISORDER_HOME/passwd . +.TP .B HOME The user's home directory. .TP diff --git a/doc/disorder_config.5.in b/doc/disorder_config.5.in index c4f3bd4..4190d16 100644 --- a/doc/disorder_config.5.in +++ b/doc/disorder_config.5.in @@ -199,17 +199,38 @@ as it cannot start up without a valid config file.) Configuration files are read in the following order: .TP .I pkgconfdir/config +Or +.BR $DISORDER_CONFIG , +if that's set; overridden by +.B \-c +.RB ( \-\-config ) +command line option, except in +.BR disrder-playrtp (1), +which uses +.BR \-C . .TP .I pkgconfdir/config.private +Or +.BR $DISORDER_PRIVCONFIG , +if that's set, else +.BR $DISORDER_CONFIG.private . Should be readable only by the jukebox group. Not really useful any more and will be abolished in future. .TP .I ~\fRUSERNAME\fI/.disorder/passwd +Or +.BR $DISORDER_USERCONFIG , +if that's set; else +.BR $DISORDER_HOME/passwd . Per-user client configuration. Optional but if it exists must be readable only by the relevant user. Would normally contain a \fBpassword\fR directive. .TP .I pkgconfdir/config.\fRUSERNAME +(Or +.BR $DISORDER_USERCONFIG_SYS , +if that's set; else +.BR $DISORDER_CONFIG.\fIUSERNAME .) Per-user system-controlled client configuration. Optional but if it exists must be readable only by the relevant user. Would normally contain a \fBpassword\fR directive. diff --git a/doc/disorderd.8.in b/doc/disorderd.8.in index 6325dd0..4673252 100644 --- a/doc/disorderd.8.in +++ b/doc/disorderd.8.in @@ -29,6 +29,9 @@ concerning what is to be played. .B \-\-config \fIPATH\fR, \fB\-c \fIPATH Set the configuration file. The default is +given by the +.B DISORDER_CONFIG +environment variable, defaulting to .IR pkgconfdir/config . See .BR disorder_config (5) @@ -190,6 +193,14 @@ Lockfile. This prevents multiple instances of DisOrder running simultaneously. .SH ENVIRONMENT .TP +.B DISORDER_CONFIG +Configuration file to use instead of +.IR pkgconfdir/config . +.TP +.B DISORDER_PRIVCONFIG +Private configuration file to use instead of +.IR pkgconfdir/config.private . +.TP .B LC_ALL\fR, \fBLANG\fR, etc Current locale. See \fBlocale\fR(7). diff --git a/lib/configuration.c b/lib/configuration.c index 17f9ec7..56a9696 100644 --- a/lib/configuration.c +++ b/lib/configuration.c @@ -1452,8 +1452,11 @@ char *config_get_file2(struct config *c, const char *name) { /** @brief Set the default configuration file */ static void set_configfile(void) { #if !_WIN32 - if(!configfile) - byte_xasprintf(&configfile, "%s/config", pkgconfdir); + if(!configfile) { + configfile = getenv("DISORDER_CONFIG"); + if(!configfile) + byte_xasprintf(&configfile, "%s/config", pkgconfdir); + } #endif } @@ -1671,6 +1674,8 @@ char *config_private(void) { /** @brief Return the path to user's personal configuration file */ char *config_userconf(void) { + char *t; + if((t = getenv("DISORDER_USERCONFIG"))) return xstrdup(t); return profile_filename("passwd"); } @@ -1680,7 +1685,9 @@ char *config_usersysconf(const struct passwd *pw) { char *s; set_configfile(); - if(!strchr(pw->pw_name, '/')) { + if((s = getenv("DISORDER_USERCONFIG_SYS"))) + return xstrdup(s); + else if(!strchr(pw->pw_name, '/')) { byte_xasprintf(&s, "%s.%s", configfile, pw->pw_name); return s; } else diff --git a/lib/home.c b/lib/home.c index 5426f76..3b3166c 100644 --- a/lib/home.c +++ b/lib/home.c @@ -56,25 +56,29 @@ const char *profile_directory(void) { char *t; if(profiledir) return profiledir; + if((t = getenv("DISORDER_HOME"))) + profiledir = t; + else { #if _WIN32 - wchar_t *wpath = 0; - char *appdata; - if(SHGetKnownFolderPath(&FOLDERID_RoamingAppData, 0, NULL, &wpath) != S_OK) { - disorder_error(0, "error calling SHGetKnownFolderPath"); - return 0; - } - t = win_wtomb(wpath); - CoTaskMemFree(wpath); - byte_xasprintf(&profiledir, "%s\\DisOrder", appdata); + wchar_t *wpath = 0; + char *appdata; + if(SHGetKnownFolderPath(&FOLDERID_RoamingAppData, 0, NULL, &wpath) != S_OK) { + disorder_error(0, "error calling SHGetKnownFolderPath"); + return 0; + } + t = win_wtomb(wpath); + CoTaskMemFree(wpath); + byte_xasprintf(&profiledir, "%s\\DisOrder", appdata); #else - struct passwd *pw; - if(!(t = getenv("HOME"))) { - if(!(pw = getpwuid(getuid()))) - disorder_error(0, "user not found in password database"); - t = pw->pw_dir; - } - byte_xasprintf(&profiledir, "%s/.disorder", t); + struct passwd *pw; + if(!(t = getenv("HOME"))) { + if(!(pw = getpwuid(getuid()))) + disorder_error(0, "user not found in password database"); + t = pw->pw_dir; + } + byte_xasprintf(&profiledir, "%s/.disorder", t); #endif + } return profiledir; } -- [mdw]