📄 directory.c
字号:
*pb_bool = false; /* FIXME */ break; /* */ case ACCESS_GET_MTU: pi_int = (int*)va_arg( args, int * ); *pi_int = 0; break; case ACCESS_GET_PTS_DELAY: pi_64 = (int64_t*)va_arg( args, int64_t * ); *pi_64 = DEFAULT_PTS_DELAY * 1000; break; /* */ case ACCESS_SET_PAUSE_STATE: case ACCESS_GET_TITLE_INFO: case ACCESS_SET_TITLE: case ACCESS_SET_SEEKPOINT: case ACCESS_SET_PRIVATE_ID_STATE: case ACCESS_GET_CONTENT_TYPE: case ACCESS_GET_META: return VLC_EGENERIC; default: msg_Warn( p_access, "unimplemented query in control" ); return VLC_EGENERIC; } return VLC_SUCCESS;}/***************************************************************************** * DemuxOpen: *****************************************************************************/static int DemuxOpen ( vlc_object_t *p_this ){ demux_t *p_demux = (demux_t*)p_this; if( strcmp( p_demux->psz_demux, "directory" ) ) return VLC_EGENERIC; p_demux->pf_demux = Demux; p_demux->pf_control = DemuxControl; return VLC_SUCCESS;}/***************************************************************************** * Demux: EOF *****************************************************************************/static int Demux( demux_t *p_demux ){ (void)p_demux; return 0;}/***************************************************************************** * DemuxControl: *****************************************************************************/static int DemuxControl( demux_t *p_demux, int i_query, va_list args ){ return demux_vaControlHelper( p_demux->s, 0, 0, 0, 1, i_query, args );}static int Sort (const char **a, const char **b){ return strcoll (*a, *b);}struct stat_list_t{ stat_list_t *parent; struct stat st;};/***************************************************************************** * ReadDir: read a directory and add its content to the list *****************************************************************************/static int ReadDir( access_t *p_access, playlist_t *p_playlist, const char *psz_name, int i_mode, playlist_item_t *p_parent_category, input_item_t *p_current_input, DIR *handle, stat_list_t *stparent ){ char **pp_dir_content = NULL; int i_dir_content, i, i_return = VLC_SUCCESS; playlist_item_t *p_node; if( !vlc_object_alive( p_access ) ) return VLC_EGENERIC; if( !vlc_object_alive( p_playlist ) ) return VLC_EGENERIC; char **ppsz_extensions = NULL; int i_extensions = 0; char *psz_ignore; struct stat_list_t stself;#ifndef WIN32 int fd = dirfd (handle); if ((fd == -1) || fstat (fd, &stself.st)) { msg_Err (p_playlist, "cannot stat `%s': %m", psz_name); return VLC_EGENERIC; } for (stat_list_t *stats = stparent; stats != NULL; stats = stats->parent) { if ((stself.st.st_ino == stats->st.st_ino) && (stself.st.st_dev == stats->st.st_dev)) { msg_Warn (p_playlist, "ignoring infinitely recursive directory `%s'", psz_name); return VLC_SUCCESS; } }#else /* Windows has st_dev (driver letter - 'A'), but it zeroes st_ino, * so that the test above will always incorrectly succeed. * Besides, Windows does not have dirfd(). */#endif stself.parent = stparent; /* Get the first directory entry */ i_dir_content = utf8_loaddir (handle, &pp_dir_content, NULL, Sort); if( i_dir_content == -1 ) { msg_Err (p_playlist, "cannot read `%s': %m", psz_name); return VLC_EGENERIC; } else if( i_dir_content <= 0 ) { /* directory is empty */ msg_Dbg( p_playlist, "%s directory is empty", psz_name ); free( pp_dir_content ); return VLC_SUCCESS; } /* Build array with ignores */ psz_ignore = var_CreateGetString( p_playlist, "ignore-filetypes" ); if( psz_ignore && *psz_ignore ) { char *psz_parser = psz_ignore; int a; for( a = 0; psz_parser[a] != '\0'; a++ ) { if( psz_parser[a] == ',' ) i_extensions++; } ppsz_extensions = (char **)calloc (i_extensions, sizeof (char *)); for( a = 0; a < i_extensions; a++ ) { char *tmp, *ptr; while( psz_parser[0] != '\0' && psz_parser[0] == ' ' ) psz_parser++; ptr = strchr( psz_parser, ','); tmp = ( ptr == NULL ) ? strdup( psz_parser ) : strndup( psz_parser, ptr - psz_parser ); ppsz_extensions[a] = tmp; psz_parser = ptr + 1; } } free( psz_ignore ); /* While we still have entries in the directory */ for( i = 0; i < i_dir_content; i++ ) { const char *entry = pp_dir_content[i]; int i_size_entry = strlen( psz_name ) + strlen( entry ) + 2 + 7 /* strlen("file://") */; char psz_uri[i_size_entry]; sprintf( psz_uri, "%s/%s", psz_name, entry); /* if it starts with '.' then forget it */ if (entry[0] != '.') { DIR *subdir = (i_mode != MODE_COLLAPSE) ? OpenDir (VLC_OBJECT (p_playlist), psz_uri) : NULL; if (subdir != NULL) /* Recurse into subdirectory */ { if( i_mode == MODE_NONE ) { msg_Dbg( p_playlist, "skipping subdirectory `%s'", psz_uri ); closedir (subdir); continue; } msg_Dbg (p_playlist, "creating subdirectory %s", psz_uri); PL_LOCK; p_node = playlist_NodeCreate( p_playlist, entry, p_parent_category, PLAYLIST_NO_REBUILD, NULL ); PL_UNLOCK; assert( p_node ); /* If we had the parent in category, the it is now node. * Else, we still don't have */ i_return = ReadDir( p_access, p_playlist, psz_uri , MODE_EXPAND, p_parent_category ? p_node : NULL, p_current_input, subdir, &stself ); closedir (subdir); if (i_return) break; // error :-( } else { input_item_t *p_input; if( i_extensions > 0 ) { const char *psz_dot = strrchr (entry, '.' ); if( psz_dot++ && *psz_dot ) { int a; for( a = 0; a < i_extensions; a++ ) { if( !strcmp( psz_dot, ppsz_extensions[a] ) ) break; } if( a < i_extensions ) { msg_Dbg( p_playlist, "ignoring file %s", psz_uri ); continue; } } } memmove (psz_uri + 7, psz_uri, sizeof (psz_uri) - 7); memcpy (psz_uri, "file://", 7); p_input = input_item_NewWithType( VLC_OBJECT( p_playlist ), psz_uri, entry, 0, NULL, -1, ITEM_TYPE_FILE ); if (p_input != NULL) { if( p_current_input ) input_item_CopyOptions( p_current_input, p_input ); assert( p_parent_category ); int i_ret = playlist_BothAddInput( p_playlist, p_input, p_parent_category, PLAYLIST_APPEND|PLAYLIST_PREPARSE| PLAYLIST_NO_REBUILD, PLAYLIST_END, NULL, NULL, pl_Unlocked ); vlc_gc_decref( p_input ); if( i_ret != VLC_SUCCESS ) return VLC_EGENERIC; } } } } for( i = 0; i < i_extensions; i++ ) free( ppsz_extensions[i] ); free( ppsz_extensions ); for( i = 0; i < i_dir_content; i++ ) free( pp_dir_content[i] ); free( pp_dir_content ); return i_return;}static DIR *OpenDir (vlc_object_t *obj, const char *path){ DIR *handle = utf8_opendir (path); if (handle == NULL) { int err = errno; if (err != ENOTDIR) msg_Err (obj, "%s: %m", path); // else not a dir errno = err; return NULL; } msg_Dbg (obj, "opening directory `%s'", path); return handle;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -