Skip to content

Commit

Permalink
Initial support for $HOME and some XDG variables inside the configura…
Browse files Browse the repository at this point in the history
…tion file

This commit tries to address issues #263 and #476. It enables the path expansion of HOME, XDG_CONFIG_HOME, XDG_MUSIC_DIR, XDG_CACHE_HOME and XDG_RUNTIME_DIR by using the glue functions already available in MPD.

Signed-off-by: Joan Vilardaga <[email protected]>
  • Loading branch information
JoanVC100 committed Mar 10, 2025
1 parent da40483 commit e8ce417
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 4 deletions.
11 changes: 10 additions & 1 deletion doc/mpd.conf.5.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,19 @@ Each line in the configuration file contains a setting name and its value, e.g.:

Lines starting with ``#`` are treated as comments and ignored.

For settings which specify a filesystem path, the tilde is expanded:
For settings that specify a file system path, the tilde ('~') is expanded to $HOME.
In addition, the following path expansions are supported:

- `$HOME`
- `$XDG_CONFIG_HOME`
- `$XDG_MUSIC_DIR`
- `$XDG_CACHE_HOME`
- `$XDG_RUNTIME_DIR`

:code:`music_directory "~/Music"`

:code:`db_file "$XDG_CONFIG_HOME/mpd/database"`

Some of the settings are grouped in blocks with curly braces, e.g. per-plugin settings:

.. code-block:: none
Expand Down
8 changes: 8 additions & 0 deletions doc/mpdconf.example
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@
# be disabled and audio files will only be accepted over ipc socket (using
# file:// protocol) or streaming files over an accepted protocol.
#
#music_directory "$XDG_MUSIC_DIR"
#music_directory "~/music"
#
# This setting sets the MPD internal playlist directory. The purpose of this
# directory is storage for playlists created by MPD. The server will use
# playlist files not created by the server but only if they are in the MPD
# format. This setting defaults to playlist saving being disabled.
#
#playlist_directory "$XDG_CONFIG_HOME/mpd/playlists"
#playlist_directory "~/.mpd/playlists"
#
# This setting sets the location of the MPD database. This file is used to
Expand All @@ -25,6 +27,7 @@
# MPD to accept files over ipc socket (using file:// protocol) or streaming
# files over an accepted protocol.
#
#db_file "$XDG_CACHE_HOME/mpd/database"
#db_file "~/.mpd/database"

# These settings are the locations for the daemon log files for the daemon.
Expand All @@ -35,6 +38,7 @@
# If you use systemd, do not configure a log_file. With systemd, MPD
# defaults to the systemd journal, which is fine.
#
#log_file "$XDG_CACHE_HOME/mpd/log"
#log_file "~/.mpd/log"

# This setting sets the location of the file which stores the process ID
Expand All @@ -43,18 +47,21 @@
#
# If you use systemd, do not configure a pid_file.
#
#pid_file "$XDG_RUNTIME_DIR/mpd/mpd.pid"
#pid_file "~/.mpd/pid"

# This setting sets the location of the file which contains information about
# most variables to get MPD back into the same general shape it was in before
# it was brought down. This setting is disabled by default and the server
# state will be reset on server start up.
#
#state_file "$XDG_RUNTIME_DIR/mpd/state"
#state_file "~/.mpd/state"
#
# The location of the sticker database. This is a database which
# manages dynamic information attached to songs.
#
#sticker_file "$XDG_CACHE_HOME/sticker.sql"
#sticker_file "~/.mpd/sticker.sql"
#
###############################################################################
Expand Down Expand Up @@ -85,6 +92,7 @@
#bind_to_address "any"
#
# And for Unix Socket
#bind_to_address "$XDG_RUNTIME_DIR/mpd/socket"
#bind_to_address "~/.mpd/socket"
#
# This setting is the TCP port that is desired for the daemon to get assigned
Expand Down
17 changes: 14 additions & 3 deletions doc/user.rst
Original file line number Diff line number Diff line change
Expand Up @@ -250,10 +250,18 @@ Each line in the configuration file contains a setting name and its value, e.g.:

