From 884408028cb6afd9c68c32d19eafdd362e7cc9c8 Mon Sep 17 00:00:00 2001
From: Maarten de Vries <maarten@de-vri.es>
Date: Sun, 25 Aug 2013 15:51:41 +0200
Subject: [PATCH] Listen: Allow tilde paths for socket.

---
 doc/mpd.conf.5       | 5 +++--
 src/ConfigGlobal.cxx | 6 ++++++
 src/ConfigGlobal.hxx | 8 ++++++++
 src/Listen.cxx       | 6 ++++--
 4 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/doc/mpd.conf.5 b/doc/mpd.conf.5
index d441c0d..b3a46e1 100644
--- a/doc/mpd.conf.5
+++ b/doc/mpd.conf.5
@@ -77,8 +77,9 @@ You can set a port that is different from the global port setting,
 e.g. "localhost:6602".  IPv6 addresses must be enclosed in square
 brackets if you want to configure a port, e.g. "[::1]:6602".
 
-To bind to a Unix domain socket, specify an absolute path.  For a
-system-wide MPD, we suggest the path "\fB/var/run/mpd/socket\fP".
+To bind to a Unix domain socket, specify an absolute path or a path starting
+with a tilde (~).  For a system-wide MPD, we suggest the path
+"\fB/var/run/mpd/socket\fP".
 .TP
 .B port <port>
 This specifies the port that mpd listens on.  The default is 6600.
diff --git a/src/ConfigGlobal.cxx b/src/ConfigGlobal.cxx
index 0bf2b44..d2e26fa 100644
--- a/src/ConfigGlobal.cxx
+++ b/src/ConfigGlobal.cxx
@@ -105,6 +105,12 @@ config_get_path(ConfigOption option, Error &error)
 	if (param == NULL)
 		return Path::Null();
 
+	return config_parse_path(param, error);
+}
+
+Path
+config_parse_path(const struct config_param *param, Error & error)
+{
 	Path path = ParsePath(param->value, error);
 	if (gcc_unlikely(path.IsNull()))
 		error.FormatPrefix("Invalid path at line %i: ",
diff --git a/src/ConfigGlobal.hxx b/src/ConfigGlobal.hxx
index efa5e06..dbfe489 100644
--- a/src/ConfigGlobal.hxx
+++ b/src/ConfigGlobal.hxx
@@ -78,6 +78,14 @@ config_get_string(enum ConfigOption option, const char *default_value);
 Path
 config_get_path(enum ConfigOption option, Error &error);
 
+/**
+ * Parse a configuration parameter as a path.
+ * If there is a tilde prefix, it is expanded. If the path could
+ * not be parsed, returns Path::Null() and sets the error.
+ */
+Path
+config_parse_path(const struct config_param *param, Error & error_r);
+
 gcc_pure
 unsigned
 config_get_unsigned(enum ConfigOption option, unsigned default_value);
diff --git a/src/Listen.cxx b/src/Listen.cxx
index 6f6ff3f..b3c5684 100644
--- a/src/Listen.cxx
+++ b/src/Listen.cxx
@@ -25,6 +25,7 @@
 #include "conf.h"
 #include "event/ServerSocket.hxx"
 #include "util/Error.hxx"
+#include "fs/Path.hxx"
 
 #include <string.h>
 #include <assert.h>
@@ -62,8 +63,9 @@ listen_add_config_param(unsigned int port,
 
 	if (0 == strcmp(param->value, "any")) {
 		return listen_socket->AddPort(port, error_r);
-	} else if (param->value[0] == '/') {
-		return listen_socket->AddPath(param->value, error_r);
+	} else if (param->value[0] == '/' || param->value[0] == '~') {
+		Path path = config_parse_path(param, error_r);
+		return !path.IsNull() && listen_socket->AddPath(path.c_str(), error_r);
 	} else {
 		return listen_socket->AddHost(param->value, port, error_r);
 	}
-- 
1.8.4

