MPD icon indicating copy to clipboard operation
MPD copied to clipboard

Environment Variables in config file

Open ForTheReallys opened this issue 7 years ago • 4 comments
trafficstars

Would you consider adding the expansion of environment variables in mpv.conf? I would like mpd to listen on $XDG_RUNTIME_DIR/mpd-socket but cannot do this without expanding the variable by hand.
Thank you!

ForTheReallys avatar Apr 09 '18 20:04 ForTheReallys

MPD listens on $XDG_RUNTIME_DIR/mpd/socket if no bind_to_address is set. So maybe expansion of $XDG_RUNTIME_DIR is no longer needed?

Source: https://www.musicpd.org/doc/html/user.html#listeners

Works with MPD 0.21.5 on Debian buster. Commented out all bind_to_address lines in my ~/.mpdconf, killed and restarted mpd. Now I can connect to it using the socket:

$ MPD_HOST="$XDG_RUNTIME_DIR/mpd/socket" mpc
volume: n/a   repeat: off   random: off   single: off   consume: off

However, even when bind_to_address is unset, mpd still listens on "[::]:6600" (world reachable) in addition to the XDG socket. If you do set bind_to_address to e.g. localhost, the XDG socket is gone. Tilde is expanded, so you can set bind_to_address to e.g. ~/.mpd/socket but that kinda defeats the point of this issue. You can still control which port mpd listens on, using the port setting, so at least you can avoid port conflicts.

ttytyper avatar Mar 13 '19 16:03 ttytyper

Another use case is music_directory with $XDG_MUSIC_DIR.

If we want to reach maximum versatility of the config file probably Parameter Expansion with subshell support would be ideal; I have zero knowledge of this codebase but I suspect that this would be not so straightforward to implement.

In my case:

music_directory  "${XDG_MUSIC_DIR:-~/Music}"

...

bind_to_address  "${XDG_RUNTIME_DIR:-/tmp/$(id -u)-runtime}/mpd/main.sock"

meliurwen avatar Mar 27 '22 09:03 meliurwen

I'm for this as well. I'd like to be able to set the playlist directory or the log file directory using $XDG_CONFIG_HOME or $XDG_CACHE_HOME or $XDG_DATA_HOME, etc.. you get the idea.

ifohancroft avatar May 22 '22 19:05 ifohancroft

quick and dirty patch

--- mpd-0.23.12/src/config/Path.cxx.orig    2023-01-17 19:54:47.000000000 +0200
+++ mpd-0.23.12/src/config/Path.cxx 2023-05-09 10:54:13.543284206 +0300
@@ -26,6 +26,8 @@
 #include "util/StringView.hxx"
 
 #include <cassert>
+#include <string>
+#include <regex>
 
 #ifndef _WIN32
 #include <pwd.h>
@@ -33,6 +35,21 @@
 static const char *configured_user = nullptr;
 
 /**
+ * Replace environment variables in form ${...} by its values
+ */
+static void
+ExpandEnvironmentVariables(std::string & text) {
+    static std::regex env( "\\$\\{([^}]+)\\}" );
+    std::smatch match;
+    while ( std::regex_search( text, match, env ) ) {
+        const char * s = getenv( match[1].str().c_str() );
+        const std::string var( s == NULL ? "" : s );
+        text.replace( match[0].first, match[0].second, var );
+    }
+}
+
+
+/**
  * Determine a given user's home directory.
  */
 static AllocatedPath
@@ -89,17 +106,21 @@
    assert(path != nullptr);
 
 #ifndef _WIN32
-   if (path[0] == '~') {
-       ++path;
+    std::string epath(path);
+    ExpandEnvironmentVariables(epath);
 
-       if (*path == '\0')
+   const char *str = epath.c_str();
+   if (str[0] == '~') {
+       ++str;
+
+       if (*str == '\0')
            return GetConfiguredHome();
 
-       if (*path == '/') {
-           ++path;
+       if (*str == '/') {
+           ++str;
 
-               AllocatedPath::FromUTF8Throw(path);
+               AllocatedPath::FromUTF8Throw(str);
        } else {
            const auto [user, rest] =
                StringView{path}.Split('/');
@@ -107,12 +128,12 @@
            return GetHome(std::string{user}.c_str())
                / AllocatedPath::FromUTF8Throw(rest);
        }
-   } else if (!PathTraitsUTF8::IsAbsolute(path)) {
-       throw FormatRuntimeError("not an absolute path: %s", path);
+   } else if (!PathTraitsUTF8::IsAbsolute(str)) {
+       throw FormatRuntimeError("not an absolute path: %s", str);
    } else {
-#endif
-       return AllocatedPath::FromUTF8Throw(path);
-#ifndef _WIN32
+       return AllocatedPath::FromUTF8Throw(str);
    }
+#else
+   return AllocatedPath::FromUTF8Throw(path);
 #endif
 }

v1cont avatar May 09 '23 08:05 v1cont