aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaphaƫl Rigo <devel-mpd@syscall.eu>2008-11-28 10:57:39 +0100
committerMax Kellermann <max@duempel.org>2008-11-28 10:57:39 +0100
commit5b089f85fd6cf3139768f450b8c18fe9d9211b73 (patch)
tree2cd22bb8954a9b03a7298a48beb7766c06c5ec9a
parent011855d22bbf9bc8e1589fd16e386fb181724ad3 (diff)
downloadmpd-5b089f85fd6cf3139768f450b8c18fe9d9211b73.tar.gz
mpd-5b089f85fd6cf3139768f450b8c18fe9d9211b73.tar.xz
mpd-5b089f85fd6cf3139768f450b8c18fe9d9211b73.zip
update: added options which control symlink behaviour
The configuration options "follow_outside_symlinks" and "follow_inside_symlinks" let the user control whether MPD should follow symbolic links in the music directory. [mk: converted variables to "bool"; moved configuration to update_global_init()]
-rw-r--r--doc/mpd.conf.511
-rw-r--r--doc/mpdconf.example2
-rw-r--r--src/conf.c2
-rw-r--r--src/conf.h2
-rw-r--r--src/update.c40
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)