예제 #1
0
파일: vdr.c 프로젝트: chouquette/vlc
/*****************************************************************************
 * Open a directory
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    access_t *p_access = (access_t*)p_this;

    if( !p_access->psz_filepath )
        return VLC_EGENERIC;

    /* Some tests can be skipped if this module was explicitly requested.
     * That way, the user can play "corrupt" recordings if necessary
     * and we can avoid false positives in the general case. */
    bool b_strict = strcmp( p_access->psz_name, "vdr" );

    /* Do a quick test based on the directory name to see if this
     * directory might contain a VDR recording. We can be reasonably
     * sure if ScanDirectory() actually finds files. */
    if( b_strict )
    {
        char psz_extension[4];
        int i_length = 0;
        const char *psz_name = BaseName( p_access->psz_filepath );
        if( sscanf( psz_name, "%*u-%*u-%*u.%*u.%*u.%*u%*[-.]%*u.%3s%n",
            psz_extension, &i_length ) != 1 || strcasecmp( psz_extension, "rec" ) ||
            ( psz_name[i_length] != DIR_SEP_CHAR && psz_name[i_length] != '\0' ) )
            return VLC_EGENERIC;
    }

    /* Only directories can be recordings */
    struct stat st;
    if( vlc_stat( p_access->psz_filepath, &st ) ||
        !S_ISDIR( st.st_mode ) )
        return VLC_EGENERIC;

    access_sys_t *p_sys = vlc_calloc( p_this, 1, sizeof( *p_sys ) );

    if( unlikely(p_sys == NULL) )
        return VLC_ENOMEM;

    p_access->p_sys = p_sys;
    p_sys->fd = -1;
    p_sys->cur_seekpoint = 0;
    p_sys->fps = var_InheritFloat( p_access, "vdr-fps" );
    ARRAY_INIT( p_sys->file_sizes );

    /* Import all files and prepare playback. */
    if( !ScanDirectory( p_access ) ||
        !SwitchFile( p_access, 0 ) )
    {
        Close( p_this );
        return VLC_EGENERIC;
    }

    ACCESS_SET_CALLBACKS( Read, NULL, Control, Seek );
    return VLC_SUCCESS;
}
예제 #2
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;
}