Lines starting with ``#`` are treated as comments and ignored.

For settings which specify a filesystem path, the tilde is expanded:
For settings that specify a file system path, the tilde ('~') is expanded to $HOME. In addition, the following path expansions are supported:

- `$HOME`
- `$XDG_CONFIG_HOME`
- `$XDG_MUSIC_DIR`
- `$XDG_CACHE_HOME`
- `$XDG_RUNTIME_DIR`

:code:`music_directory "~/Music"`

:code:`db_file "$XDG_CONFIG_HOME/mpd/database"`

Some of the settings are grouped in blocks with curly braces, e.g. per-plugin settings:

.. code-block:: none
Expand Down Expand Up @@ -1210,8 +1218,11 @@ Mounting is only possible with the simple database plugin and a :code:`cache_dir
database {
plugin "simple"
path "~/.mpd/db"
cache_directory "~/.mpd/cache"
path "$XDG_CACHE_HOME/mpd/database"
cache_directory "$XDG_CACHE_HOME/mpd/"
# or you can also use relative or absolute paths
# path "~/.mpd/db"
# cache_directory "~/.mpd/cache"
}
This requires migrating from the old :code:`db_file` setting to a database section. The cache directory must exist, and :program:`MPD` will put one file per mount there, which will be reused when the same storage is used again later.
Expand Down
5 changes: 5 additions & 0 deletions src/config/Net.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@
#include "event/ServerSocket.hxx"
#include "Path.hxx"
#include "fs/AllocatedPath.hxx"
#include "fs/XDG.hxx"

void
ServerSocketAddGeneric(ServerSocket &server_socket, const char *address, unsigned int port)
{
if (address == nullptr || 0 == strcmp(address, "any")) {
server_socket.AddPort(port);
#ifdef USE_XDG
} else if (address[0] == '/' || address[0] == '~' || address[0] == '$') {
#else
} else if (address[0] == '/' || address[0] == '~') {
#endif
server_socket.AddPath(ParsePath(address));
} else if (address[0] == '@') {
server_socket.AddAbstract(address);
Expand Down
24 changes: 24 additions & 0 deletions src/config/Path.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "Data.hxx"
#include "fs/AllocatedPath.hxx"
#include "fs/Traits.hxx"
#include "fs/XDG.hxx"
#include "fs/glue/StandardDirectory.hxx"
#include "lib/fmt/RuntimeError.hxx"
#include "util/StringSplit.hxx"
Expand Down Expand Up @@ -90,6 +91,29 @@ ParsePath(const char *path)
return GetHome(std::string{user}.c_str())
/ AllocatedPath::FromUTF8Throw(rest);
}
#ifdef USE_XDG
} else if (path[0] == '$') {
++path;

const auto [env_var, rest] = Split(std::string_view{path}, '/');

AllocatedPath xdg_path(nullptr);
if (env_var == "HOME") {
xdg_path = GetConfiguredHome();
} else if (env_var == "XDG_CONFIG_HOME") {
xdg_path = GetUserConfigDir();
} else if (env_var == "XDG_MUSIC_DIR") {
xdg_path = GetUserMusicDir();
} else if (env_var == "XDG_CACHE_HOME") {
xdg_path = GetUserCacheDir();
} else if (env_var == "XDG_RUNTIME_DIR") {
xdg_path = GetUserRuntimeDir();
} else {
throw FmtRuntimeError("environment variable not supported: {:?}", env_var);
}

return xdg_path / AllocatedPath::FromUTF8Throw(rest);
#endif
} else if (!PathTraitsUTF8::IsAbsolute(path)) {
throw FmtRuntimeError("not an absolute path: {:?}", path);
} else {
Expand Down

0 comments on commit e8ce417

Please sign in to comment.