static int BrowseShare( stream_t *p_access, input_item_node_t *p_node ) { access_sys_t *p_sys = p_access->p_sys; smb_share_list shares; const char *psz_name; size_t share_count; int i_ret = VLC_SUCCESS; if( smb_share_get_list( p_sys->p_session, &shares, &share_count ) != DSM_SUCCESS ) return VLC_EGENERIC; struct vlc_readdir_helper rdh; vlc_readdir_helper_init( &rdh, p_access, p_node ); for( size_t i = 0; i < share_count && i_ret == VLC_SUCCESS; i++ ) { psz_name = smb_share_list_at( shares, i ); if( psz_name[strlen( psz_name ) - 1] == '$') continue; i_ret = add_item( p_access, &rdh, psz_name, ITEM_TYPE_DIRECTORY ); } vlc_readdir_helper_finish( &rdh, i_ret == VLC_SUCCESS ); smb_share_list_destroy( shares ); return i_ret; }
static int BrowseDirectory( stream_t *p_access, input_item_node_t *p_node ) { access_sys_t *p_sys = p_access->p_sys; smb_stat_list files; smb_stat st; char *psz_query; const char *psz_name; size_t files_count; int i_ret = VLC_SUCCESS; if( p_sys->psz_path != NULL ) { if( asprintf( &psz_query, "%s\\*", p_sys->psz_path ) == -1 ) return VLC_ENOMEM; files = smb_find( p_sys->p_session, p_sys->i_tid, psz_query ); free( psz_query ); } else files = smb_find( p_sys->p_session, p_sys->i_tid, "\\*" ); if( files == NULL ) return VLC_EGENERIC; struct vlc_readdir_helper rdh; vlc_readdir_helper_init( &rdh, p_access, p_node ); files_count = smb_stat_list_count( files ); for( size_t i = 0; i < files_count && i_ret == VLC_SUCCESS; i++ ) { int i_type; st = smb_stat_list_at( files, i ); if( st == NULL ) { continue; } psz_name = smb_stat_name( st ); i_type = smb_stat_get( st, SMB_STAT_ISDIR ) ? ITEM_TYPE_DIRECTORY : ITEM_TYPE_FILE; i_ret = add_item( p_access, &rdh, psz_name, i_type ); } vlc_readdir_helper_finish( &rdh, i_ret == VLC_SUCCESS ); smb_stat_list_destroy( files ); return i_ret; }
static int ReadDir( stream_directory_t* p_directory, input_item_node_t* p_node ) { private_sys_t* p_sys = p_directory->p_sys; libarchive_t* p_arc = p_sys->p_archive; struct vlc_readdir_helper rdh; vlc_readdir_helper_init( &rdh, p_directory, p_node); struct archive_entry* entry; int archive_status; while( !( archive_status = archive_read_next_header( p_arc, &entry ) ) ) { if( archive_entry_filetype( entry ) == AE_IFDIR ) continue; char const* path = archive_entry_pathname( entry ); if( unlikely( !path ) ) break; char* mrl = vlc_stream_extractor_CreateMRL( p_directory, path ); if( unlikely( !mrl ) ) break; if( vlc_readdir_helper_additem( &rdh, mrl, path, NULL, ITEM_TYPE_FILE, ITEM_LOCAL ) ) { free( mrl ); break; } free( mrl ); if( archive_read_data_skip( p_arc ) ) break; } vlc_readdir_helper_finish( &rdh, archive_status == ARCHIVE_EOF ); return archive_status == ARCHIVE_EOF ? VLC_SUCCESS : VLC_EGENERIC; }
int DirRead (stream_t *access, input_item_node_t *node) { access_sys_t *sys = access->p_sys; const char *entry; int ret = VLC_SUCCESS; bool special_files = var_InheritBool(access, "list-special-files"); struct vlc_readdir_helper rdh; vlc_readdir_helper_init(&rdh, access, node); while (ret == VLC_SUCCESS && (entry = vlc_readdir(sys->dir)) != NULL) { struct stat st; int type; #ifdef HAVE_OPENAT if (fstatat(dirfd(sys->dir), entry, &st, 0)) continue; #else char path[PATH_MAX]; if (snprintf(path, PATH_MAX, "%s"DIR_SEP"%s", access->psz_filepath, entry) >= PATH_MAX || vlc_stat(path, &st)) continue; #endif switch (st.st_mode & S_IFMT) { case S_IFBLK: if (!special_files) continue; type = ITEM_TYPE_DISC; break; case S_IFCHR: if (!special_files) continue; type = ITEM_TYPE_CARD; break; case S_IFIFO: if (!special_files) continue; type = ITEM_TYPE_STREAM; break; case S_IFREG: type = ITEM_TYPE_FILE; break; case S_IFDIR: type = ITEM_TYPE_DIRECTORY; break; /* S_IFLNK cannot occur while following symbolic links */ /* S_IFSOCK cannot be opened with open()/openat() */ default: continue; /* ignore */ } /* Create an input item for the current entry */ char *encoded = vlc_uri_encode(entry); if (unlikely(encoded == NULL)) { ret = VLC_ENOMEM; break; } char *uri; if (unlikely(asprintf(&uri, "%s/%s", sys->base_uri, encoded) == -1)) uri = NULL; free(encoded); if (unlikely(uri == NULL)) { ret = VLC_ENOMEM; break; } ret = vlc_readdir_helper_additem(&rdh, uri, NULL, entry, type, ITEM_NET_UNKNOWN); free(uri); } vlc_readdir_helper_finish(&rdh, ret == VLC_SUCCESS); return ret; }
/***************************************************************************** * DirRead: *****************************************************************************/ static int DirRead (stream_t *p_access, input_item_node_t *p_node ) { access_sys_t *p_sys = p_access->p_sys; int i_ret = VLC_SUCCESS; struct vlc_readdir_helper rdh; vlc_readdir_helper_init( &rdh, p_access, p_node ); #ifndef _WIN32 struct smbc_dirent *p_entry; while( i_ret == VLC_SUCCESS && ( p_entry = smbc_readdir( p_sys->i_smb ) ) ) { char *psz_uri; const char *psz_server = p_sys->url.psz_host; const char *psz_path = p_sys->url.psz_path; const char *psz_name = p_entry->name; int i_type; switch( p_entry->smbc_type ) { case SMBC_SERVER: case SMBC_WORKGROUP: psz_server = p_sys->url.psz_host; psz_path = NULL; psz_name = NULL; case SMBC_FILE_SHARE: case SMBC_DIR: i_type = ITEM_TYPE_DIRECTORY; break; case SMBC_FILE: i_type = ITEM_TYPE_FILE; break; default: case SMBC_PRINTER_SHARE: case SMBC_COMMS_SHARE: case SMBC_IPC_SHARE: case SMBC_LINK: continue; } char *psz_encoded_name = NULL; if( psz_name != NULL && ( psz_encoded_name = vlc_uri_encode( psz_name ) ) == NULL ) { i_ret = VLC_ENOMEM; break; } if( smb_get_uri( p_access, &psz_uri, NULL, NULL, NULL, psz_server, psz_path, psz_encoded_name ) < 0 ) { free(psz_encoded_name); i_ret = VLC_ENOMEM; break; } free(psz_encoded_name); i_ret = vlc_readdir_helper_additem( &rdh, psz_uri, NULL, p_entry->name, i_type, ITEM_NET ); free( psz_uri ); } #else // Handle share listing from here. Directory browsing is handled by the // usual filesystem module. SHARE_INFO_1 *p_info; DWORD i_share_enum_res; DWORD i_nb_elem; DWORD i_resume_handle = 0; DWORD i_total_elements; // Unused, but needs to be passed wchar_t *wpsz_host = ToWide( p_sys->url.psz_host ); if( wpsz_host == NULL ) return VLC_ENOMEM; do { i_share_enum_res = NetShareEnum( wpsz_host, 1, (LPBYTE*)&p_info, MAX_PREFERRED_LENGTH, &i_nb_elem, &i_total_elements, &i_resume_handle ); if( i_share_enum_res == ERROR_SUCCESS || i_share_enum_res == ERROR_MORE_DATA ) { for ( DWORD i = 0; i < i_nb_elem; ++i ) { SHARE_INFO_1 *p_current = p_info + i; if( p_current->shi1_type & STYPE_SPECIAL ) continue; char* psz_name = FromWide( p_current->shi1_netname ); if( psz_name == NULL ) { i_ret = VLC_ENOMEM; break; } char* psz_path; if( smb_get_uri( p_access, &psz_path, NULL, NULL, NULL, p_sys->url.psz_host, p_sys->url.psz_path, psz_name ) < 0 ) { free( psz_name ); i_ret = VLC_ENOMEM; break; } free( psz_name ); // We need to concatenate the scheme before, as the window version // of smb_get_uri generates a path (and the other call site needs // a path). The path is already prefixed by "//" so we just need // to add "file:" char* psz_uri; if( asprintf( &psz_uri, "file:%s", psz_path ) < 0 ) { free( psz_path ); i_ret = VLC_ENOMEM; break; } free( psz_path ); i_ret = vlc_readdir_helper_additem( &rdh, psz_uri, NULL, psz_name, ITEM_TYPE_DIRECTORY, ITEM_NET ); free( psz_uri ); } } NetApiBufferFree( p_info ); } while( i_share_enum_res == ERROR_MORE_DATA && i_ret == VLC_SUCCESS ); free( wpsz_host ); #endif vlc_readdir_helper_finish( &rdh, i_ret == VLC_SUCCESS ); return i_ret; }
static int DirRead(stream_t *p_access, input_item_node_t *p_node) { access_sys_t *p_sys = p_access->p_sys; int i_ret = VLC_SUCCESS; struct vlc_readdir_helper rdh; vlc_readdir_helper_init( &rdh, p_access, p_node ); // Handle share listing from here. Directory browsing is handled by the // usual filesystem module. SHARE_INFO_1 *p_info; DWORD i_share_enum_res; DWORD i_nb_elem; DWORD i_resume_handle = 0; DWORD i_total_elements; // Unused, but needs to be passed wchar_t *wpsz_host = ToWide( p_sys->url.psz_host ); if( wpsz_host == NULL ) return VLC_ENOMEM; do { i_share_enum_res = NetShareEnum( wpsz_host, 1, (LPBYTE*)&p_info, MAX_PREFERRED_LENGTH, &i_nb_elem, &i_total_elements, &i_resume_handle ); if( i_share_enum_res == ERROR_SUCCESS || i_share_enum_res == ERROR_MORE_DATA ) { for ( DWORD i = 0; i < i_nb_elem; ++i ) { SHARE_INFO_1 *p_current = p_info + i; if( p_current->shi1_type & STYPE_SPECIAL ) continue; char* psz_name = FromWide( p_current->shi1_netname ); if( psz_name == NULL ) { i_ret = VLC_ENOMEM; break; } char* psz_path; if( smb_get_uri( p_access, &psz_path, NULL, NULL, NULL, p_sys->url.psz_host, p_sys->url.psz_path, psz_name ) < 0 ) { free( psz_name ); i_ret = VLC_ENOMEM; break; } // We need to concatenate the scheme before, as the window version // of smb_get_uri generates a path (and the other call site needs // a path). The path is already prefixed by "//" so we just need // to add "file:" char* psz_uri; if( asprintf( &psz_uri, "file:%s", psz_path ) < 0 ) { free( psz_name ); free( psz_path ); i_ret = VLC_ENOMEM; break; } free( psz_path ); i_ret = vlc_readdir_helper_additem( &rdh, psz_uri, NULL, psz_name, ITEM_TYPE_DIRECTORY, ITEM_NET ); free( psz_name ); free( psz_uri ); } } NetApiBufferFree( p_info ); } while( i_share_enum_res == ERROR_MORE_DATA && i_ret == VLC_SUCCESS ); free( wpsz_host ); vlc_readdir_helper_finish( &rdh, i_ret == VLC_SUCCESS ); return i_ret; }