예제 #1
0
파일: keystore.c 프로젝트: mstorsjo/vlc
static vlc_keystore_entry *
find_closest_path(vlc_keystore_entry *p_entries, unsigned i_count,
                  const char *psz_path)
{
    vlc_keystore_entry *p_match_entry = NULL;
    size_t i_last_pathlen = 0;
    char *psz_decoded_path = vlc_uri_decode_duplicate(psz_path);
    if (psz_decoded_path == NULL)
        return NULL;

    /* Try to find the entry that has the closest path to psz_url */
    for (unsigned int i = 0; i < i_count; ++i)
    {
        vlc_keystore_entry *p_entry = &p_entries[i];
        const char *psz_entry_path = p_entry->ppsz_values[KEY_PATH];
        if (psz_entry_path == NULL)
        {
            if (p_match_entry == NULL)
                p_match_entry = p_entry;
            continue;
        }
        size_t i_entry_pathlen = strlen(psz_entry_path);

        if (strncasecmp(psz_decoded_path, psz_entry_path, i_entry_pathlen) == 0
         && i_entry_pathlen > i_last_pathlen)
        {
            i_last_pathlen = i_entry_pathlen;
            p_match_entry = p_entry;
        }
    }
    free(psz_decoded_path);
    return p_match_entry;
}
예제 #2
0
파일: access.c 프로젝트: mstorsjo/vlc
/* Get the share and filepath from uri (also replace all / by \ in url.psz_path) */
static bool get_path( stream_t *p_access )
{
    access_sys_t *p_sys = p_access->p_sys;
    char *iter;

    if( p_sys->url.psz_path == NULL )
        return false;

    p_sys->psz_fullpath = vlc_uri_decode_duplicate( p_sys->url.psz_path );
    if( p_sys->psz_fullpath == NULL )
        return false;

    backslash_path( p_sys->psz_fullpath );

    /* Is path longer than just "/" ? */
    if( strlen( p_sys->psz_fullpath ) > 1 )
    {
        iter = p_sys->psz_fullpath;
        while( *iter == '\\' ) iter++; /* Handle smb://Host/////Share/ */

        p_sys->psz_share = iter;
    }
    else
    {
        msg_Dbg( p_access, "no share, nor file path provided, will switch to browser");
        return false;
    }

    iter = strchr( p_sys->psz_share, '\\' );
    if( iter == NULL || strlen(iter + 1) == 0 )
    {
        if( iter != NULL ) /* Remove the trailing \ */
            *iter = '\0';
        p_sys->psz_path = "";

        msg_Dbg( p_access, "no file path provided, will switch to browser ");
        return true;
    }

    p_sys->psz_path = iter + 1; /* Skip the first \ */
    *iter = '\0';

    return true;
}
예제 #3
0
파일: nfs.c 프로젝트: BossKing/vlc
static int
Open(vlc_object_t *p_obj)
{
    access_t *p_access = (access_t *)p_obj;
    access_sys_t *p_sys = calloc(1, sizeof (*p_sys));

    if (unlikely(p_sys == NULL))
        goto error;
    p_access->p_sys = p_sys;

    p_sys->b_auto_guid = var_InheritBool(p_obj, "nfs-auto-guid");

    /* nfs_* functions need a decoded url */
    p_sys->psz_url_decoded = vlc_uri_decode_duplicate(p_access->psz_url);
    if (p_sys->psz_url_decoded == NULL)
        goto error;

    /* Parse the encoded URL */
    vlc_UrlParse(&p_sys->encoded_url, p_access->psz_url);
    if (p_sys->encoded_url.psz_option)
    {
        if (strstr(p_sys->encoded_url.psz_option, "uid")
         || strstr(p_sys->encoded_url.psz_option, "gid"))
            p_sys->b_auto_guid = false;
    }

    if (NfsInit(p_access, p_sys->psz_url_decoded) == -1)
        goto error;

    if (p_sys->p_nfs_url->path != NULL && p_sys->p_nfs_url->file != NULL)
    {
        /* The url has a valid path and file, mount the path and open/opendir
         * the file */
        msg_Dbg(p_access, "nfs_mount: server: '%s', path: '%s'",
                p_sys->p_nfs_url->server, p_sys->p_nfs_url->path);

        if (nfs_mount_async(p_sys->p_nfs, p_sys->p_nfs_url->server,
                            p_sys->p_nfs_url->path, nfs_mount_cb, p_access) < 0)
        {
            msg_Err(p_access, "nfs_mount_async failed");
            goto error;
        }

        if (vlc_nfs_mainloop(p_access, nfs_mount_open_finished_cb) < 0)
            goto error;

        if (p_sys->psz_url_decoded_slash != NULL)
        {
            /* Retry to mount by adding a '/' to the path, see comment in
             * nfs_mount_cb */
            nfs_destroy_url(p_sys->p_nfs_url);
            nfs_destroy_context(p_sys->p_nfs);
            p_sys->p_nfs_url = NULL;
            p_sys->p_nfs = NULL;

            if (NfsInit(p_access, p_sys->psz_url_decoded_slash) == -1
             || p_sys->p_nfs_url->path == NULL || p_sys->p_nfs_url->file == NULL)
                goto error;

            if (nfs_mount_async(p_sys->p_nfs, p_sys->p_nfs_url->server,
                                p_sys->p_nfs_url->path, nfs_mount_cb, p_access) < 0)
            {
                msg_Err(p_access, "nfs_mount_async failed");
                goto error;
            }

            if (vlc_nfs_mainloop(p_access, nfs_mount_open_slash_finished_cb) < 0)
                goto error;
        }

        if (p_sys->p_nfsfh != NULL)
        {
            p_access->pf_read = FileRead;
            p_access->pf_seek = FileSeek;
            p_access->pf_control = FileControl;
        }
        else if (p_sys->p_nfsdir != NULL)
        {
            p_access->pf_readdir = DirRead;
            p_access->pf_seek = NULL;
            p_access->pf_control = DirControl;
        }
        else
            vlc_assert_unreachable();
    }
    else
    {
        /* url is just a server: fetch exports point */
        nfs_destroy_context(p_sys->p_nfs);
        p_sys->p_nfs = NULL;

        p_sys->p_mount = rpc_init_context();
        if (p_sys->p_mount == NULL)
        {
            msg_Err(p_access, "rpc_init_context failed");
            goto error;
        }

        p_sys->res.exports.ppsz_names = NULL;
        p_sys->res.exports.i_count = -1;

        if (mount_getexports_async(p_sys->p_mount, p_sys->p_nfs_url->server,
                                   mount_export_cb, p_access) < 0)
        {
            msg_Err(p_access, "mount_getexports_async failed");
            goto error;
        }

        if (vlc_mount_mainloop(p_access, mount_getexports_finished_cb) < 0)
            goto error;

        p_access->pf_readdir = MountRead;
        p_access->pf_seek = NULL;
        p_access->pf_control = DirControl;
    }

    return VLC_SUCCESS;

error:
    Close(p_obj);
    return VLC_EGENERIC;
}
예제 #4
0
파일: ram.c 프로젝트: MarkYuan/vlc
/**
 * Parses clipinfo parameter
 * @param psz_clipinfo: string containing the clipinfo parameter along with quotes
 * @param ppsz_artist: Buffer to store artist name
 * @param ppsz_title: Buffer to store title
 * @param ppsz_album: Buffer to store album
 * @param ppsz_genre: Buffer to store genre
 * @param ppsz_year: Buffer to store year
 * @param ppsz_cdnum: Buffer to store cdnum
 * @param ppsz_comments: Buffer to store comments
 */
