| 
				
				
					
				
				
				 | 
			
			 | 
			@@ -23,6 +23,7 @@ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include "libavutil/internal.h" | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include "libavutil/opt.h" | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include "avformat.h" | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include <dirent.h> | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include <fcntl.h> | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#if HAVE_IO_H | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include <io.h> | 
		
		
	
	
		
			
				| 
				
					
				
				
					
				
				
				 | 
			
			 | 
			@@ -51,6 +52,7 @@ typedef struct FileContext { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    int fd; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    int trunc; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    int blocksize; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    DIR *dir; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} FileContext; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			static const AVOption file_options[] = { | 
		
		
	
	
		
			
				| 
				
					
				
				
					
				
				
				 | 
			
			 | 
			@@ -225,6 +227,88 @@ static int file_close(URLContext *h) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    return close(c->fd); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			static int file_open_dir(URLContext *h) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    FileContext *c = h->priv_data; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    c->dir = opendir(h->filename); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (!c->dir) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        return AVERROR(errno); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    return 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			static int file_read_dir(URLContext *h, AVIODirEntry **next) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    FileContext *c = h->priv_data; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    struct dirent *dir; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    char *fullpath = NULL; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    *next = ff_alloc_dir_entry(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (!*next) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        return AVERROR(ENOMEM); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    do { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        errno = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        dir = readdir(c->dir); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        if (!dir) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            av_freep(next); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            return AVERROR(errno); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } while (!strcmp(dir->d_name, ".") || !strcmp(dir->d_name, "..")); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    fullpath = av_append_path_component(h->filename, dir->d_name); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (fullpath) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        struct stat st; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        if (!stat(fullpath, &st)) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            (*next)->group_id = st.st_gid; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            (*next)->user_id = st.st_uid; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            (*next)->size = st.st_size; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            (*next)->filemode = st.st_mode & 0777; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            (*next)->modification_timestamp = INT64_C(1000000) * st.st_mtime; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            (*next)->access_timestamp =  INT64_C(1000000) * st.st_atime; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            (*next)->status_change_timestamp = INT64_C(1000000) * st.st_ctime; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        av_free(fullpath); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    (*next)->name = av_strdup(dir->d_name); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    switch (dir->d_type) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    case DT_FIFO: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        (*next)->type = AVIO_ENTRY_NAMED_PIPE; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    case DT_CHR: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        (*next)->type = AVIO_ENTRY_CHARACTER_DEVICE; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    case DT_DIR: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        (*next)->type = AVIO_ENTRY_DIRECTORY; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    case DT_BLK: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        (*next)->type = AVIO_ENTRY_BLOCK_DEVICE; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    case DT_REG: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        (*next)->type = AVIO_ENTRY_FILE; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    case DT_LNK: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        (*next)->type = AVIO_ENTRY_SYMBOLIC_LINK; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    case DT_SOCK: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        (*next)->type = AVIO_ENTRY_SOCKET; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    case DT_UNKNOWN: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    default: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        (*next)->type = AVIO_ENTRY_UNKNOWN; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    return 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			static int file_close_dir(URLContext *h) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    FileContext *c = h->priv_data; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    closedir(c->dir); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    return 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			URLProtocol ff_file_protocol = { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    .name                = "file", | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    .url_open            = file_open, | 
		
		
	
	
		
			
				| 
				
				
				
					
				
				 | 
			
			 | 
			@@ -238,6 +322,9 @@ URLProtocol ff_file_protocol = { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    .url_move            = file_move, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    .priv_data_size      = sizeof(FileContext), | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    .priv_data_class     = &file_class, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    .url_open_dir        = file_open_dir, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    .url_read_dir        = file_read_dir, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    .url_close_dir       = file_close_dir, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#endif /* CONFIG_FILE_PROTOCOL */ | 
		
		
	
	
		
			
				| 
				
					
				
				
				
				 | 
			
			 | 
			
  |