+ if( net_GetPeerAddress( p_sys->fd_cmd, p_sys->sz_epsv_ip, NULL ) )
+ {
+ net_Close( p_sys->fd_cmd );
+ return -1;
+ }
+ }
+ else
+ {
+ /* If ESPV ALL fails, we fallback to PASV.
+ * We have to restart the connection in case there is a NAT that
+ * understands EPSV ALL in the way, and hence won't allow PASV on
+ * the initial connection.
+ */
+ msg_Info( p_access, "FTP Extended passive mode disabled" );
+ net_Close( p_sys->fd_cmd );
+
+ if( Login( p_access, p_sys ) )
+ {
+ net_Close( p_sys->fd_cmd );
+ return -1;
+ }
+ }
+
+ /* check binary mode support */
+ if( ftp_SendCommand( p_access, p_sys, "TYPE I" ) < 0 ||
+ ftp_ReadCommand( p_access, p_sys, NULL, NULL ) != 2 )
+ {
+ msg_Err( p_access, "cannot set binary transfer mode" );
+ net_Close( p_sys->fd_cmd );
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static int parseURL( vlc_url_t *url, const char *path )
+{
+ if( path == NULL )
+ return VLC_EGENERIC;
+
+ /* *** Parse URL and get server addr/port and path *** */
+ while( *path == '/' )
+ path++;
+
+ vlc_UrlParse( url, path, 0 );
+
+ if( url->psz_host == NULL || *url->psz_host == '\0' )
+ return VLC_EGENERIC;
+
+ if( url->i_port <= 0 )
+ url->i_port = IPPORT_FTP; /* default port */
+
+ if( url->psz_path == NULL )
+ return VLC_SUCCESS;
+ /* FTP URLs are relative to user's default directory (RFC1738 §3.2)
+ For absolute path use ftp://foo.bar//usr/local/etc/filename */
+ /* FIXME: we should issue a series of CWD, one per slash */
+ if( url->psz_path )
+ {
+ assert( url->psz_path[0] == '/' );
+ url->psz_path++;
+ }
+
+ char *type = strstr( url->psz_path, ";type=" );
+ if( type )
+ {
+ *type = '\0';
+ if( strchr( "iI", type[6] ) == NULL )
+ return VLC_EGENERIC; /* ASCII and directory not supported */
+ }
+ decode_URI( url->psz_path );
+ /* FIXME: check for UTF-8 support, otherwise only ASCII is allowed */
+ EnsureUTF8( url->psz_path );
+ return VLC_SUCCESS;
+}
+
+
+/****************************************************************************
+ * Open: connect to ftp server and ask for file
+ ****************************************************************************/
+static int InOpen( vlc_object_t *p_this )
+{
+ access_t *p_access = (access_t*)p_this;
+ access_sys_t *p_sys;
+ char *psz_arg;
+
+ /* Init p_access */
+ STANDARD_READ_ACCESS_INIT
+ p_sys->fd_data = -1;
+ p_sys->out = false;
+ p_sys->directory = false;
+
+ if( parseURL( &p_sys->url, p_access->psz_location ) )
+ goto exit_error;
+
+ if( Connect( p_this, p_sys ) )