static void ParseClipInfo( const char *psz_clipinfo, char **ppsz_artist, char **ppsz_title,
                           char **ppsz_album, char **ppsz_genre, char **ppsz_year,
                           char **ppsz_cdnum, char **ppsz_comments )
{
    char *psz_option_next, *psz_option_start, *psz_param, *psz_value, *psz_suboption;
    char *psz_temp_clipinfo = strdup( psz_clipinfo );
    psz_option_start = strchr( psz_temp_clipinfo, '"' );
    if( !psz_option_start )
    {
        free( psz_temp_clipinfo );
        return;
    }

    psz_option_start++;
    psz_option_next = psz_option_start;
    while( 1 ) /* Process each sub option */
    {
        /* Get the sub option */
        psz_option_start = psz_option_next;
        psz_option_next = strchr( psz_option_start, '|' );
        if( psz_option_next )
            *psz_option_next = '\0';
        else
            psz_option_next = strchr( psz_option_start, '"' );
        if( psz_option_next )
            *psz_option_next = '\0';
        else
            psz_option_next = strchr( psz_option_start, '\0' );
        if( psz_option_next == psz_option_start )
            break;

        psz_suboption = strdup( psz_option_start );
        if( !psz_suboption )
            break;

        /* Parse out param and value */
        psz_param = psz_suboption;
        if( strchr( psz_suboption, '=' ) )
        {
            psz_value = strchr( psz_suboption, '=' ) + 1;
            *( strchr( psz_suboption, '=' ) ) = '\0';
        }
        else
        {
            free( psz_suboption );
            break;
        }
        /* Put into args */
        if( !strcmp( psz_param, "artist name" ) )
            *ppsz_artist = vlc_uri_decode_duplicate( psz_value );
        else if( !strcmp( psz_param, "title" ) )
            *ppsz_title = vlc_uri_decode_duplicate( psz_value );
        else if( !strcmp( psz_param, "album name" ) )
            *ppsz_album = vlc_uri_decode_duplicate( psz_value );
        else if( !strcmp( psz_param, "genre" ) )
            *ppsz_genre = vlc_uri_decode_duplicate( psz_value );
        else if( !strcmp( psz_param, "year" ) )
            *ppsz_year = vlc_uri_decode_duplicate( psz_value );
        else if( !strcmp( psz_param, "cdnum" ) )
            *ppsz_cdnum = vlc_uri_decode_duplicate( psz_value );
        else if( !strcmp( psz_param, "comments" ) )
            *ppsz_comments = vlc_uri_decode_duplicate( psz_value );

        free( psz_suboption );
        psz_option_next++;
    }

    free( psz_temp_clipinfo );
}
예제 #5
0
파일: ram.c 프로젝트: MarkYuan/vlc
/**
 * Main demux callback function
 * @param p_demux: this demux object
 */
