diff options
-rw-r--r-- | doc/mpd.conf.5 | 11 | ||||
-rw-r--r-- | doc/mpdconf.example | 2 | ||||
-rw-r--r-- | src/conf.c | 2 | ||||
-rw-r--r-- | src/conf.h | 2 | ||||
-rw-r--r-- | src/update.c | 40 |
5 files changed, 50 insertions, 7 deletions
diff --git a/doc/mpd.conf.5 b/doc/mpd.conf.5 index 60fd8ebcc..4427b9798 100644 --- a/doc/mpd.conf.5 +++ b/doc/mpd.conf.5 @@ -35,6 +35,17 @@ This specifies the directory where music is located. .B playlist_directory <directory> This specifies the directory where saved playlists are stored. .TP +.B follow_outside_symlinks <yes or no> +Control if MPD will follow symbolic links pointing outside the music dir. +You must recreate the database after changing this option. +The default is "no". +.TP +.B follow_inside_symlinks <yes or no> +Control if MPD will follow symbolic links pointing outside the music dir, potentially +adding duplicates to the database. +You must recreate the database after changing this option. +The default is "yes". +.TP .B db_file <file> This specifies where the db file will be stored. .TP diff --git a/doc/mpdconf.example b/doc/mpdconf.example index bb42b3f17..151c9464f 100644 --- a/doc/mpdconf.example +++ b/doc/mpdconf.example @@ -7,6 +7,8 @@ playlist_directory "~/.mpd/playlists" db_file "~/.mpd/mpd.db" log_file "~/.mpd/mpd.log" error_file "~/.mpd/mpd.error" +#follow_outside_symlinks "no" +#follow_inside_symlinks "yes" ################################################################ diff --git a/src/conf.c b/src/conf.c index 885da1f29..cdcb917f6 100644 --- a/src/conf.c +++ b/src/conf.c @@ -145,6 +145,8 @@ void initConf(void) /* registerConfigParam(name, repeatable, block); */ registerConfigParam(CONF_MUSIC_DIR, 0, 0); registerConfigParam(CONF_PLAYLIST_DIR, 0, 0); + registerConfigParam(CONF_FOLLOW_INSIDE_SYMLINKS, 0, 0); + registerConfigParam(CONF_FOLLOW_OUTSIDE_SYMLINKS, 0, 0); registerConfigParam(CONF_DB_FILE, 0, 0); registerConfigParam(CONF_LOG_FILE, 0, 0); registerConfigParam(CONF_ERROR_FILE, 0, 0); diff --git a/src/conf.h b/src/conf.h index 14cc883b9..e2e50c5bc 100644 --- a/src/conf.h +++ b/src/conf.h @@ -23,6 +23,8 @@ #define CONF_MUSIC_DIR "music_directory" #define CONF_PLAYLIST_DIR "playlist_directory" +#define CONF_FOLLOW_INSIDE_SYMLINKS "follow_inside_symlinks" +#define CONF_FOLLOW_OUTSIDE_SYMLINKS "follow_outside_symlinks" #define CONF_DB_FILE "db_file" #define CONF_LOG_FILE "log_file" #define CONF_ERROR_FILE "error_file" diff --git a/src/update.c b/src/update.c index b4f02d59c..2349d3e0f 100644 --- a/src/update.c +++ b/src/update.c @@ -31,6 +31,7 @@ #include "condition.h" #include "update.h" #include "idle.h" +#include "conf.h" #include <glib.h> @@ -56,6 +57,14 @@ static struct song *delete; static struct condition delete_cond; +enum { + DEFAULT_FOLLOW_INSIDE_SYMLINKS = true, + DEFAULT_FOLLOW_OUTSIDE_SYMLINKS = false, +}; + +static bool follow_inside_symlinks; +static bool follow_outside_symlinks; + unsigned isUpdatingDB(void) { @@ -337,19 +346,28 @@ skip_symlink(const struct directory *directory, const char *utf8_name) /* don't skip if this is not a symlink */ return errno != EINVAL; - if (buffer[0] == '/') + if (!follow_inside_symlinks && !follow_outside_symlinks) { + /* ignore all symlinks */ + return true; + } else if (follow_inside_symlinks && follow_outside_symlinks) { + /* consider all symlinks */ return false; + } + + if (buffer[0] == '/') + return !follow_outside_symlinks; p = buffer; while (*p == '.') { if (p[1] == '.' && p[2] == '/') { /* "../" moves to parent directory */ directory = directory->parent; - if (directory == NULL) + if (directory == NULL) { /* we have moved outside the music - directory - don't skip this - symlink */ - return false; + directory - skip this symlink + if such symlinks are not allowed */ + return !follow_outside_symlinks; + } p += 3; } else if (p[1] == '/') /* eliminate "./" */ @@ -359,8 +377,9 @@ skip_symlink(const struct directory *directory, const char *utf8_name) } /* we are still in the music directory, so this symlink points - to a song which is already in the database - skip it */ - return true; + to a song which is already in the database - skip according + to the follow_inside_symlinks param*/ + return !follow_inside_symlinks; } static bool @@ -583,6 +602,13 @@ void reap_update_task(void) void update_global_init(void) { + follow_inside_symlinks = + config_get_bool(CONF_FOLLOW_INSIDE_SYMLINKS, + DEFAULT_FOLLOW_INSIDE_SYMLINKS); + + follow_outside_symlinks = + config_get_bool(CONF_FOLLOW_OUTSIDE_SYMLINKS, + DEFAULT_FOLLOW_OUTSIDE_SYMLINKS); } void update_global_finish(void) |