dvb: don't preparse
[vlc.git] / modules / access / smb.c
index e88946c..e5ebb4f 100644 (file)
@@ -84,7 +84,7 @@ 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 );
 #ifndef _WIN32
-static input_item_t* DirRead( access_t * );
+static int DirRead( access_t *, input_item_node_t * );
 static int DirControl( access_t *, int, va_list );
 #endif
 
@@ -154,7 +154,8 @@ static int Open( vlc_object_t *p_this )
     struct stat  filestat;
     vlc_url_t    url;
     vlc_credential credential;
-    char         *psz_uri = NULL, *psz_var_domain = NULL;
+    char         *psz_decoded_path = NULL, *psz_uri = NULL,
+                 *psz_var_domain = NULL;
     int          i_ret;
     int          i_smb;
     uint64_t     i_size;
@@ -174,11 +175,17 @@ static int Open( vlc_object_t *p_this )
 # undef open
 #endif
 
-    char *psz_decoded_url = vlc_uri_decode_duplicate( p_access->psz_url );
-    if( psz_decoded_url == NULL )
-        return VLC_ENOMEM;
-    vlc_UrlParse( &url, psz_decoded_url );
-    free( psz_decoded_url );
+    vlc_UrlParse( &url, p_access->psz_url );
+    if( url.psz_path )
+    {
+        psz_decoded_path = vlc_uri_decode_duplicate( url.psz_path );
+        if( !psz_decoded_path )
+        {
+            vlc_UrlClean( &url );
+            return VLC_EGENERIC;
+        }
+    }
+
     vlc_credential_init( &credential, &url );
     psz_var_domain = var_InheritString( p_access, "smb-domain" );
     credential.psz_realm = psz_var_domain;
@@ -188,10 +195,11 @@ static int Open( vlc_object_t *p_this )
     {
         if( smb_get_uri( p_access, &psz_uri, credential.psz_realm,
                          credential.psz_username, credential.psz_password,
-                         url.psz_host, url.psz_path, NULL ) == -1 )
+                         url.psz_host, psz_decoded_path, NULL ) == -1 )
         {
             vlc_credential_clean( &credential );
             free(psz_var_domain);
+            free( psz_decoded_path );
             vlc_UrlClean( &url );
             return VLC_ENOMEM;
         }
@@ -211,10 +219,10 @@ static int Open( vlc_object_t *p_this )
         break;
     }
 
-    vlc_credential_store( &credential );
+    vlc_credential_store( &credential, p_access );
     vlc_credential_clean( &credential );
     free(psz_var_domain);
-    vlc_UrlClean( &url );
+    free( psz_decoded_path );
 
     /* Init p_access */
     access_InitFields( p_access );
@@ -223,6 +231,7 @@ static int Open( vlc_object_t *p_this )
     if( !p_sys )
     {
         free( psz_uri );
+        vlc_UrlClean( &url );
         return VLC_ENOMEM;
     }
 
@@ -231,9 +240,10 @@ static int Open( vlc_object_t *p_this )
 #ifdef _WIN32
         free( p_sys );
         free( psz_uri );
+        vlc_UrlClean( &url );
         return VLC_EGENERIC;
 #else
-        vlc_UrlParse( &p_sys->url, p_access->psz_url );
+        p_sys->url = url;
         p_access->pf_readdir = DirRead;
         p_access->pf_control = DirControl;
         i_smb = smbc_opendir( psz_uri );
@@ -252,8 +262,8 @@ static int Open( vlc_object_t *p_this )
     {
         msg_Err( p_access, "open failed for '%s' (%s)",
                  p_access->psz_location, vlc_strerror_c(errno) );
-        free( p_sys );
         vlc_UrlClean( &p_sys->url );
+        free( p_sys );
         return VLC_EGENERIC;
     }
 
@@ -279,6 +289,7 @@ static void Close( vlc_object_t *p_this )
     else
 #endif
         smbc_close( p_sys->i_smb );
+    free( p_sys );
 }
 
 /*****************************************************************************
@@ -333,13 +344,16 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
 /*****************************************************************************
  * DirRead:
  *****************************************************************************/
-static input_item_t* DirRead (access_t *p_access )
+static int DirRead (access_t *p_access, input_item_node_t *p_node )
 {
     access_sys_t *p_sys = p_access->p_sys;
     struct smbc_dirent *p_entry;
-    input_item_t *p_item = NULL;
+    int i_ret = VLC_SUCCESS;
+
+    struct access_fsdir fsdir;
+    access_fsdir_init( &fsdir, p_access, p_node );
 
-    while( !p_item && ( p_entry = smbc_readdir( p_sys->i_smb ) ) )
+    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;
@@ -372,22 +386,26 @@ static input_item_t* DirRead (access_t *p_access )
         char *psz_encoded_name = NULL;
         if( psz_name != NULL
          && ( psz_encoded_name = vlc_uri_encode( psz_name ) ) == NULL )
-            return 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);
-            return NULL;
+            i_ret = VLC_ENOMEM;
+            break;
         }
         free(psz_encoded_name);
-
-        p_item = input_item_NewWithTypeExt( psz_uri, p_entry->name, 0, NULL,
-                                            0, -1, i_type, 1 );
+        i_ret = access_fsdir_additem( &fsdir, psz_uri, p_entry->name,
+                                      i_type, ITEM_NET );
         free( psz_uri );
-        if( !p_item )
-            return NULL;
     }
-    return p_item;
+
+    access_fsdir_finish( &fsdir, i_ret == VLC_SUCCESS );
+
+    return i_ret;
 }
 
 static int DirControl( access_t *p_access, int i_query, va_list args )
@@ -395,7 +413,6 @@ static int DirControl( access_t *p_access, int i_query, va_list args )
     switch( i_query )
     {
     case ACCESS_IS_DIRECTORY:
-        *va_arg( args, bool * ) = false; /* is not sorted */
         *va_arg( args, bool * ) = true; /* might loop */
         break;
     default:
@@ -414,12 +431,15 @@ 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_CAN_FASTSEEK:
+        *va_arg( args, bool* ) = false;
+        break;
+
     case ACCESS_GET_SIZE:
         if( p_access->pf_readdir != NULL )
             return VLC_EGENERIC;