[scan] Configuration option to follow symlinks

This commit is contained in:
Wolfgang Scherer 2017-11-09 01:16:44 +01:00
parent 84fc4622d5
commit 16fa1e77b2
3 changed files with 30 additions and 3 deletions

View File

@ -62,6 +62,9 @@ library {
# Directories to index
directories = { "/srv/music" }
# Follow symlinks. Default: true.
# follow_symlinks = true
# Directories containing podcasts
# For each directory that is indexed the path is matched against these
# names. If there is a match all items in the directory are marked as

View File

@ -73,6 +73,7 @@ static cfg_opt_t sec_library[] =
CFG_INT("port", 3689, CFGF_NONE),
CFG_STR("password", NULL, CFGF_NONE),
CFG_STR_LIST("directories", NULL, CFGF_NONE),
CFG_BOOL("follow_symlinks", cfg_true, CFGF_NONE),
CFG_STR_LIST("podcasts", NULL, CFGF_NONE),
CFG_STR_LIST("audiobooks", NULL, CFGF_NONE),
CFG_STR_LIST("compilations", NULL, CFGF_NONE),

View File

@ -679,10 +679,12 @@ create_virtual_path(char *path, char *virtual_path, int virtual_path_len)
* The return value is 0 if the operation is successful, or -1 on failure
*/
static int
read_attributes(char *resolved_path, const char *path, struct stat *sb)
read_attributes(char *resolved_path, const char *path, struct stat *sb, int *is_link)
{
int ret;
*is_link = 0;
ret = lstat(path, sb);
if (ret < 0)
{
@ -692,6 +694,8 @@ read_attributes(char *resolved_path, const char *path, struct stat *sb)
if (S_ISLNK(sb->st_mode))
{
*is_link = 1;
if (!realpath(path, resolved_path))
{
DPRINTF(E_LOG, L_SCAN, "Skipping %s, could not dereference symlink: %s\n", path, strerror(errno));
@ -721,6 +725,8 @@ process_directory(char *path, int parent_id, int flags)
char entry[PATH_MAX];
char resolved_path[PATH_MAX];
struct stat sb;
int is_link;
int follow_symlinks;
struct watch_info wi;
int type;
char virtual_path[PATH_MAX];
@ -758,6 +764,8 @@ process_directory(char *path, int parent_id, int flags)
if (check_speciallib(path, "audiobooks"))
type |= F_SCAN_TYPE_AUDIOBOOK;
follow_symlinks = cfg_getbool(cfg_getsec(cfg, "library"), "follow_symlinks");
for (;;)
{
if (library_is_exiting())
@ -786,7 +794,7 @@ process_directory(char *path, int parent_id, int flags)
continue;
}
ret = read_attributes(resolved_path, entry, &sb);
ret = read_attributes(resolved_path, entry, &sb, &is_link);
if (ret < 0)
{
DPRINTF(E_LOG, L_SCAN, "Skipping %s, read_attributes() failed\n", entry);
@ -794,6 +802,12 @@ process_directory(char *path, int parent_id, int flags)
continue;
}
if (is_link && !follow_symlinks)
{
DPRINTF(E_DBG, L_SCAN, "Ignore symlink %s\n", entry);
continue;
}
if (S_ISDIR(sb.st_mode))
{
push_dir(&dirstack, resolved_path, dir_id);
@ -1179,6 +1193,7 @@ static void
process_inotify_file(struct watch_info *wi, char *path, struct inotify_event *ie)
{
struct stat sb;
int is_link;
uint32_t path_hash;
char *file = path;
char resolved_path[PATH_MAX];
@ -1306,6 +1321,8 @@ process_inotify_file(struct watch_info *wi, char *path, struct inotify_event *ie
if (ie->mask & IN_CLOSE_WRITE)
{
int follow_symlinks = cfg_getbool(cfg_getsec(cfg, "library"), "follow_symlinks");
DPRINTF(E_DBG, L_SCAN, "File closed: %s\n", path);
// File has been closed so remove from the IN_ATTRIB ignore list
@ -1317,7 +1334,7 @@ process_inotify_file(struct watch_info *wi, char *path, struct inotify_event *ie
incomingfiles_buffer[i] = 0;
}
ret = read_attributes(resolved_path, path, &sb);
ret = read_attributes(resolved_path, path, &sb, &is_link);
if (ret < 0)
{
DPRINTF(E_LOG, L_SCAN, "Skipping %s, read_attributes() failed\n", path);
@ -1325,6 +1342,12 @@ process_inotify_file(struct watch_info *wi, char *path, struct inotify_event *ie
return;
}
if (is_link && !follow_symlinks)
{
DPRINTF(E_DBG, L_SCAN, "Ignore symlink %s\n", path);
return;
}
type = 0;
if (check_speciallib(path, "compilations"))
type |= F_SCAN_TYPE_COMPILATION;