static int Demux( demux_t *p_demux )
{
    char       *psz_line;
    char       *psz_artist = NULL, *psz_album = NULL, *psz_genre = NULL, *psz_year = NULL;
    char       *psz_author = NULL, *psz_title = NULL, *psz_copyright = NULL, *psz_cdnum = NULL, *psz_comments = NULL;
    mtime_t    i_duration = -1;
    const char **ppsz_options = NULL;
    int        i_options = 0, i_start = 0, i_stop = 0;
    bool b_cleanup = false;
    input_item_t *p_input;

    input_item_t *p_current_input = GetCurrentItem(p_demux);

    input_item_node_t *p_subitems = input_item_node_Create( p_current_input );

    psz_line = vlc_stream_ReadLine( p_demux->s );
    while( psz_line )
    {
        char *psz_parse = psz_line;

        /* Skip leading tabs and spaces */
        while( *psz_parse == ' ' || *psz_parse == '\t' ||
               *psz_parse == '\n' || *psz_parse == '\r' ) psz_parse++;

        if( *psz_parse == '#' )
        {
            /* Ignore comments */
        }
        else if( *psz_parse )
        {
            char *psz_mrl, *psz_option_next, *psz_option;
            char *psz_param, *psz_value;

            /* Get the MRL from the file. Note that this might contain parameters of form ?param1=value1&param2=value2 in a RAM file */
            psz_mrl = ProcessMRL( psz_parse, p_demux->p_sys->psz_prefix );

            b_cleanup = true;
            if ( !psz_mrl ) goto error;

            /* We have the MRL, now we have to check for options and parse them from MRL */
            psz_option = strchr( psz_mrl, '?' ); /* Look for start of options */
            if( psz_option )
            {
                /* Remove options from MRL
                   because VLC can't get the file otherwise */
                *psz_option = '\0';
                psz_option++;
                psz_option_next = psz_option;
                while( 1 ) /* Process each option */
                {
                    /* Look for end of first option which maybe a & or \0 */
                    psz_option = psz_option_next;
                    psz_option_next = strchr( psz_option, '&' );
                    if( psz_option_next )
                    {
                        *psz_option_next = '\0';
                        psz_option_next++;
                    }
                    else
                        psz_option_next = strchr( psz_option, '\0' );
                    /* Quit if options are over */
                    if( psz_option_next == psz_option )
                        break;

                    /* Parse out param and value */
                    psz_param = psz_option;
                    psz_value = strchr( psz_option, '=' );
                    if( psz_value == NULL )
                        break;
                    *psz_value = '\0';
                    psz_value++;

                    /* Take action based on parameter value in the below if else structure */
                    /* TODO: Remove any quotes surrounding values if required */
                    if( !strcmp( psz_param, "clipinfo" ) )
                    {
                        ParseClipInfo( psz_value, &psz_artist, &psz_title,
                           &psz_album, &psz_genre, &psz_year,
                           &psz_cdnum, &psz_comments ); /* clipinfo has various sub parameters, which is parsed by this function */
                    }
                    else if( !strcmp( psz_param, "author" ) )
                    {
                        psz_author = vlc_uri_decode_duplicate(psz_value);
                        EnsureUTF8( psz_author );
                    }
                    else if( !strcmp( psz_param, "start" )
                            && strncmp( psz_mrl, "rtsp", 4 ) /* Our rtsp-real or our real demuxer is wrong */  )
                    {
                        i_start = ParseTime( psz_value, strlen( psz_value ) );
                        char *temp;
                        if( i_start )
                        {
                            if( asprintf( &temp, ":start-time=%d", i_start ) != -1 )
                                INSERT_ELEM( ppsz_options, i_options, i_options, temp );
                        }
                    }
                    else if( !strcmp( psz_param, "end" ) )
                    {
                        i_stop = ParseTime( psz_value, strlen( psz_value ) );
                        char *temp;
                        if( i_stop )
                        {
                            if( asprintf( &temp, ":stop-time=%d", i_stop ) != -1 )
                                INSERT_ELEM( ppsz_options, i_options, i_options, temp );
                        }
                    }
                    else if( !strcmp( psz_param, "title" ) )
                    {
                        free( psz_title );
                        psz_title = vlc_uri_decode_duplicate(psz_value);
                        EnsureUTF8( psz_title );
                    }
                    else if( !strcmp( psz_param, "copyright" ) )
                    {
                        psz_copyright = vlc_uri_decode_duplicate(psz_value);
                        EnsureUTF8( psz_copyright );
                    }
                    else
                    {   /* TODO: insert option anyway? Currently ignores*/
                        /* INSERT_ELEM( ppsz_options, i_options, i_options, psz_option ); */
                    }
                }
            }

            /* Create the input item and pump in all the options into playlist item */
            p_input = input_item_NewExt( psz_mrl, psz_title, i_duration,
                                         ITEM_TYPE_UNKNOWN, ITEM_NET_UNKNOWN );
            if( !p_input )
            {
                free( psz_mrl );
                goto error;
            }
            input_item_AddOptions( p_input, i_options, ppsz_options, 0 );

            if( !EMPTY_STR( psz_artist ) ) input_item_SetArtist( p_input, psz_artist );
            if( !EMPTY_STR( psz_author ) ) input_item_SetPublisher( p_input, psz_author );
            if( !EMPTY_STR( psz_title ) ) input_item_SetTitle( p_input, psz_title );
            if( !EMPTY_STR( psz_copyright ) ) input_item_SetCopyright( p_input, psz_copyright );
            if( !EMPTY_STR( psz_album ) ) input_item_SetAlbum( p_input, psz_album );
            if( !EMPTY_STR( psz_genre ) ) input_item_SetGenre( p_input, psz_genre );
            if( !EMPTY_STR( psz_year ) ) input_item_SetDate( p_input, psz_year );
            if( !EMPTY_STR( psz_cdnum ) ) input_item_SetTrackNum( p_input, psz_cdnum );
            if( !EMPTY_STR( psz_comments ) ) input_item_SetDescription( p_input, psz_comments );

            input_item_node_AppendItem( p_subitems, p_input );
            vlc_gc_decref( p_input );
            free( psz_mrl );
        }

 error:
        /* Fetch another line */
        free( psz_line );
        psz_line = vlc_stream_ReadLine( p_demux->s );
        if( !psz_line ) b_cleanup = true;

        if( b_cleanup )
        {
            /* Cleanup state */
            while( i_options-- ) free( (char*)ppsz_options[i_options] );
            FREENULL( ppsz_options );
            FREENULL( psz_artist );
            FREENULL( psz_title );
            FREENULL( psz_author );
            FREENULL( psz_copyright );
            FREENULL( psz_album );
            FREENULL( psz_genre );
            FREENULL( psz_year );
            FREENULL( psz_cdnum );
            FREENULL( psz_comments );
            i_options = 0;
            i_duration = -1;
            i_start = 0;
            i_stop = 0;
            b_cleanup = false;
        }
    }
    input_item_node_PostAndDelete( p_subitems );
    vlc_gc_decref(p_current_input);
    var_Destroy( p_demux, "m3u-extvlcopt" );
    return 0; /* Needed for correct operation of go back */
}
예제 #6
0
파일: keystore.c 프로젝트: mstorsjo/vlc
bool
vlc_credential_store(vlc_credential *p_credential, vlc_object_t *p_parent)
{
    if (!is_credential_valid(p_credential))
        return false;
    /* Don't need to store again */
    if (p_credential->b_from_keystore)
        return p_credential->b_from_keystore;

    vlc_keystore *p_keystore;
    if (p_credential->b_store)
    {
        /* Store in permanent keystore */
        assert(p_credential->p_keystore != NULL);
        p_keystore = p_credential->p_keystore;
    }
    else
    {
        /* Store in memory keystore */
        p_keystore = get_memory_keystore(p_parent);
    }
    if (p_keystore == NULL)
        return false;

    const vlc_url_t *p_url = p_credential->p_url;

    char *psz_path = NULL;
    if (protocol_store_path(p_url)
     && (psz_path =  vlc_uri_decode_duplicate(p_url->psz_path)) != NULL)
    {
        char *p_slash;
        if (protocol_is_smb(p_url))
        {
            /* Remove all characters after the first slash (store the share but
             * not the path) */
            p_slash = strchr(psz_path + 1, '/');
        }
        else
        {
            /* Remove all characters after the last slash (store the path
             * without the filename) */
            p_slash = strrchr(psz_path + 1, '/');
        }
        if (p_slash && psz_path != p_slash)
            *p_slash = '\0';
    }

    const char *ppsz_values[KEY_MAX] = { 0 };
    ppsz_values[KEY_PROTOCOL] = p_url->psz_protocol;
    ppsz_values[KEY_USER] = p_credential->psz_username;
    ppsz_values[KEY_SERVER] = p_url->psz_host;
    ppsz_values[KEY_PATH] = psz_path;
    ppsz_values[KEY_REALM] = p_credential->psz_realm;
    ppsz_values[KEY_AUTHTYPE] = p_credential->psz_authtype;

    char psz_port[21];
    if (protocol_set_port(p_url, psz_port))
        ppsz_values[KEY_PORT] = psz_port;

    char *psz_label;
    if (asprintf(&psz_label, "LibVLC password for %s://%s%s",
                 p_url->psz_protocol, p_url->psz_host,
                 psz_path ? psz_path : "") == -1)
    {
        free(psz_path);
        return false;
    }

    const uint8_t *p_password = (const uint8_t *)
        (p_credential->psz_password != NULL ? p_credential->psz_password : "");

    bool b_ret = vlc_keystore_store(p_keystore, ppsz_values, p_password,
                                    -1, psz_label) == VLC_SUCCESS;
    free(psz_label);
    free(psz_path);
    return b_ret;
}
예제 #7
0
파일: access.c 프로젝트: huotianjun/vlc
/*****************************************************************************
 * Open: Initialize module's data structures and libdsm
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    access_t     *p_access = (access_t*)p_this;
    access_sys_t *p_sys;
    smb_stat st;

    /* Init p_access */
    access_InitFields( p_access );
    p_sys = p_access->p_sys = (access_sys_t*)calloc( 1, sizeof( access_sys_t ) );
    if( p_access->p_sys == NULL )
        return VLC_ENOMEM;

    p_sys->p_ns = netbios_ns_new();
    if( p_sys->p_ns == NULL )
        goto error;

    p_sys->p_session = smb_session_new();
    if( p_sys->p_session == NULL )
        goto error;

    char *psz_decoded_location = vlc_uri_decode_duplicate( p_access->psz_location );
    if( psz_decoded_location == NULL )
        goto error;
    vlc_UrlParse( &p_sys->url, psz_decoded_location );
    free( psz_decoded_location );
    if( get_address( p_access ) != VLC_SUCCESS )
        goto error;

    msg_Dbg( p_access, "Session: Host name = %s, ip = %s", p_sys->netbios_name,
             inet_ntoa( p_sys->addr ) );

    /* Now that we have the required data, let's establish a session */
    if( !smb_session_connect( p_sys->p_session, p_sys->netbios_name,
                              p_sys->addr.s_addr, SMB_TRANSPORT_TCP ) )
    {
        msg_Err( p_access, "Unable to connect/negotiate SMB session");
        goto error;
    }

    get_path( p_access );

    if( login( p_access ) != VLC_SUCCESS )
    {
        msg_Err( p_access, "Unable to open file with path %s (in share %s)",
                 p_sys->psz_path, p_sys->psz_share );
        goto error;
    }

    /* If there is no shares, browse them */
    if( !p_sys->psz_share )
        return BrowserInit( p_access );

    assert(p_sys->i_fd > 0);

    msg_Dbg( p_access, "Path: Share name = %s, path = %s", p_sys->psz_share,
             p_sys->psz_path );

    st = smb_stat_fd( p_sys->p_session, p_sys->i_fd );
    if( smb_stat_get( st, SMB_STAT_ISDIR ) )
    {
        smb_fclose( p_sys->p_session, p_sys->i_fd );
        return BrowserInit( p_access );
    }

    msg_Dbg( p_access, "Successfully opened smb://%s", p_access->psz_location );

    ACCESS_SET_CALLBACKS( Read, NULL, Control, Seek );
    return VLC_SUCCESS;

    error:
        Close( p_this );
        return VLC_EGENERIC;
}
예제 #8
0
파일: smb.c 프로젝트: tguillem/vlc
/****************************************************************************
 * Open: connect to smb server and ask for file
 ****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    stream_t     *p_access = (stream_t*)p_this;
    access_sys_t *p_sys;
    struct stat  filestat;
    vlc_url_t    url;
    vlc_credential credential;
    char         *psz_decoded_path = NULL, *psz_uri = NULL,
                 *psz_var_domain = NULL;
    int          i_ret;
    int          i_smb;
    uint64_t     i_size;
    bool         b_is_dir = false;

#ifndef _WIN32
    if( smbc_init( smb_auth, 0 ) )
        return VLC_EGENERIC;
#endif

/*
** some version of glibc defines open as a macro, causing havoc
** with other macros using 'open' under the hood, such as the
** following one:
*/
#if defined(smbc_open) && defined(open)
# undef open
#endif

    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;
    vlc_credential_get( &credential, p_access, "smb-user", "smb-pwd",
                        NULL, NULL );
    for (;;)
    {
        if( smb_get_uri( p_access, &psz_uri, credential.psz_realm,
                         credential.psz_username, credential.psz_password,
                         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;
        }

        if( ( i_ret = smbc_stat( psz_uri, &filestat ) ) && errno == EACCES )
        {
            errno = 0;
            if( vlc_credential_get( &credential, p_access, "smb-user", "smb-pwd",
                                    SMB_LOGIN_DIALOG_TITLE,
                                    SMB_LOGIN_DIALOG_TEXT, url.psz_host) )
                continue;
        }

        /* smbc_stat fails with servers or shares. Assume they are directory */
        if( i_ret || S_ISDIR( filestat.st_mode ) )
            b_is_dir = true;
        break;
    }

    vlc_credential_store( &credential, p_access );
    vlc_credential_clean( &credential );
    free(psz_var_domain);
    free( psz_decoded_path );

    /* Init p_access */
    p_sys =
    p_access->p_sys = vlc_calloc( p_this, 1, sizeof( access_sys_t ) );
    if( !p_sys )
    {
        free( psz_uri );
        vlc_UrlClean( &url );
        return VLC_ENOMEM;
    }

    if( b_is_dir )
    {
        p_sys->url = url;
        p_access->pf_readdir = DirRead;
        p_access->pf_control = access_vaDirectoryControlHelper;
        i_size = 0;
#ifndef _WIN32
        i_smb = smbc_opendir( psz_uri );
        if( i_smb < 0 )
            vlc_UrlClean( &p_sys->url );
#endif
    }
    else
    {
        ACCESS_SET_CALLBACKS( Read, NULL, Control, Seek );
        i_smb = smbc_open( psz_uri, O_RDONLY, 0 );
        i_size = filestat.st_size;
        vlc_UrlClean( &url );
    }
    free( psz_uri );

#ifndef _WIN32
    if( i_smb < 0 )
    {
        msg_Err( p_access, "open failed for '%s' (%s)",
                 p_access->psz_location, vlc_strerror_c(errno) );
        return VLC_EGENERIC;
    }
#endif

    p_sys->size = i_size;
    p_sys->i_smb = i_smb;

    return VLC_SUCCESS;
}
예제 #9
0
파일: unc.c 프로젝트: mstorsjo/vlc
static int Open(vlc_object_t *obj)
{
    stream_t *access = (stream_t *)obj;
    vlc_url_t url;
    vlc_credential credential;
    char *psz_decoded_path = NULL, *psz_uri = NULL, *psz_var_domain = NULL;
    int fd;
    uint64_t size;
    bool is_dir;

    if (vlc_UrlParseFixup(&url, access->psz_url) != 0)
    {
        vlc_UrlClean(&url);
        return VLC_EGENERIC;
    }

    if (url.psz_path != NULL)
    {
        psz_decoded_path = vlc_uri_decode_duplicate(url.psz_path);
        if (psz_decoded_path == NULL)
        {
            vlc_UrlClean(&url);
            return VLC_EGENERIC;
        }
    }

    vlc_credential_init(&credential, &url);
    psz_var_domain = var_InheritString(access, "smb-domain");
    credential.psz_realm = psz_var_domain;
    vlc_credential_get(&credential, access, "smb-user", "smb-pwd", NULL, NULL);

    for (;;)
    {
        struct stat st;

        if (smb_get_uri(access, &psz_uri, credential.psz_realm,
                        credential.psz_username, credential.psz_password,
                        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;
        }

        if (stat(psz_uri, &st) == 0)
        {
            is_dir = S_ISDIR(st.st_mode) != 0;
            size = st.st_size;
            break;
        }

        /* stat() fails with servers or shares. Assume directory. */
        is_dir = true;
        size = 0;

        if (errno != EACCES)
            break;

        errno = 0;
        if (!vlc_credential_get(&credential, access, "smb-user",
                                "smb-pwd", SMB_LOGIN_DIALOG_TITLE,
                                SMB_LOGIN_DIALOG_TEXT, url.psz_host))
            break;
    }

    vlc_credential_store(&credential, access);
    vlc_credential_clean(&credential);
    free(psz_var_domain);
    free(psz_decoded_path);

    /* Init access */
    access_sys_t *sys = vlc_obj_calloc(obj, 1, sizeof (*sys));
    if (unlikely(sys == NULL))
    {
        free(psz_uri);
        vlc_UrlClean(&url);
        return VLC_ENOMEM;
    }

    access->p_sys = sys;

    if (is_dir)
    {
        sys->url = url;
        access->pf_readdir = DirRead;
        access->pf_control = access_vaDirectoryControlHelper;
    }
    else
    {
        access->pf_read = Read;
        access->pf_control = Control;
        access->pf_seek = Seek;
        fd = open(psz_uri, O_RDONLY, 0);
        vlc_UrlClean(&url);
    }
    free(psz_uri);

    sys->size = size;
    sys->i_smb = fd;

    return VLC_SUCCESS;
}