* To my surprise, XFS doesn't support dt_type in readdir results, so we need to stat each entry of type DT_UNKNOWN.
This commit is contained in:
		
							
								
								
									
										31
									
								
								inotify.c
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								inotify.c
									
									
									
									
									
								
							@@ -234,7 +234,8 @@ int add_dir_watch(int fd, char * path, char * filename)
 | 
				
			|||||||
			if( strcmp(e->d_name, ".") == 0 ||
 | 
								if( strcmp(e->d_name, ".") == 0 ||
 | 
				
			||||||
			    strcmp(e->d_name, "..") == 0 )
 | 
								    strcmp(e->d_name, "..") == 0 )
 | 
				
			||||||
				continue;
 | 
									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);
 | 
									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;
 | 
						char *id=NULL, *path_buf, *parent_buf, *esc_name;
 | 
				
			||||||
	int wd;
 | 
						int wd;
 | 
				
			||||||
	int rows, i = 0;
 | 
						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));
 | 
					 	parent_buf = dirname(strdup(path));
 | 
				
			||||||
	sql = sqlite3_mprintf("SELECT OBJECT_ID from OBJECTS o left join DETAILS d on (d.ID = o.DETAIL_ID)"
 | 
						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);
 | 
							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);
 | 
						ds = opendir(path);
 | 
				
			||||||
	if( ds != NULL )
 | 
						if( ds != NULL )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@@ -418,11 +433,21 @@ inotify_insert_directory(int fd, char *name, const char * path)
 | 
				
			|||||||
			if( !esc_name )
 | 
								if( !esc_name )
 | 
				
			||||||
				esc_name = strdup(e->d_name);
 | 
									esc_name = strdup(e->d_name);
 | 
				
			||||||
			asprintf(&path_buf, "%s/%s", path, 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);
 | 
									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);
 | 
									inotify_insert_file(esc_name, path_buf);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,7 +25,14 @@ enum media_types {
 | 
				
			|||||||
	ALL_MEDIA,
 | 
						ALL_MEDIA,
 | 
				
			||||||
	AUDIO_ONLY,
 | 
						AUDIO_ONLY,
 | 
				
			||||||
	VIDEO_ONLY,
 | 
						VIDEO_ONLY,
 | 
				
			||||||
	IMAGES_ONLY
 | 
						IMAGES_ONLY,
 | 
				
			||||||
 | 
						NO_MEDIA
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum file_types {
 | 
				
			||||||
 | 
						TYPE_UNKNOWN,
 | 
				
			||||||
 | 
						TYPE_DIR,
 | 
				
			||||||
 | 
						TYPE_FILE
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum client_types {
 | 
					enum client_types {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										82
									
								
								scanner.c
									
									
									
									
									
								
							
							
						
						
									
										82
									
								
								scanner.c
									
									
									
									
									
								
							@@ -44,39 +44,6 @@ struct virtual_item
 | 
				
			|||||||
	char name[256];
 | 
						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
 | 
					sqlite_int64
 | 
				
			||||||
get_next_available_id(const char * table, const char * parentID)
 | 
					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
 | 
					void
 | 
				
			||||||
ScanDirectory(const char * dir, const char * parent, enum media_types dir_type)
 | 
					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 full_path[PATH_MAX];
 | 
				
			||||||
	char * name = NULL;
 | 
						char * name = NULL;
 | 
				
			||||||
	static long long unsigned int fileno = 0;
 | 
						static long long unsigned int fileno = 0;
 | 
				
			||||||
	unsigned char type;
 | 
						enum file_types type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	setlocale(LC_COLLATE, "");
 | 
						setlocale(LC_COLLATE, "");
 | 
				
			||||||
	if( chdir(dir) != 0 )
 | 
						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++)
 | 
						for (i=0; i < n; i++)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		type = 0;
 | 
							type = TYPE_UNKNOWN;
 | 
				
			||||||
		sprintf(full_path, "%s/%s", dir, namelist[i]->d_name);
 | 
							sprintf(full_path, "%s/%s", dir, namelist[i]->d_name);
 | 
				
			||||||
		name = escape_tag(namelist[i]->d_name);
 | 
							name = escape_tag(namelist[i]->d_name);
 | 
				
			||||||
		if( namelist[i]->d_type == DT_DIR )
 | 
							if( namelist[i]->d_type == DT_DIR )
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										78
									
								
								utils.c
									
									
									
									
									
								
							
							
						
						
									
										78
									
								
								utils.c
									
									
									
									
									
								
							@@ -26,6 +26,8 @@
 | 
				
			|||||||
#include <fcntl.h>
 | 
					#include <fcntl.h>
 | 
				
			||||||
#include <errno.h>
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "minidlnatypes.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
ends_with(const char * haystack, const char * needle)
 | 
					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);
 | 
						printf("make_dir: cannot create directory '%s'", path);
 | 
				
			||||||
	return -1;
 | 
						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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										12
									
								
								utils.h
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								utils.h
									
									
									
									
									
								
							@@ -28,4 +28,16 @@ strip_ext(char * name);
 | 
				
			|||||||
int
 | 
					int
 | 
				
			||||||
make_dir(char * path, mode_t mode);
 | 
					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
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user