mirror of
https://github.com/owntone/owntone-server.git
synced 2025-01-12 15:33:23 -05:00
add scanning/follow_symlinks option to close ticket #194
This commit is contained in:
parent
b87d2443b7
commit
0fa620d4a7
@ -182,6 +182,17 @@
|
|||||||
<option value="1">Yes</option>
|
<option value="1">Yes</option>
|
||||||
</options>
|
</options>
|
||||||
</item>
|
</item>
|
||||||
|
<item id="scanning:follow_symlinks">
|
||||||
|
<name>Follow Symlinks</name>
|
||||||
|
<short_description>
|
||||||
|
Should symlinks be followed when scanning directories?
|
||||||
|
</short_description>
|
||||||
|
<type default_value="1">select</type>
|
||||||
|
<options>
|
||||||
|
<option value="0">No</option>
|
||||||
|
<option value="1">Yes</option>
|
||||||
|
</options>
|
||||||
|
</item>
|
||||||
</section>
|
</section>
|
||||||
<section name="Database">
|
<section name="Database">
|
||||||
<item id="general:db_type" advanced="true" restart="true">
|
<item id="general:db_type" advanced="true" restart="true">
|
||||||
|
@ -135,6 +135,7 @@ static CONF_ELEMENTS conf_elements[] = {
|
|||||||
{ 0, 0, CONF_T_INT,"scanning","ignore_dotfiles" },
|
{ 0, 0, CONF_T_INT,"scanning","ignore_dotfiles" },
|
||||||
{ 0, 0, CONF_T_INT,"scanning","concat_compilations" },
|
{ 0, 0, CONF_T_INT,"scanning","concat_compilations" },
|
||||||
{ 0, 0, CONF_T_INT,"scanning","case_sensitive" },
|
{ 0, 0, CONF_T_INT,"scanning","case_sensitive" },
|
||||||
|
{ 0, 0, CONF_T_INT,"scanning","follow_symlinks" },
|
||||||
{ 0, 0, CONF_T_INT,"scan","correct_order" },
|
{ 0, 0, CONF_T_INT,"scan","correct_order" },
|
||||||
{ 0, 0, CONF_T_INT, NULL, NULL }
|
{ 0, 0, CONF_T_INT, NULL, NULL }
|
||||||
};
|
};
|
||||||
|
@ -69,6 +69,12 @@ typedef struct {
|
|||||||
|
|
||||||
|
|
||||||
#define MAYBEFREE(a) { if((a)) free((a)); };
|
#define MAYBEFREE(a) { if((a)) free((a)); };
|
||||||
|
#ifndef S_ISDIR
|
||||||
|
# define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR)
|
||||||
|
#endif
|
||||||
|
#ifndef S_ISLNK
|
||||||
|
# define S_ISLNK(a) (((a) & S_IFMT) == S_IFLNK)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -327,7 +333,9 @@ int scan_path(char *path) {
|
|||||||
struct stat sb;
|
struct stat sb;
|
||||||
char *extensions;
|
char *extensions;
|
||||||
int is_compdir;
|
int is_compdir;
|
||||||
|
int follow_symlinks = 0;
|
||||||
|
|
||||||
|
follow_symlinks = conf_get_int("scanning","follow_symlinks",0);
|
||||||
extensions = conf_alloc_string("general","extensions",".mp3,.m4a,.m4p");
|
extensions = conf_alloc_string("general","extensions",".mp3,.m4a,.m4p");
|
||||||
|
|
||||||
if((current_dir=opendir(path)) == NULL) {
|
if((current_dir=opendir(path)) == NULL) {
|
||||||
@ -365,13 +373,19 @@ int scan_path(char *path) {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
snprintf(relative_path,PATH_MAX,"%s/%s",path,pde->d_name);
|
snprintf(relative_path,PATH_MAX,"%s/%s",path,pde->d_name);
|
||||||
|
|
||||||
|
if(!os_lstat(relative_path,&sb)) {
|
||||||
|
if(S_ISLNK(sb.st_mode) && !follow_symlinks)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
mp3_path[0] = '\x0';
|
mp3_path[0] = '\x0';
|
||||||
realpath(relative_path,mp3_path);
|
realpath(relative_path,mp3_path);
|
||||||
DPRINTF(E_DBG,L_SCAN,"Found %s\n",relative_path);
|
DPRINTF(E_DBG,L_SCAN,"Found %s\n",relative_path);
|
||||||
if(os_stat(mp3_path,&sb)) {
|
if(os_stat(mp3_path,&sb)) {
|
||||||
DPRINTF(E_INF,L_SCAN,"Error statting %s: %s\n",mp3_path,strerror(errno));
|
DPRINTF(E_INF,L_SCAN,"Error statting %s: %s\n",mp3_path,strerror(errno));
|
||||||
} else {
|
} else {
|
||||||
if(sb.st_mode & S_IFDIR) { /* dir -- recurse */
|
if(S_ISDIR(sb.st_mode)) { /* follow dir */
|
||||||
if(conf_get_int("scanning","ignore_appledouble",1) &&
|
if(conf_get_int("scanning","ignore_appledouble",1) &&
|
||||||
((strcasecmp(pde->d_name,".AppleDouble") == 0) ||
|
((strcasecmp(pde->d_name,".AppleDouble") == 0) ||
|
||||||
(strcasecmp(pde->d_name,".AppleDesktop") == 0))) {
|
(strcasecmp(pde->d_name,".AppleDesktop") == 0))) {
|
||||||
|
@ -500,3 +500,7 @@ char *os_apppath(char *parm) {
|
|||||||
int os_stat(const char *path, struct stat *sb) {
|
int os_stat(const char *path, struct stat *sb) {
|
||||||
return stat(path, sb);
|
return stat(path, sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int os_lstat(const char *path, struct stat *sb) {
|
||||||
|
return lstat(path, sb);
|
||||||
|
}
|
||||||
|
@ -146,6 +146,10 @@ char *os_realpath(const char *pathname, char *resolved_path) {
|
|||||||
return &resolved_path[0];
|
return &resolved_path[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int os_lstat(const char *path, struct _stat *sb) {
|
||||||
|
return os_stat(path,sb);
|
||||||
|
}
|
||||||
|
|
||||||
int os_stat(const char *path, struct _stat *sb) {
|
int os_stat(const char *path, struct _stat *sb) {
|
||||||
WCHAR utf16_path[PATH_MAX+1];
|
WCHAR utf16_path[PATH_MAX+1];
|
||||||
|
|
||||||
|
1
src/os.h
1
src/os.h
@ -40,6 +40,7 @@ extern int os_unload(void *handle);
|
|||||||
|
|
||||||
/* misc */
|
/* misc */
|
||||||
extern int os_stat(const char *path, struct stat *sb);
|
extern int os_stat(const char *path, struct stat *sb);
|
||||||
|
extern int os_lstat(const char *path, struct stat *sb);
|
||||||
extern int os_islocaladdr(char *hostaddr);
|
extern int os_islocaladdr(char *hostaddr);
|
||||||
extern char *os_apppath(char *parm);
|
extern char *os_apppath(char *parm);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user