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()]
This commit is contained in:
Raphaël Rigo 2008-11-28 10:57:39 +01:00 committed by Max Kellermann
parent 011855d22b
commit 5b089f85fd
5 changed files with 50 additions and 7 deletions

View File

@ -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

View File

@ -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"
################################################################

View File

@ -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);

View File

@ -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"

View File

@ -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)