[vlc-devel] [PATCH 2/3] ftp: implement readdir

Thomas Guillem thomas at gllm.fr
Sun May 3 19:36:30 CEST 2015


---
 modules/access/ftp.c | 129 +++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 93 insertions(+), 36 deletions(-)

diff --git a/modules/access/ftp.c b/modules/access/ftp.c
index fa22a20..e16a0c4 100644
--- a/modules/access/ftp.c
+++ b/modules/access/ftp.c
@@ -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,8 @@ 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 * );
+static int DirControl( access_t *, int, va_list );
 #ifdef ENABLE_SOUT
 static int OutSeek( sout_access_out_t *, off_t );
 static ssize_t Write( sout_access_out_t *, block_t * );
@@ -141,7 +144,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 +265,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 +616,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 +636,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 +657,20 @@ 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;
+        p_access->pf_control = DirControl;
+    }
+    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 +717,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 +784,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 +815,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 +823,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 +905,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* );
@@ -914,8 +942,37 @@ static int Control( access_t *p_access, int i_query, va_list args )
     return VLC_SUCCESS;
 }
 
+/*****************************************************************************
+ * DirControl:
+ *****************************************************************************/
+static int DirControl( access_t *p_access, int i_query, va_list args )
+{
+    VLC_UNUSED( p_access );
+
+    switch( i_query )
+    {
+    case ACCESS_CAN_SEEK:
+    case ACCESS_CAN_FASTSEEK:
+        *va_arg( args, bool* ) = false;
+        break;
+
+    case ACCESS_CAN_PAUSE:
+    case ACCESS_CAN_CONTROL_PACE:
+        *va_arg( args, bool* ) = true;
+        break;
+
+    case ACCESS_GET_PTS_DELAY:
+        *va_arg( args, int64_t * ) = DEFAULT_PTS_DELAY * 1000;
+        break;
+
+    default:
+        return VLC_EGENERIC;
+    }
+    return VLC_SUCCESS;
+}
+
 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 +1056,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 )
-- 
2.1.4




More information about the vlc-devel mailing list