summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars-Dominik Braun <lars@6xq.net>2014-05-30 14:57:19 +0200
committerLars-Dominik Braun <lars@6xq.net>2014-05-30 14:57:19 +0200
commit947b381fb63711fab30f7212638ef792f5aa2a3f (patch)
tree080d9c3e7128b7c3563972977b6ae25ed7569f84
parent81c9327143c1b0484eaceaf69e7f79da0099ba91 (diff)
downloadpianobar-windows-947b381fb63711fab30f7212638ef792f5aa2a3f.tar.gz
pianobar-windows-947b381fb63711fab30f7212638ef792f5aa2a3f.tar.bz2
pianobar-windows-947b381fb63711fab30f7212638ef792f5aa2a3f.zip
settings: Support ~/ expansion
Only the simple ~/ expansion is supported right now, since ~user expansion does not make sense for per-user config files anyway. Closes #431 and #430. On my way to this solution I tried libconfuse and json-based config files. I’m not convinced yet one of these is the solution though…
-rw-r--r--contrib/pianobar.15
-rw-r--r--src/settings.c100
-rw-r--r--src/settings.h1
3 files changed, 73 insertions, 33 deletions
diff --git a/contrib/pianobar.1 b/contrib/pianobar.1
index 490ee23..8a311a5 100644
--- a/contrib/pianobar.1
+++ b/contrib/pianobar.1
@@ -215,9 +215,8 @@ File that is executed when event occurs. See section
.B EVENTCMD
.TP
-.B fifo = /home/user/.config/pianobar/ctl
-Location of control fifo. Defaults to $XDG_CONFIG_HOME/pianobar/ctl (which is
-usually the value above). See section
+.B fifo = $XDG_CONFIG_HOME/pianobar/ctl
+Location of control fifo. See section
.B REMOTE CONTROL
.TP
diff --git a/src/settings.c b/src/settings.c
index d90a7d7..f03f368 100644
--- a/src/settings.c
+++ b/src/settings.c
@@ -34,6 +34,8 @@ THE SOFTWARE.
#include <stdio.h>
#include <limits.h>
#include <assert.h>
+#include <sys/types.h>
+#include <pwd.h>
#include <piano.h>
@@ -43,32 +45,58 @@ THE SOFTWARE.
#define streq(a, b) (strcmp (a, b) == 0)
-/* tries to guess your config dir; somehow conforming to
- * http://standards.freedesktop.org/basedir-spec/basedir-spec-0.6.html
- * @param name of the config file (can contain subdirs too)
- * @param store the whole path here
- * @param but only up to this size
- * @return nothing
+/* Get current user’s home directory
*/
-void BarGetXdgConfigDir (const char *filename, char *retDir,
- size_t retDirN) {
- char *xdgConfigDir = NULL;
+static char *BarSettingsGetHome () {
+ char *home;
+
+ /* try environment variable */
+ if ((home = getenv ("HOME")) != NULL && strlen (home) > 0) {
+ return strdup (home);
+ }
+
+ /* try passwd mechanism */
+ struct passwd * const pw = getpwuid (getuid ());
+ if (pw != NULL && pw->pw_dir != NULL && strlen (pw->pw_dir) > 0) {
+ return strdup (pw->pw_dir);
+ }
+
+ return NULL;
+}
+
+/* Get XDG config directory, which is set by BarSettingsRead (if not set)
+ */
+static char *BarGetXdgConfigDir (const char * const filename) {
+ assert (filename != NULL);
+
+ char *xdgConfigDir;
if ((xdgConfigDir = getenv ("XDG_CONFIG_HOME")) != NULL &&
strlen (xdgConfigDir) > 0) {
- /* special dir: $xdg_config_home */
- snprintf (retDir, retDirN, "%s/%s", xdgConfigDir, filename);
- } else {
- if ((xdgConfigDir = getenv ("HOME")) != NULL &&
- strlen (xdgConfigDir) > 0) {
- /* standard config dir: $home/.config */
- snprintf (retDir, retDirN, "%s/.config/%s", xdgConfigDir,
- filename);
- } else {
- /* fallback: working dir */
- snprintf (retDir, retDirN, "%s", filename);
- }
+ const size_t len = (strlen (xdgConfigDir) + 1 +
+ strlen (filename) + 1);
+ char * const concat = malloc (len * sizeof (*concat));
+ snprintf (concat, len, "%s/%s", xdgConfigDir, filename);
+ return concat;
+ }
+
+ return NULL;
+}
+
+/* Expand ~/ to user’s home directory
+ */
+char *BarSettingsExpandTilde (const char * const path, const char * const home) {
+ assert (path != NULL);
+ assert (home != NULL);
+
+ if (strncmp (path, "~/", 2) == 0) {
+ char * const expanded = malloc ((strlen (home) + 1 + strlen (path)-2 + 1) *
+ sizeof (*expanded));
+ sprintf (expanded, "%s/%s", home, &path[2]);
+ return expanded;
}
+
+ return strdup (path);
}
/* initialize settings structure
@@ -115,7 +143,14 @@ void BarSettingsDestroy (BarSettings_t *settings) {
* @return nothing yet
*/
void BarSettingsRead (BarSettings_t *settings) {
- char *configfiles[] = {PACKAGE "/state", PACKAGE "/config"};
+ char * const configfiles[] = {PACKAGE "/state", PACKAGE "/config"};
+ char * const userhome = BarSettingsGetHome ();
+ assert (userhome != NULL);
+ /* set xdg config path (if not set) */
+ char * const defaultxdg = malloc (strlen (userhome) + strlen ("/.config") + 1);
+ sprintf (defaultxdg, "%s/.config", userhome);
+ setenv ("XDG_CONFIG_HOME", defaultxdg, 0);
+ free (defaultxdg);
assert (sizeof (settings->keys) / sizeof (*settings->keys) ==
sizeof (dispatchActions) / sizeof (*dispatchActions));
@@ -140,8 +175,8 @@ void BarSettingsRead (BarSettings_t *settings) {
settings->device = strdup ("android-generic");
settings->inkey = strdup ("R=U!LH$O2B#");
settings->outkey = strdup ("6#26FRL$ZWD");
- settings->fifo = malloc (PATH_MAX * sizeof (*settings->fifo));
- BarGetXdgConfigDir (PACKAGE "/ctl", settings->fifo, PATH_MAX);
+ settings->fifo = BarGetXdgConfigDir (PACKAGE "/ctl");
+ assert (settings->fifo != NULL);
memcpy (settings->tlsFingerprint, "\x2D\x0A\xFD\xAF\xA1\x6F\x4B\x5C\x0A"
"\x43\xF3\xCB\x1D\x47\x52\xF9\x53\x55\x07\xC0",
sizeof (settings->tlsFingerprint));
@@ -168,11 +203,13 @@ void BarSettingsRead (BarSettings_t *settings) {
/* read config files */
for (size_t j = 0; j < sizeof (configfiles) / sizeof (*configfiles); j++) {
static const char *formatMsgPrefix = "format_msg_";
- char key[256], val[256], path[PATH_MAX];
+ char key[256], val[256];
FILE *configfd;
- BarGetXdgConfigDir (configfiles[j], path, sizeof (path));
+ char * const path = BarGetXdgConfigDir (configfiles[j]);
+ assert (path != NULL);
if ((configfd = fopen (path, "r")) == NULL) {
+ free (path);
continue;
}
@@ -283,7 +320,7 @@ void BarSettingsRead (BarSettings_t *settings) {
settings->listSongFormat = strdup (val);
} else if (streq ("fifo", key)) {
free (settings->fifo);
- settings->fifo = strdup (val);
+ settings->fifo = BarSettingsExpandTilde (val, userhome);
} else if (streq ("autoselect", key)) {
settings->autoselect = atoi (val);
} else if (streq ("tls_fingerprint", key)) {
@@ -330,6 +367,7 @@ void BarSettingsRead (BarSettings_t *settings) {
}
fclose (configfd);
+ free (path);
}
/* check environment variable if proxy is not set explicitly */
@@ -339,18 +377,21 @@ void BarSettingsRead (BarSettings_t *settings) {
settings->proxy = strdup (tmpProxy);
}
}
+
+ free (userhome);
}
/* write statefile
*/
void BarSettingsWrite (PianoStation_t *station, BarSettings_t *settings) {
- char path[PATH_MAX];
FILE *fd;
assert (settings != NULL);
- BarGetXdgConfigDir (PACKAGE "/state", path, sizeof (path));
+ char * const path = BarGetXdgConfigDir (PACKAGE "/state");
+ assert (path != NULL);
if ((fd = fopen (path, "w")) == NULL) {
+ free (path);
return;
}
@@ -361,5 +402,6 @@ void BarSettingsWrite (PianoStation_t *station, BarSettings_t *settings) {
}
fclose (fd);
+ free (path);
}
diff --git a/src/settings.h b/src/settings.h
index 5212d10..b56351e 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -114,6 +114,5 @@ void BarSettingsInit (BarSettings_t *);
void BarSettingsDestroy (BarSettings_t *);
void BarSettingsRead (BarSettings_t *);
void BarSettingsWrite (PianoStation_t *, BarSettings_t *);
-void BarGetXdgConfigDir (const char *, char *, size_t);
#endif /* SRC_SETTINGS_H_IPL0ON9L */