Commit eba42da6 authored by Thomas Guillem's avatar Thomas Guillem

ftp: implement readdir

parent 54551b5c
......@@ -37,6 +37,7 @@
#include <vlc_access.h>
#include <vlc_dialog.h>
#include <vlc_input_item.h>
#include <vlc_network.h>
#include <vlc_url.h>
......@@ -105,6 +106,7 @@ vlc_module_end ()
static ssize_t Read( access_t *, uint8_t *, size_t );
static int Seek( access_t *, uint64_t );
static int Control( access_t *, int, va_list );
static int DirRead( access_t *, input_item_node_t * );
#ifdef ENABLE_SOUT
static int OutSeek( sout_access_out_t *, off_t );
static ssize_t Write( sout_access_out_t *, block_t * );
......@@ -141,7 +143,6 @@ struct access_sys_t
char sz_epsv_ip[NI_MAXNUMERICHOST];
bool out;
bool directory;
uint64_t size;
};
#define GET_OUT_SYS( p_this ) \
......@@ -263,7 +264,7 @@ static int ftp_RecvCommand( vlc_object_t *obj, access_sys_t *sys,
return ftp_RecvAnswer( obj, sys, codep, strp, DummyLine, NULL );
}
static int ftp_StartStream( vlc_object_t *, access_sys_t *, uint64_t );
static int ftp_StartStream( vlc_object_t *, access_sys_t *, uint64_t, bool );
static int ftp_StopStream ( vlc_object_t *, access_sys_t * );
static void readTLSMode( access_sys_t *p_sys, const char * psz_access )
......@@ -614,12 +615,15 @@ static int InOpen( vlc_object_t *p_this )
access_t *p_access = (access_t*)p_this;
access_sys_t *p_sys;
char *psz_arg;
bool b_directory = false;
/* Init p_access */
STANDARD_READ_ACCESS_INIT
access_InitFields( p_access );
p_sys = p_access->p_sys = (access_sys_t*)calloc( 1, sizeof( access_sys_t ) );
if( !p_sys )
return VLC_ENOMEM;
p_sys->data.fd = -1;
p_sys->out = false;
p_sys->directory = false;
p_sys->size = 0;
readTLSMode( p_sys, p_access->psz_access );
......@@ -631,7 +635,7 @@ static int InOpen( vlc_object_t *p_this )
/* get size */
if( p_sys->url.psz_path == NULL )
p_sys->directory = true;
b_directory = true;
else
if( ftp_SendCommand( p_this, p_sys, "SIZE %s", p_sys->url.psz_path ) < 0 )
goto error;
......@@ -652,10 +656,15 @@ static int InOpen( vlc_object_t *p_this )
goto error;
}
else
p_sys->directory = true;
b_directory = true;
if( b_directory )
p_access->pf_readdir = DirRead;
else
ACCESS_SET_CALLBACKS( Read, NULL, Control, Seek ); \
/* Start the 'stream' */
if( ftp_StartStream( p_this, p_sys, 0 ) < 0 )
if( ftp_StartStream( p_this, p_sys, 0, b_directory ) < 0 )
{
msg_Err( p_this, "cannot retrieve file" );
clearCmdTLS( p_sys );
......@@ -702,7 +711,7 @@ static int OutOpen( vlc_object_t *p_this )
goto exit_error;
/* Start the 'stream' */
if( ftp_StartStream( p_this, p_sys, 0 ) < 0 )
if( ftp_StartStream( p_this, p_sys, 0, false ) < 0 )
{
msg_Err( p_access, "cannot store file" );
clearCmdTLS( p_sys );
......@@ -769,7 +778,7 @@ static int _Seek( vlc_object_t *p_access, access_sys_t *p_sys, uint64_t i_pos )
msg_Dbg( p_access, "seeking to %"PRIu64, i_pos );
ftp_StopStream( (vlc_object_t *)p_access, p_sys );
if( ftp_StartStream( (vlc_object_t *)p_access, p_sys, i_pos ) < 0 )
if( ftp_StartStream( (vlc_object_t *)p_access, p_sys, i_pos, false ) < 0 )
return VLC_EGENERIC;
return VLC_SUCCESS;
......@@ -800,6 +809,7 @@ static int OutSeek( sout_access_out_t *p_access, off_t i_pos )
static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
{
access_sys_t *p_sys = p_access->p_sys;
int i_read;
assert( p_sys->data.fd != -1 );
assert( !p_sys->out );
......@@ -807,36 +817,48 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
if( p_access->info.b_eof )
return 0;
if( p_sys->directory )
i_read = net_Read( p_access, p_sys->data.fd, p_sys->data.p_vs,
p_buffer, i_len, false );
if( i_read == 0 )
p_access->info.b_eof = true;
else if( i_read > 0 )
p_access->info.i_pos += i_read;
return i_read;
}
/*****************************************************************************
* DirRead:
*****************************************************************************/
static int DirRead (access_t *p_access, input_item_node_t *p_current_node)
{
access_sys_t *p_sys = p_access->p_sys;
char *psz_line;
assert( p_sys->data.fd != -1 );
assert( !p_sys->out );
while( ( psz_line = net_Gets( p_access, p_sys->data.fd, p_sys->data.p_vs ) ) )
{
char *psz_line = net_Gets( p_access, p_sys->data.fd, p_sys->data.p_vs );
if( !psz_line )
{
p_access->info.b_eof = true;
return 0;
}
else
{
snprintf( (char*)p_buffer, i_len, "%s://%s:%d/%s/%s\n",
char *psz_uri;
if( asprintf( &psz_uri, "%s://%s:%d/%s/%s",
( p_sys->tlsmode == NONE ) ? "ftp" :
( ( p_sys->tlsmode == IMPLICIT ) ? "ftps" : "ftpes" ),
p_sys->url.psz_host, p_sys->url.i_port,
p_sys->url.psz_path, psz_line );
free( psz_line );
return strlen( (const char *)p_buffer );
p_sys->url.psz_path, psz_line ) != -1 )
{
input_item_t *p_item;
p_item = input_item_NewWithTypeExt( psz_uri, psz_line, 0, NULL,
0, -1, ITEM_TYPE_UNKNOWN, 1 );
input_item_CopyOptions( p_current_node->p_item, p_item );
input_item_node_AppendItem( p_current_node, p_item );
free( psz_uri );
}
free( psz_line );
}
else
{
int i_read = net_Read( p_access, p_sys->data.fd, p_sys->data.p_vs,
p_buffer, i_len, false );
if( i_read == 0 )
p_access->info.b_eof = true;
else if( i_read > 0 )
p_access->info.i_pos += i_read;
return i_read;
}
return VLC_SUCCESS;
}
/*****************************************************************************
......@@ -877,7 +899,7 @@ static int Control( access_t *p_access, int i_query, va_list args )
{
case ACCESS_CAN_SEEK:
pb_bool = (bool*)va_arg( args, bool* );
*pb_bool = !p_access->p_sys->directory;
*pb_bool = true;
break;
case ACCESS_CAN_FASTSEEK:
pb_bool = (bool*)va_arg( args, bool* );
......@@ -915,7 +937,7 @@ static int Control( access_t *p_access, int i_query, va_list args )
}
static int ftp_StartStream( vlc_object_t *p_access, access_sys_t *p_sys,
uint64_t i_start )
uint64_t i_start, bool b_directory )
{
char psz_ipv4[16], *psz_ip = p_sys->sz_epsv_ip;
int i_answer;
......@@ -999,7 +1021,7 @@ static int ftp_StartStream( vlc_object_t *p_access, access_sys_t *p_sys,
msg_Dbg( p_access, "connection with \"%s:%d\" successful",
psz_ip, i_port );
if( p_sys->directory )
if( b_directory )
{
if( ftp_SendCommand( p_access, p_sys, "NLST" ) < 0 ||
ftp_RecvCommand( p_access, p_sys, NULL, &psz_arg ) > 2 )
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment