From a295b448ba097d29bce0dc54154d4c368b3503c1 Mon Sep 17 00:00:00 2001 From: Justin Maggard Date: Thu, 4 Jun 2009 22:32:10 +0000 Subject: [PATCH] * To my surprise, XFS doesn't support dt_type in readdir results, so we need to stat each entry of type DT_UNKNOWN. --- inotify.c | 31 +++++++++++++++++-- minidlnatypes.h | 9 +++++- scanner.c | 82 ++----------------------------------------------- utils.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++ utils.h | 12 ++++++++ 5 files changed, 128 insertions(+), 84 deletions(-) diff --git a/inotify.c b/inotify.c index eecb939..3095d9e 100644 --- a/inotify.c +++ b/inotify.c @@ -234,7 +234,8 @@ int add_dir_watch(int fd, char * path, char * filename) if( strcmp(e->d_name, ".") == 0 || strcmp(e->d_name, "..") == 0 ) continue; - if( e->d_type == DT_DIR ) + if( (e->d_type == DT_DIR) || + (e->d_type == DT_UNKNOWN && resolve_unknown_type(buf, NO_MEDIA) == TYPE_DIR) ) i += add_dir_watch(fd, buf, e->d_name); } } @@ -383,6 +384,9 @@ inotify_insert_directory(int fd, char *name, const char * path) char *id=NULL, *path_buf, *parent_buf, *esc_name; int wd; int rows, i = 0; + enum file_types type = TYPE_UNKNOWN; + enum media_types dir_type = ALL_MEDIA; + struct media_dir_s * media_path; parent_buf = dirname(strdup(path)); sql = sqlite3_mprintf("SELECT OBJECT_ID from OBJECTS o left join DETAILS d on (d.ID = o.DETAIL_ID)" @@ -406,6 +410,17 @@ inotify_insert_directory(int fd, char *name, const char * path) DPRINTF(E_INFO, L_INOTIFY, "Added watch to %s [%d]\n", path, wd); } + media_path = media_dirs; + while( media_path ) + { + if( strncmp(path, media_path->path, strlen(media_path->path)) == 0 ) + { + dir_type = media_path->type; + break; + } + media_path = media_path->next; + } + ds = opendir(path); if( ds != NULL ) { @@ -418,11 +433,21 @@ inotify_insert_directory(int fd, char *name, const char * path) if( !esc_name ) esc_name = strdup(e->d_name); asprintf(&path_buf, "%s/%s", path, e->d_name); - if( e->d_type == DT_DIR ) + switch( e->d_type ) + { + case DT_DIR: + case DT_REG: + case DT_LNK: + case DT_UNKNOWN: + type = resolve_unknown_type(path_buf, dir_type); + default: + break; + } + if( type == TYPE_DIR ) { inotify_insert_directory(fd, esc_name, path_buf); } - else if( e->d_type == DT_REG ) + else if( type == TYPE_FILE ) { inotify_insert_file(esc_name, path_buf); } diff --git a/minidlnatypes.h b/minidlnatypes.h index 70018a6..a352bb6 100644 --- a/minidlnatypes.h +++ b/minidlnatypes.h @@ -25,7 +25,14 @@ enum media_types { ALL_MEDIA, AUDIO_ONLY, VIDEO_ONLY, - IMAGES_ONLY + IMAGES_ONLY, + NO_MEDIA +}; + +enum file_types { + TYPE_UNKNOWN, + TYPE_DIR, + TYPE_FILE }; enum client_types { diff --git a/scanner.c b/scanner.c index aa0f30e..7ed91c7 100644 --- a/scanner.c +++ b/scanner.c @@ -44,39 +44,6 @@ struct virtual_item char name[256]; }; -int -is_video(const char * file) -{ - return (ends_with(file, ".mpg") || ends_with(file, ".mpeg") || - ends_with(file, ".avi") || ends_with(file, ".divx") || - ends_with(file, ".asf") || ends_with(file, ".wmv") || - ends_with(file, ".mp4") || ends_with(file, ".m4v") || - ends_with(file, ".mts") || ends_with(file, ".m2ts") || - ends_with(file, ".m2t") || ends_with(file, ".mkv") || - ends_with(file, ".vob") || ends_with(file, ".ts") || - #ifdef TIVO_SUPPORT - ends_with(file, ".TiVo") || - #endif - ends_with(file, ".flv") || ends_with(file, ".xvid")); -} - -int -is_audio(const char * file) -{ - return (ends_with(file, ".mp3") || ends_with(file, ".flac") || - ends_with(file, ".wma") || ends_with(file, ".asf") || - ends_with(file, ".fla") || ends_with(file, ".flc") || - ends_with(file, ".m4a") || ends_with(file, ".aac") || - ends_with(file, ".mp4") || ends_with(file, ".m4p") || - ends_with(file, ".wav")); -} - -int -is_image(const char * file) -{ - return (ends_with(file, ".jpg") || ends_with(file, ".jpeg")); -} - sqlite_int64 get_next_available_id(const char * table, const char * parentID) { @@ -755,51 +722,6 @@ filter_media(const struct dirent *d) ) )); } -#define TYPE_OTHER 0 -#define TYPE_DIR 1 -#define TYPE_FILE 2 -unsigned char -resolve_unknown_type(const char * path, enum media_types dir_type) -{ - struct stat entry; - unsigned char type = TYPE_OTHER; - - if( stat(path, &entry) == 0 ) - { - if( S_ISDIR(entry.st_mode) ) - { - type = TYPE_DIR; - } - else if( S_ISREG(entry.st_mode) ) - { - switch( dir_type ) - { - case ALL_MEDIA: - if( is_image(path) || - is_audio(path) || - is_video(path) ) - type = TYPE_FILE; - break; - case AUDIO_ONLY: - if( is_audio(path) ) - type = TYPE_FILE; - break; - case VIDEO_ONLY: - if( is_video(path) ) - type = TYPE_FILE; - break; - case IMAGES_ONLY: - if( is_image(path) ) - type = TYPE_FILE; - break; - default: - break; - } - } - } - return type; -} - void ScanDirectory(const char * dir, const char * parent, enum media_types dir_type) { @@ -809,7 +731,7 @@ ScanDirectory(const char * dir, const char * parent, enum media_types dir_type) char full_path[PATH_MAX]; char * name = NULL; static long long unsigned int fileno = 0; - unsigned char type; + enum file_types type; setlocale(LC_COLLATE, ""); if( chdir(dir) != 0 ) @@ -846,7 +768,7 @@ ScanDirectory(const char * dir, const char * parent, enum media_types dir_type) for (i=0; i < n; i++) { - type = 0; + type = TYPE_UNKNOWN; sprintf(full_path, "%s/%s", dir, namelist[i]->d_name); name = escape_tag(namelist[i]->d_name); if( namelist[i]->d_type == DT_DIR ) diff --git a/utils.c b/utils.c index fa8f516..37b7324 100644 --- a/utils.c +++ b/utils.c @@ -26,6 +26,8 @@ #include #include +#include "minidlnatypes.h" + int ends_with(const char * haystack, const char * needle) { @@ -161,3 +163,79 @@ make_dir(char * path, mode_t mode) printf("make_dir: cannot create directory '%s'", path); return -1; } + +int +is_video(const char * file) +{ + return (ends_with(file, ".mpg") || ends_with(file, ".mpeg") || + ends_with(file, ".avi") || ends_with(file, ".divx") || + ends_with(file, ".asf") || ends_with(file, ".wmv") || + ends_with(file, ".mp4") || ends_with(file, ".m4v") || + ends_with(file, ".mts") || ends_with(file, ".m2ts") || + ends_with(file, ".m2t") || ends_with(file, ".mkv") || + ends_with(file, ".vob") || ends_with(file, ".ts") || + #ifdef TIVO_SUPPORT + ends_with(file, ".TiVo") || + #endif + ends_with(file, ".flv") || ends_with(file, ".xvid")); +} + +int +is_audio(const char * file) +{ + return (ends_with(file, ".mp3") || ends_with(file, ".flac") || + ends_with(file, ".wma") || ends_with(file, ".asf") || + ends_with(file, ".fla") || ends_with(file, ".flc") || + ends_with(file, ".m4a") || ends_with(file, ".aac") || + ends_with(file, ".mp4") || ends_with(file, ".m4p") || + ends_with(file, ".wav")); +} + +int +is_image(const char * file) +{ + return (ends_with(file, ".jpg") || ends_with(file, ".jpeg")); +} + +int +resolve_unknown_type(const char * path, enum media_types dir_type) +{ + struct stat entry; + unsigned char type = TYPE_UNKNOWN; + + if( stat(path, &entry) == 0 ) + { + if( S_ISDIR(entry.st_mode) ) + { + type = TYPE_DIR; + } + else if( S_ISREG(entry.st_mode) ) + { + switch( dir_type ) + { + case ALL_MEDIA: + if( is_image(path) || + is_audio(path) || + is_video(path) ) + type = TYPE_FILE; + break; + case AUDIO_ONLY: + if( is_audio(path) ) + type = TYPE_FILE; + break; + case VIDEO_ONLY: + if( is_video(path) ) + type = TYPE_FILE; + break; + case IMAGES_ONLY: + if( is_image(path) ) + type = TYPE_FILE; + break; + default: + break; + } + } + } + return type; +} + diff --git a/utils.h b/utils.h index ead5fa7..5e1dac4 100644 --- a/utils.h +++ b/utils.h @@ -28,4 +28,16 @@ strip_ext(char * name); int make_dir(char * path, mode_t mode); +int +is_video(const char * file); + +int +is_audio(const char * file); + +int +is_image(const char * file); + +int +resolve_unknown_type(const char * path, enum media_types dir_type); + #endif