/***************************************************************************** * Control: *****************************************************************************/ static int Control( access_t *p_access, int i_query, va_list args ) { switch( i_query ) { case ACCESS_CAN_SEEK: case ACCESS_CAN_FASTSEEK: case ACCESS_CAN_PAUSE: case ACCESS_CAN_CONTROL_PACE: *va_arg( args, bool* ) = true; break; case ACCESS_GET_SIZE: { smb_stat st = smb_stat_fd( p_access->p_sys->p_session, p_access->p_sys->i_fd ); *va_arg( args, uint64_t * ) = smb_stat_get( st, SMB_STAT_SIZE ); break; } case ACCESS_GET_PTS_DELAY: *va_arg( args, int64_t * ) = INT64_C(1000) * var_InheritInteger( p_access, "network-caching" ); break; case ACCESS_SET_PAUSE_STATE: /* Nothing to do */ break; default: return VLC_EGENERIC; } return VLC_SUCCESS; }
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 input_item_t* BrowseDirectory( access_t *p_access ) { access_sys_t *p_sys = p_access->p_sys; smb_stat st; input_item_t *p_item = NULL; char *psz_query; const char *psz_name; int i_ret; if( !p_sys->i_browse_count ) { if( p_sys->psz_path != NULL ) { i_ret = asprintf( &psz_query, "%s\\*", p_sys->psz_path ); if( i_ret == -1 ) return NULL; p_sys->files = smb_find( p_sys->p_session, p_sys->i_tid, psz_query ); free( psz_query ); } else p_sys->files = smb_find( p_sys->p_session, p_sys->i_tid, "\\*" ); if( p_sys->files == NULL ) return NULL; p_sys->i_browse_count = smb_stat_list_count( p_sys->files ); } if( p_sys->i_browse_idx < p_sys->i_browse_count ) { int i_type; st = smb_stat_list_at( p_sys->files, p_sys->i_browse_idx++ ); if( st == NULL ) return NULL; psz_name = smb_stat_name( st ); i_type = smb_stat_get( st, SMB_STAT_ISDIR ) ? ITEM_TYPE_DIRECTORY : ITEM_TYPE_FILE; p_item = new_item( p_access, psz_name, i_type ); if( !p_item ) return NULL; } return p_item; }
/***************************************************************************** * Control: *****************************************************************************/ static int Control( stream_t *p_access, int i_query, va_list args ) { access_sys_t *p_sys = p_access->p_sys; switch( i_query ) { case STREAM_CAN_SEEK: case STREAM_CAN_PAUSE: case STREAM_CAN_CONTROL_PACE: *va_arg( args, bool* ) = true; break; case STREAM_CAN_FASTSEEK: *va_arg( args, bool* ) = false; break; case STREAM_GET_SIZE: { smb_stat st = smb_stat_fd( p_sys->p_session, p_sys->i_fd ); *va_arg( args, uint64_t * ) = smb_stat_get( st, SMB_STAT_SIZE ); break; } case STREAM_GET_PTS_DELAY: *va_arg( args, vlc_tick_t * ) = VLC_TICK_FROM_MS( var_InheritInteger( p_access, "network-caching" ) ); break; case STREAM_SET_PAUSE_STATE: /* Nothing to do */ break; default: return VLC_EGENERIC; } return VLC_SUCCESS; }
/***************************************************************************** * Open: Initialize module's data structures and libdsm *****************************************************************************/ static int Open( vlc_object_t *p_this ) { stream_t *p_access = (stream_t*)p_this; access_sys_t *p_sys; smb_stat st; /* Init p_access */ p_sys = p_access->p_sys = (access_sys_t*)calloc( 1, sizeof( access_sys_t ) ); if( p_access->p_sys == NULL ) return VLC_ENOMEM; p_sys->p_ns = netbios_ns_new(); if( p_sys->p_ns == NULL ) goto error; p_sys->p_session = smb_session_new(); if( p_sys->p_session == NULL ) goto error; if( vlc_UrlParseFixup( &p_sys->url, p_access->psz_url ) != 0 ) goto error; if( get_address( p_access ) != VLC_SUCCESS ) goto error; msg_Dbg( p_access, "Session: Host name = %s, ip = %s", p_sys->netbios_name, inet_ntoa( p_sys->addr ) ); /* Now that we have the required data, let's establish a session */ if( smb_session_connect( p_sys->p_session, p_sys->netbios_name, p_sys->addr.s_addr, SMB_TRANSPORT_TCP ) != DSM_SUCCESS ) { msg_Err( p_access, "Unable to connect/negotiate SMB session"); goto error; } get_path( p_access ); if( login( p_access ) != VLC_SUCCESS ) { msg_Err( p_access, "Unable to open file with path %s (in share %s)", p_sys->psz_path, p_sys->psz_share ); goto error; } /* If there is no shares, browse them */ if( !p_sys->psz_share ) return BrowserInit( p_access ); assert(p_sys->i_fd > 0); msg_Dbg( p_access, "Path: Share name = %s, path = %s", p_sys->psz_share, p_sys->psz_path ); st = smb_stat_fd( p_sys->p_session, p_sys->i_fd ); if( smb_stat_get( st, SMB_STAT_ISDIR ) ) { smb_fclose( p_sys->p_session, p_sys->i_fd ); return BrowserInit( p_access ); } msg_Dbg( p_access, "Successfully opened smb://%s", p_access->psz_location ); ACCESS_SET_CALLBACKS( Read, NULL, Control, Seek ); return VLC_SUCCESS; error: Close( p_this ); return VLC_EGENERIC; }