Commit 69ae80b5 authored by Thomas Guillem's avatar Thomas Guillem

smb: use vlc_UrlParse to parse url

parent aa599c4b
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
# include "config.h" # include "config.h"
#endif #endif
#include <assert.h>
#include <errno.h> #include <errno.h>
#ifdef _WIN32 #ifdef _WIN32
# include <fcntl.h> # include <fcntl.h>
...@@ -47,6 +48,7 @@ ...@@ -47,6 +48,7 @@
#include <vlc_plugin.h> #include <vlc_plugin.h>
#include <vlc_access.h> #include <vlc_access.h>
#include <vlc_input_item.h> #include <vlc_input_item.h>
#include <vlc_url.h>
#include "smb_common.h" #include "smb_common.h"
...@@ -89,10 +91,11 @@ struct access_sys_t ...@@ -89,10 +91,11 @@ struct access_sys_t
{ {
int i_smb; int i_smb;
uint64_t size; uint64_t size;
vlc_url_t url;
}; };
#ifdef _WIN32 #ifdef _WIN32
static void Win32AddConnection( access_t *, char *, char *, char *, char * ); static void Win32AddConnection( access_t *, const char *, const char *, const char *, const char *, const char * );
#else #else
static void smb_auth( const char *srv, const char *shr, char *wg, int wglen, static void smb_auth( const char *srv, const char *shr, char *wg, int wglen,
char *un, int unlen, char *pw, int pwlen ) char *un, int unlen, char *pw, int pwlen )
...@@ -114,24 +117,29 @@ static void smb_auth( const char *srv, const char *shr, char *wg, int wglen, ...@@ -114,24 +117,29 @@ static void smb_auth( const char *srv, const char *shr, char *wg, int wglen,
static int smb_get_uri( access_t *p_access, char **ppsz_uri, static int smb_get_uri( access_t *p_access, char **ppsz_uri,
const char *psz_domain, const char *psz_domain,
const char *psz_user, const char *psz_pwd, const char *psz_user, const char *psz_pwd,
const char *psz_location, const char *psz_name ) const char *psz_server, const char *psz_share_path,
const char *psz_name )
{ {
assert(psz_server);
#define PSZ_SHARE_PATH_OR_NULL psz_share_path ? psz_share_path : ""
#define PSZ_NAME_OR_NULL psz_name ? "/" : "", psz_name ? psz_name : "" #define PSZ_NAME_OR_NULL psz_name ? "/" : "", psz_name ? psz_name : ""
#ifdef _WIN32 #ifdef _WIN32
if( psz_user ) if( psz_user )
Win32AddConnection( p_access, psz_location, psz_user, psz_pwd, psz_domain); Win32AddConnection( p_access, psz_server, psz_share_path,
return asprintf( ppsz_uri, "//%s%s%s", psz_location, PSZ_NAME_OR_NULL ); psz_user, psz_pwd, psz_domain );
return asprintf( ppsz_uri, "//%s%s%s%s", psz_server, PSZ_SHARE_PATH_OR_NULL,
PSZ_NAME_OR_NULL );
#else #else
(void) p_access; (void) p_access;
if( psz_user ) if( psz_user )
return asprintf( ppsz_uri, "smb://%s%s%s%s%s@%s%s%s", return asprintf( ppsz_uri, "smb://%s%s%s%s%s@%s%s%s%s",
psz_domain ? psz_domain : "", psz_domain ? ";" : "", psz_domain ? psz_domain : "", psz_domain ? ";" : "",
psz_user, psz_pwd ? ":" : "", psz_user, psz_pwd ? ":" : "",
psz_pwd ? psz_pwd : "", psz_location, psz_pwd ? psz_pwd : "", psz_server,
PSZ_NAME_OR_NULL ); PSZ_SHARE_PATH_OR_NULL, PSZ_NAME_OR_NULL );
else else
return asprintf( ppsz_uri, "smb://%s%s%s", psz_location, return asprintf( ppsz_uri, "smb://%s%s%s%s", psz_server,
PSZ_NAME_OR_NULL ); PSZ_SHARE_PATH_OR_NULL, PSZ_NAME_OR_NULL );
#endif #endif
} }
...@@ -143,7 +151,8 @@ static int Open( vlc_object_t *p_this ) ...@@ -143,7 +151,8 @@ static int Open( vlc_object_t *p_this )
access_t *p_access = (access_t*)p_this; access_t *p_access = (access_t*)p_this;
access_sys_t *p_sys; access_sys_t *p_sys;
struct stat filestat; struct stat filestat;
char *psz_location, *psz_uri = NULL; vlc_url_t url;
char *psz_uri = NULL;
char *psz_user = NULL, *psz_pwd = NULL, *psz_domain = NULL; char *psz_user = NULL, *psz_pwd = NULL, *psz_domain = NULL;
int i_ret; int i_ret;
int i_smb; int i_smb;
...@@ -153,43 +162,20 @@ static int Open( vlc_object_t *p_this ) ...@@ -153,43 +162,20 @@ static int Open( vlc_object_t *p_this )
* [[[domain;]user[:password@]]server[/share[/path[/file]]]] * [[[domain;]user[:password@]]server[/share[/path[/file]]]]
* No need to search a user/pwd if there is no '/', indeed, user/pwd are * No need to search a user/pwd if there is no '/', indeed, user/pwd are
* set for a FILE_SHARE. */ * set for a FILE_SHARE. */
vlc_UrlParse( &url, p_access->psz_location );
psz_location = strchr( p_access->psz_location, '/' ); if( url.psz_username )
if( psz_location )
{ {
char *psz_tmp = strdup( p_access->psz_location ); char *psz_delim = strchr( url.psz_username, ';' );
char *psz_parser; if( psz_delim )
psz_tmp[ psz_location - p_access->psz_location ] = 0;
psz_location = p_access->psz_location;
psz_parser = strchr( psz_tmp, '@' );
if( psz_parser )
{ {
/* User info is there */ *psz_delim = '\0';
*psz_parser = 0; psz_user = strdup(psz_delim + 1);
psz_location = p_access->psz_location + (psz_parser - psz_tmp) + 1; psz_domain = strdup(url.psz_username);
psz_parser = strchr( psz_tmp, ':' );
if( psz_parser )
{
/* Password found */
psz_pwd = strdup( psz_parser+1 );
*psz_parser = 0;
} }
else
psz_parser = strchr( psz_tmp, ';' ); psz_user = strdup(url.psz_username);
if( psz_parser )
{
/* Domain found */
*psz_parser = 0; psz_parser++;
psz_domain = strdup( psz_tmp );
}
else psz_parser = psz_tmp;
psz_user = strdup( psz_parser );
} }
psz_pwd = url.psz_password ? strdup(url.psz_password) : NULL;
free( psz_tmp );
if( !psz_user ) psz_user = var_InheritString( p_access, "smb-user" ); if( !psz_user ) psz_user = var_InheritString( p_access, "smb-user" );
if( psz_user && !*psz_user ) { free( psz_user ); psz_user = NULL; } if( psz_user && !*psz_user ) { free( psz_user ); psz_user = NULL; }
...@@ -197,23 +183,25 @@ static int Open( vlc_object_t *p_this ) ...@@ -197,23 +183,25 @@ static int Open( vlc_object_t *p_this )
if( psz_pwd && !*psz_pwd ) { free( psz_pwd ); psz_pwd = NULL; } if( psz_pwd && !*psz_pwd ) { free( psz_pwd ); psz_pwd = NULL; }
if( !psz_domain ) psz_domain = var_InheritString( p_access, "smb-domain" ); if( !psz_domain ) psz_domain = var_InheritString( p_access, "smb-domain" );
if( psz_domain && !*psz_domain ) { free( psz_domain ); psz_domain = NULL; } if( psz_domain && !*psz_domain ) { free( psz_domain ); psz_domain = NULL; }
} else
psz_location = p_access->psz_location;
i_ret = smb_get_uri( p_access, &psz_uri, psz_domain, psz_user, psz_pwd, i_ret = smb_get_uri( p_access, &psz_uri, psz_domain, psz_user, psz_pwd,
psz_location, NULL ); url.psz_host, url.psz_path, NULL );
free( psz_user ); free( psz_user );
free( psz_pwd ); free( psz_pwd );
free( psz_domain ); free( psz_domain );
if( i_ret == -1 ) if( i_ret == -1 )
{
vlc_UrlClean( &url );
return VLC_ENOMEM; return VLC_ENOMEM;
}
#ifndef _WIN32 #ifndef _WIN32
if( smbc_init( smb_auth, 0 ) ) if( smbc_init( smb_auth, 0 ) )
{ {
free( psz_uri ); free( psz_uri );
vlc_UrlClean( &url );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
#endif #endif
...@@ -234,8 +222,10 @@ static int Open( vlc_object_t *p_this ) ...@@ -234,8 +222,10 @@ static int Open( vlc_object_t *p_this )
if( !p_sys ) if( !p_sys )
{ {
free( psz_uri ); free( psz_uri );
vlc_UrlClean( &url );
return VLC_ENOMEM; return VLC_ENOMEM;
} }
p_sys->url = url;
i_ret = smbc_stat( psz_uri, &filestat ); i_ret = smbc_stat( psz_uri, &filestat );
...@@ -243,6 +233,9 @@ static int Open( vlc_object_t *p_this ) ...@@ -243,6 +233,9 @@ static int Open( vlc_object_t *p_this )
if( i_ret || S_ISDIR( filestat.st_mode ) ) if( i_ret || S_ISDIR( filestat.st_mode ) )
{ {
#ifdef _WIN32 #ifdef _WIN32
free( p_sys );
free( psz_uri );
vlc_UrlClean( &p_sys->url );
return VLC_EGENERIC; return VLC_EGENERIC;
#else #else
p_access->pf_readdir = DirRead; p_access->pf_readdir = DirRead;
...@@ -264,6 +257,7 @@ static int Open( vlc_object_t *p_this ) ...@@ -264,6 +257,7 @@ static int Open( vlc_object_t *p_this )
msg_Err( p_access, "open failed for '%s' (%s)", msg_Err( p_access, "open failed for '%s' (%s)",
p_access->psz_location, vlc_strerror_c(errno) ); p_access->psz_location, vlc_strerror_c(errno) );
free( p_sys ); free( p_sys );
vlc_UrlClean( &p_sys->url );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
...@@ -281,6 +275,8 @@ static void Close( vlc_object_t *p_this ) ...@@ -281,6 +275,8 @@ static void Close( vlc_object_t *p_this )
access_t *p_access = (access_t*)p_this; access_t *p_access = (access_t*)p_this;
access_sys_t *p_sys = p_access->p_sys; access_sys_t *p_sys = p_access->p_sys;
vlc_UrlClean( &p_sys->url );
#ifndef _WIN32 #ifndef _WIN32
if( p_access->pf_readdir ) if( p_access->pf_readdir )
smbc_closedir( p_sys->i_smb ); smbc_closedir( p_sys->i_smb );
...@@ -350,7 +346,8 @@ static input_item_t* DirRead (access_t *p_access ) ...@@ -350,7 +346,8 @@ static input_item_t* DirRead (access_t *p_access )
while( !p_item && ( p_entry = smbc_readdir( p_sys->i_smb ) ) ) while( !p_item && ( p_entry = smbc_readdir( p_sys->i_smb ) ) )
{ {
char *psz_uri; char *psz_uri;
const char *psz_location = p_access->psz_location; const char *psz_server = p_sys->url.psz_host;
const char *psz_path = p_sys->url.psz_path;
const char *psz_name = p_entry->name; const char *psz_name = p_entry->name;
int i_type; int i_type;
...@@ -358,7 +355,8 @@ static input_item_t* DirRead (access_t *p_access ) ...@@ -358,7 +355,8 @@ static input_item_t* DirRead (access_t *p_access )
{ {
case SMBC_SERVER: case SMBC_SERVER:
case SMBC_WORKGROUP: case SMBC_WORKGROUP:
psz_location = p_entry->name; psz_server = p_sys->url.psz_host;
psz_path = NULL;
psz_name = NULL; psz_name = NULL;
case SMBC_FILE_SHARE: case SMBC_FILE_SHARE:
case SMBC_DIR: case SMBC_DIR:
...@@ -376,7 +374,7 @@ static input_item_t* DirRead (access_t *p_access ) ...@@ -376,7 +374,7 @@ static input_item_t* DirRead (access_t *p_access )
} }
if( smb_get_uri( p_access, &psz_uri, NULL, NULL, NULL, if( smb_get_uri( p_access, &psz_uri, NULL, NULL, NULL,
psz_location, psz_name ) < 0 ) psz_server, psz_path, psz_name ) < 0 )
return NULL; return NULL;
p_item = input_item_NewWithTypeExt( psz_uri, p_entry->name, 0, NULL, p_item = input_item_NewWithTypeExt( psz_uri, p_entry->name, 0, NULL,
...@@ -441,31 +439,29 @@ static int Control( access_t *p_access, int i_query, va_list args ) ...@@ -441,31 +439,29 @@ static int Control( access_t *p_access, int i_query, va_list args )
} }
#ifdef _WIN32 #ifdef _WIN32
static void Win32AddConnection( access_t *p_access, char *psz_path, static void Win32AddConnection( access_t *p_access, const char *psz_server,
char *psz_user, char *psz_pwd, const char *psz_share, const char *psz_user,
char *psz_domain ) const char *psz_pwd, const char *psz_domain )
{ {
char psz_remote[MAX_PATH], psz_server[MAX_PATH], psz_share[MAX_PATH]; char psz_remote[MAX_PATH];
NETRESOURCE net_resource; NETRESOURCE net_resource;
DWORD i_result; DWORD i_result;
char *psz_parser;
VLC_UNUSED( psz_domain ); VLC_UNUSED( psz_domain );
memset( &net_resource, 0, sizeof(net_resource) ); memset( &net_resource, 0, sizeof(net_resource) );
net_resource.dwType = RESOURCETYPE_DISK; net_resource.dwType = RESOURCETYPE_DISK;
/* Find out server and share names */ if (psz_share)
strlcpy( psz_server, psz_path, sizeof( psz_server ) ); psz_share = psz_share + 1; /* skip first '/' */
psz_share[0] = 0; else
psz_parser = strchr( psz_path, '/' ); psz_share = "";
if( psz_parser )
{
char *psz_parser2 = strchr( ++psz_parser, '/' );
if( psz_parser2 )
strlcpy( psz_share, psz_parser, sizeof( psz_share ) );
}
snprintf( psz_remote, sizeof( psz_remote ), "\\\\%s\\%s", psz_server, psz_share ); snprintf( psz_remote, sizeof( psz_remote ), "\\\\%s\\%s", psz_server, psz_share );
/* remove trailings '/' */
char *psz_delim = strchr( psz_remote, '/' );
if( psz_delim )
*psz_delim = '\0';
net_resource.lpRemoteName = psz_remote; net_resource.lpRemoteName = psz_remote;
i_result = WNetAddConnection2( &net_resource, psz_pwd, psz_user, 0 ); i_result = WNetAddConnection2( &net_resource, psz_pwd, psz_user, 0 );
......
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