Ejemplo n.º 1
0
int DoAcoustIdWebRequest( vlc_object_t *p_obj, acoustid_fingerprint_t *p_data )
{
    if ( !p_data->psz_fingerprint ) return VLC_SUCCESS;

    char *psz_url;
    if( unlikely(asprintf( &psz_url, "https://fingerprint.videolan.org/"
                           "acoustid.php?meta=recordings+tracks+usermeta+"
                           "releases&duration=%d&fingerprint=%s",
                           p_data->i_duration, p_data->psz_fingerprint ) < 1 ) )
         return VLC_EGENERIC;

    msg_Dbg( p_obj, "Querying AcoustID from %s", psz_url );
    int i_saved_flags = p_obj->obj.flags;
    p_obj->obj.flags |= OBJECT_FLAGS_NOINTERACT;

    stream_t *p_stream = vlc_stream_NewURL( p_obj, psz_url );

    free( psz_url );
    p_obj->obj.flags = i_saved_flags;
    if ( p_stream == NULL )
        return VLC_EGENERIC;

    stream_t *p_chain = vlc_stream_FilterNew( p_stream, "inflate" );
    if( p_chain )
        p_stream = p_chain;

    /* read answer */
    char *p_buffer = NULL;
    int i_ret = 0;
    for( ;; )
    {
        int i_read = 65536;

        if( i_ret >= INT_MAX - i_read )
            break;

        p_buffer = realloc_or_free( p_buffer, 1 + i_ret + i_read );
        if( unlikely(p_buffer == NULL) )
        {
            vlc_stream_Delete( p_stream );
            return VLC_ENOMEM;
        }

        i_read = vlc_stream_Read( p_stream, &p_buffer[i_ret], i_read );
        if( i_read <= 0 )
            break;

        i_ret += i_read;
    }
    vlc_stream_Delete( p_stream );
    p_buffer[i_ret] = 0;

    if ( ParseJson( p_obj, p_buffer, & p_data->results ) )
        msg_Dbg( p_obj, "results count == %d", p_data->results.count );
    else
        msg_Dbg( p_obj, "No results" );
    free( p_buffer );

    return VLC_SUCCESS;
}
Ejemplo n.º 2
0
Archivo: image.c Proyecto: BossKing/vlc
static picture_t *ImageReadUrl( image_handler_t *p_image, const char *psz_url,
                                video_format_t *p_fmt_in,
                                video_format_t *p_fmt_out )
{
    block_t *p_block;
    picture_t *p_pic;
    stream_t *p_stream = NULL;
    uint64_t i_size;

    p_stream = vlc_stream_NewMRL( p_image->p_parent, psz_url );

    if( !p_stream )
    {
        msg_Dbg( p_image->p_parent, "could not open %s for reading",
                 psz_url );
        return NULL;
    }

    if( vlc_stream_GetSize( p_stream, &i_size ) || i_size > SSIZE_MAX )
    {
        msg_Dbg( p_image->p_parent, "could not read %s", psz_url );
        goto error;
    }

    p_block = vlc_stream_Block( p_stream, i_size );
    if( p_block == NULL )
        goto error;

    if( !p_fmt_in->i_chroma )
    {
        char *psz_mime = stream_ContentType( p_stream );
        if( psz_mime != NULL )
        {
            p_fmt_in->i_chroma = image_Mime2Fourcc( psz_mime );
            free( psz_mime );
        }
    }
    vlc_stream_Delete( p_stream );

    if( !p_fmt_in->i_chroma )
    {
        /* Try to guess format from file name */
        p_fmt_in->i_chroma = image_Ext2Fourcc( psz_url );
    }

    p_pic = ImageRead( p_image, p_block, p_fmt_in, p_fmt_out );

    return p_pic;
error:
    vlc_stream_Delete( p_stream );
    return NULL;
}
Ejemplo n.º 3
0
/*****************************************************************************
 * Import_podcast: main import function
 *****************************************************************************/
int Import_podcast( vlc_object_t *p_this )
{
    stream_t *p_demux = (stream_t *)p_this;

    CHECK_FILE(p_demux);
    if( stream_IsMimeType( p_demux->s, "text/xml" )
     || stream_IsMimeType( p_demux->s, "application/xml" ) )
    {
        /* XML: check if the root node is "rss". Use a specific peeked
         * probestream in order to not modify the source state while probing.
         * */
        const uint8_t *p_peek;
        ssize_t i_peek = vlc_stream_Peek( p_demux->s, &p_peek, 2048 );
        if( unlikely( i_peek <= 0 ) )
            return VLC_EGENERIC;

        stream_t *p_probestream =
            vlc_stream_MemoryNew( p_demux, (uint8_t *)p_peek, i_peek, true );
        if( unlikely( !p_probestream ) )
            return VLC_EGENERIC;

        xml_reader_t *p_xml_reader = xml_ReaderCreate( p_demux, p_probestream );
        if( !p_xml_reader )
        {
            vlc_stream_Delete( p_probestream );
            return VLC_EGENERIC;
        }

        const char *node;
        int ret;
        if( ( ret = xml_ReaderNextNode( p_xml_reader, &node ) ) != XML_READER_STARTELEM
         || strcmp( node, "rss" ) )
        {
            vlc_stream_Delete( p_probestream );
            xml_ReaderDelete( p_xml_reader );
            return VLC_EGENERIC;
        }

        xml_ReaderDelete( p_xml_reader );
        vlc_stream_Delete( p_probestream );
        /* SUCCESS: this text/xml is a rss file */
    }
    else if( !stream_IsMimeType( p_demux->s, "application/rss+xml" ) )
        return VLC_EGENERIC;

    p_demux->pf_readdir = ReadDir;
    p_demux->pf_control = access_vaDirectoryControlHelper;
    msg_Dbg( p_demux, "using podcast reader" );

    return VLC_SUCCESS;
}
Ejemplo n.º 4
0
static int Seek(access_t *access, uint64_t position)
{
    access_sys_t *sys = access->p_sys;
    const rar_file_t *file = sys->file;

    if (position > file->real_size)
        position = file->real_size;
    sys->position = position;

    /* Search the chunk */
    const rar_file_chunk_t *old_chunk = sys->chunk;
    for (int i = 0; i < file->chunk_count; i++) {
        sys->chunk = file->chunk[i];
        if (position < sys->chunk->cummulated_size + sys->chunk->size)
            break;
    }

    const uint64_t offset = sys->chunk->offset +
                            (position - sys->chunk->cummulated_size);

    if (strcmp(old_chunk->mrl, sys->chunk->mrl)) {
        if (sys->s)
            vlc_stream_Delete(sys->s);
        sys->s = vlc_stream_NewMRL(access, sys->chunk->mrl);
    }
    return sys->s ? vlc_stream_Seek(sys->s, offset) : VLC_EGENERIC;
}
Ejemplo n.º 5
0
vlc_demux_chained_t *vlc_demux_chained_New(vlc_object_t *parent,
                                           const char *name, es_out_t *out)
{
    vlc_demux_chained_t *dc = malloc(sizeof (*dc) + strlen(name) + 1);
    if (unlikely(dc == NULL))
        return NULL;

    dc->writer = vlc_stream_fifo_New(parent, &dc->reader);
    if (dc->writer == NULL)
    {
        free(dc);
        return NULL;
    }

    dc->stats.position = 0.;
    dc->stats.length = 0;
    dc->stats.time = 0;
    dc->out = out;
    strcpy(dc->name, name);

    vlc_mutex_init(&dc->lock);

    if (vlc_clone(&dc->thread, vlc_demux_chained_Thread, dc,
                  VLC_THREAD_PRIORITY_INPUT))
    {
        vlc_stream_Delete(dc->reader);
        vlc_stream_fifo_Close(dc->writer);
        vlc_mutex_destroy(&dc->lock);
        free(dc);
        dc = NULL;
    }
    return dc;
}
Ejemplo n.º 6
0
static int Find( addons_finder_t *p_finder )
{
    bool b_done = false;

    while ( !b_done )
    {
        char *psz_uri = NULL;

        if ( ! asprintf( &psz_uri, ADDONS_REPO_SCHEMEHOST"/xml" ) ) return VLC_ENOMEM;
        b_done = true;

        stream_t *p_stream = vlc_stream_NewURL_ND( p_finder, psz_uri );
        free( psz_uri );
        if ( !p_stream ) return VLC_EGENERIC;

        if ( ! ParseCategoriesInfo( p_finder, p_stream ) )
        {
            /* no more entries have been read: was last page or error */
            b_done = true;
        }

        vlc_stream_Delete( p_stream );
    }

    return VLC_SUCCESS;
}
Ejemplo n.º 7
0
static access_t *GetAccess(access_t *access)
{
    access_sys_t *sys = access->p_sys;
    access_t *a = sys->access;

    if (a != NULL)
    {
        if (!vlc_stream_Eof(a))
            return a;

        vlc_stream_Delete(a);
        sys->access = NULL;
    }

    if (sys->next == NULL)
        return NULL;

    a = vlc_access_NewMRL(VLC_OBJECT(access), sys->next->mrl);
    if (a == NULL)
        return NULL;

    sys->access = a;
    sys->next = sys->next->next;
    return a;
}
Ejemplo n.º 8
0
static void StreamDelete( stream_t *s )
{
    module_unneed( s, s->p_module );

    if( s->p_source )
        vlc_stream_Delete( s->p_source );
}
Ejemplo n.º 9
0
static void StreamDelete(stream_t *s)
{
    struct vlc_stream_filter_private *priv = vlc_stream_Private(s);

    module_unneed(s, priv->module);
    vlc_stream_Delete(s->s);
    free(s->psz_filepath);
}
Ejemplo n.º 10
0
void RarAccessClose(vlc_object_t *object)
{
    access_t *access = (access_t*)object;
    access_sys_t *sys = access->p_sys;

    if (sys->s)
        vlc_stream_Delete(sys->s);
    RarFileDelete(sys->file);
    free(sys);
}
Ejemplo n.º 11
0
static int Find( addons_finder_t *p_finder )
{
    stream_t *p_stream = vlc_stream_NewURL_ND( p_finder,
                                            ADDONS_REPO_SCHEMEHOST "/xml" );
    if ( !p_stream )
        return VLC_EGENERIC;

    int i_res = ParseCategoriesInfo( p_finder, p_stream );
    vlc_stream_Delete( p_stream );

    return i_res > 0 ? VLC_SUCCESS : VLC_EGENERIC;
}
Ejemplo n.º 12
0
Archivo: access.c Proyecto: etix/vlc
static int SwitchCallback(struct archive *p_archive, void *p_object, void *p_object2)
{
    VLC_UNUSED(p_archive);
    callback_data_t *p_data = (callback_data_t *) p_object;
    callback_data_t *p_nextdata = (callback_data_t *) p_object2;
    access_sys_t *p_sys = p_data->p_access->p_sys;

    msg_Dbg(p_data->p_access, "opening next volume %s", p_nextdata->psz_uri);
    vlc_stream_Delete(p_sys->p_stream);
    p_sys->p_stream = vlc_stream_NewURL(p_nextdata->p_access, p_nextdata->psz_uri);
    return p_sys->p_stream ? ARCHIVE_OK : ARCHIVE_FATAL;
}
Ejemplo n.º 13
0
Archivo: vlc.c Proyecto: etix/vlc
/** Replacement for luaL_dofile, using VLC's input capabilities */
int vlclua_dofile( vlc_object_t *p_this, lua_State *L, const char *curi )
{
    char *uri = ToLocaleDup( curi );
    if( !strstr( uri, "://" ) ) {
        int ret = luaL_dofile( L, uri );
        free( uri );
        return ret;
    }
    if( !strncasecmp( uri, "file://", 7 ) ) {
        int ret = luaL_dofile( L, uri + 7 );
        free( uri );
        return ret;
    }
    stream_t *s = vlc_stream_NewURL( p_this, uri );
    if( !s )
    {
        free( uri );
        return 1;
    }
    int64_t i_size = stream_Size( s );
    char *p_buffer = ( i_size > 0 ) ? malloc( i_size ) : NULL;
    if( !p_buffer )
    {
        // FIXME: read the whole stream until we reach the end (if no size)
        vlc_stream_Delete( s );
        free( uri );
        return 1;
    }
    int64_t i_read = vlc_stream_Read( s, p_buffer, (int) i_size );
    int i_ret = ( i_read == i_size ) ? 0 : 1;
    if( !i_ret )
        i_ret = luaL_loadbuffer( L, p_buffer, (size_t) i_size, uri );
    if( !i_ret )
        i_ret = lua_pcall( L, 0, LUA_MULTRET, 0 );
    vlc_stream_Delete( s );
    free( p_buffer );
    free( uri );
    return i_ret;
}
Ejemplo n.º 14
0
Archivo: access.c Proyecto: etix/vlc
static int CloseCallback(struct archive *p_archive, void *p_object)
{
    VLC_UNUSED(p_archive);
    callback_data_t *p_data = (callback_data_t *) p_object;
    access_sys_t *p_sys = p_data->p_access->p_sys;

    if (p_sys->p_stream)
    {
        vlc_stream_Delete(p_sys->p_stream);
        p_sys->p_stream = NULL;
    }

    return ARCHIVE_OK;
}
Ejemplo n.º 15
0
/**
 * Release the private data associated with a stream-extractor
 * \param priv pointer to the private section
 */
static void se_Release( struct stream_extractor_private* priv )
{
    if( priv->pf_clean )
        priv->pf_clean( priv );

    if( priv->module )
    {
        module_unneed( priv->object, priv->module );

        if( priv->source )
            vlc_stream_Delete( priv->source );
    }

    vlc_object_release( priv->object );
}
Ejemplo n.º 16
0
static void *vlc_demux_chained_Thread(void *data)
{
    vlc_demux_chained_t *dc = data;
    demux_t *demux = demux_New(VLC_OBJECT(dc->reader), dc->name, dc->reader,
                               dc->out);
    if (demux == NULL)
    {
        vlc_stream_Delete(dc->reader);
        return NULL;
    }

    /* Stream FIFO cannot apply DVB filters.
     * Get all programs and let the E/S output sort them out. */
    demux_Control(demux, DEMUX_SET_GROUP_ALL);

    /* Main loop */
    vlc_tick_t next_update = 0;

    do
        if (demux_TestAndClearFlags(demux, UINT_MAX) || vlc_tick_now() >= next_update)
        {
            double newpos;
            vlc_tick_t newlen;
            vlc_tick_t newtime;

            if (demux_Control(demux, DEMUX_GET_POSITION, &newpos))
                newpos = 0.;
            if (demux_Control(demux, DEMUX_GET_LENGTH, &newlen))
                newlen = 0;
            if (demux_Control(demux, DEMUX_GET_TIME, &newtime))
                newtime = 0;

            vlc_mutex_lock(&dc->lock);
            dc->stats.position = newpos;
            dc->stats.length = newlen;
            dc->stats.time = newtime;
            vlc_mutex_unlock(&dc->lock);

            next_update = vlc_tick_now() + VLC_TICK_FROM_MS(250);
        }
    while (demux_Demux(demux) > 0);

    demux_Delete(demux);
    return NULL;
}
Ejemplo n.º 17
0
static int libarchive_exit_cb( libarchive_t* p_arc, void* p_obj )
{
    VLC_UNUSED( p_arc );

    libarchive_callback_t* p_cb = (libarchive_callback_t*)p_obj;

    if( p_cb->p_sys->source == p_cb->p_source )
    {  /* DO NOT CLOSE OUR MOTHER STREAM */
        if( !p_cb->p_sys->b_dead && vlc_stream_Seek( p_cb->p_source, 0 ) )
            return ARCHIVE_FATAL;
    }
    else if( p_cb->p_source )
    {
        vlc_stream_Delete( p_cb->p_source );
        p_cb->p_source = NULL;
    }

    return ARCHIVE_OK;
}
Ejemplo n.º 18
0
Archivo: access.c Proyecto: etix/vlc
static int FindVolumes(access_t *p_access, struct archive *p_archive, const char *psz_uri,
                       char *** const pppsz_files, unsigned int * const pi_files)
{
    VLC_UNUSED(p_archive);
    *pppsz_files = NULL;
    *pi_files = 0;

    static const struct
    {
        char const * const psz_match;
        char const * const psz_format;
        uint16_t i_min;
        uint16_t i_max;
    } patterns[] = {
        { ".part1.rar",   "%.*s.part%.1d.rar", 2,   9 },
        { ".part01.rar",  "%.*s.part%.2d.rar", 2,  99 },
        { ".part001.rar", "%.*s.part%.3d.rar", 2, 999 },
        { ".001",         "%.*s.%.3d",         2, 999 },
        { ".000",         "%.*s.%.3d",         1, 999 },
    };

    const int i_uri_size = strlen(psz_uri);
    const size_t i_patterns = ARRAY_SIZE(patterns);

    for (size_t i = 0; i < i_patterns; i++)
    {
        const int i_match_size = strlen(patterns[i].psz_match);
        if (i_uri_size < i_match_size)
            continue;

        if (!strcmp(&psz_uri[i_uri_size - i_match_size], patterns[i].psz_match))
        {
            char **ppsz_files = xmalloc(sizeof(char *) * patterns[i].i_max);

            for (unsigned j = patterns[i].i_min; j < patterns[i].i_max; j++)
            {
                char *psz_newuri;

                if (asprintf(&psz_newuri, patterns[i].psz_format,
                             i_uri_size - i_match_size, psz_uri, j) == -1)
                    break;

                /* Probe URI */
                int i_savedflags = p_access->obj.flags;
                p_access->obj.flags |= OBJECT_FLAGS_NOINTERACT;
                stream_t *p_stream = vlc_stream_NewURL(p_access, psz_newuri);
                p_access->obj.flags = i_savedflags;
                if (p_stream)
                {
                    ppsz_files[*pi_files] = psz_newuri;
                    (*pi_files)++;
                    vlc_stream_Delete(p_stream);
                }
                else
                {
                    free(psz_newuri);
                    break;
                }
            }

            if (*pi_files == 0)
                FREENULL(ppsz_files);
            *pppsz_files = ppsz_files;

            return VLC_SUCCESS;
        }
    }

    return VLC_SUCCESS;
}
Ejemplo n.º 19
0
Archivo: stream.c Proyecto: mkeiser/vlc
static int vlclua_stream_delete( lua_State *L )
{
    stream_t **pp_stream = (stream_t **)luaL_checkudata( L, 1, "stream" );
    vlc_stream_Delete( *pp_stream );
    return 0;
}
Ejemplo n.º 20
0
/*****************************************************************************
 * Open: initializes matroska demux structures
 *****************************************************************************/
static int Open( vlc_object_t * p_this )
{
    demux_t            *p_demux = (demux_t*)p_this;
    demux_sys_t        *p_sys;
    matroska_stream_c  *p_stream;
    matroska_segment_c *p_segment;
    const uint8_t      *p_peek;
    std::string         s_path, s_filename;
    vlc_stream_io_callback *p_io_callback;
    EbmlStream         *p_io_stream;
    bool                b_need_preload = false;

    /* peek the begining */
    if( vlc_stream_Peek( p_demux->s, &p_peek, 4 ) < 4 ) return VLC_EGENERIC;

    /* is a valid file */
    if( p_peek[0] != 0x1a || p_peek[1] != 0x45 ||
        p_peek[2] != 0xdf || p_peek[3] != 0xa3 ) return VLC_EGENERIC;

    /* Set the demux function */
    p_demux->pf_demux   = Demux;
    p_demux->pf_control = Control;
    p_demux->p_sys      = p_sys = new demux_sys_t( *p_demux );

    p_io_callback = new vlc_stream_io_callback( p_demux->s, false );
    p_io_stream = new (std::nothrow) EbmlStream( *p_io_callback );

    if( p_io_stream == NULL )
    {
        msg_Err( p_demux, "failed to create EbmlStream" );
        delete p_io_callback;
        delete p_sys;
        return VLC_EGENERIC;
    }

    p_stream = p_sys->AnalyseAllSegmentsFound( p_demux, p_io_stream, true );
    if( p_stream == NULL )
    {
        msg_Err( p_demux, "cannot find KaxSegment or missing mandatory KaxInfo" );
        goto error;
    }
    p_sys->streams.push_back( p_stream );

    p_stream->p_io_callback = p_io_callback;
    p_stream->p_estream = p_io_stream;

    for (size_t i=0; i<p_stream->segments.size(); i++)
    {
        p_stream->segments[i]->Preload();
        b_need_preload |= p_stream->segments[i]->b_ref_external_segments;
        if ( p_stream->segments[i]->translations.size() &&
             p_stream->segments[i]->translations[0]->codec_id == MATROSKA_CHAPTER_CODEC_DVD &&
             p_stream->segments[i]->families.size() )
            b_need_preload = true;
    }

    p_segment = p_stream->segments[0];
    if( p_segment->cluster == NULL && p_segment->stored_editions.size() == 0 )
    {
        msg_Err( p_demux, "cannot find any cluster or chapter, damaged file ?" );
        goto error;
    }

    if (b_need_preload && var_InheritBool( p_demux, "mkv-preload-local-dir" ))
    {
        msg_Dbg( p_demux, "Preloading local dir" );
        /* get the files from the same dir from the same family (based on p_demux->psz_path) */
        if ( p_demux->psz_file && !strcmp( p_demux->psz_access, "file" ) )
        {
            // assume it's a regular file
            // get the directory path
            s_path = p_demux->psz_file;
            if (s_path.at(s_path.length() - 1) == DIR_SEP_CHAR)
            {
                s_path = s_path.substr(0,s_path.length()-1);
            }
            else
            {
                if (s_path.find_last_of(DIR_SEP_CHAR) > 0)
                {
                    s_path = s_path.substr(0,s_path.find_last_of(DIR_SEP_CHAR));
                }
            }

            DIR *p_src_dir = vlc_opendir(s_path.c_str());

            if (p_src_dir != NULL)
            {
                const char *psz_file;
                while ((psz_file = vlc_readdir(p_src_dir)) != NULL)
                {
                    if (strlen(psz_file) > 4)
                    {
                        s_filename = s_path + DIR_SEP_CHAR + psz_file;

#if defined(_WIN32) || defined(__OS2__)
                        if (!strcasecmp(s_filename.c_str(), p_demux->psz_file))
#else
                        if (!s_filename.compare(p_demux->psz_file))
#endif
                        {
                            continue; // don't reuse the original opened file
                        }

                        if (!s_filename.compare(s_filename.length() - 3, 3, "mkv") ||
                            !s_filename.compare(s_filename.length() - 3, 3, "mka"))
                        {
                            // test whether this file belongs to our family
                            const uint8_t *p_peek;
                            bool          file_ok = false;
                            char          *psz_url = vlc_path2uri( s_filename.c_str(), "file" );
                            stream_t      *p_file_stream = vlc_stream_NewURL(
                                                            p_demux,
                                                            psz_url );
                            /* peek the begining */
                            if( p_file_stream &&
                                vlc_stream_Peek( p_file_stream, &p_peek, 4 ) >= 4
                                && p_peek[0] == 0x1a && p_peek[1] == 0x45 &&
                                p_peek[2] == 0xdf && p_peek[3] == 0xa3 ) file_ok = true;

                            if ( file_ok )
                            {
                                vlc_stream_io_callback *p_file_io = new vlc_stream_io_callback( p_file_stream, true );
                                EbmlStream *p_estream = new EbmlStream(*p_file_io);

                                p_stream = p_sys->AnalyseAllSegmentsFound( p_demux, p_estream );

                                if ( p_stream == NULL )
                                {
                                    msg_Dbg( p_demux, "the file '%s' will not be used", s_filename.c_str() );
                                    delete p_estream;
                                    delete p_file_io;
                                }
                                else
                                {
                                    p_stream->p_io_callback = p_file_io;
                                    p_stream->p_estream = p_estream;
                                    p_sys->streams.push_back( p_stream );
                                }
                            }
                            else
                            {
                                if( p_file_stream ) {
                                    vlc_stream_Delete( p_file_stream );
                                }
                                msg_Dbg( p_demux, "the file '%s' cannot be opened", s_filename.c_str() );
                            }
                            free( psz_url );
                        }
                    }
                }
                closedir( p_src_dir );
            }
        }

        p_sys->PreloadFamily( *p_segment );
    }
    else if (b_need_preload)
        msg_Warn( p_demux, "This file references other files, you may want to enable the preload of local directory");

    if ( !p_sys->PreloadLinked() ||
         !p_sys->PreparePlayback( *p_sys->p_current_vsegment, 0 ) )
    {
        msg_Err( p_demux, "cannot use the segment" );
        goto error;
    }

    p_sys->FreeUnused();

    p_sys->InitUi();

    return VLC_SUCCESS;

error:
    delete p_sys;
    return VLC_EGENERIC;
}
Ejemplo n.º 21
0
static int Retrieve( addons_finder_t *p_finder, addon_entry_t *p_entry )
{
    vlc_mutex_lock( &p_entry->lock );
    if ( !p_entry->psz_archive_uri )
    {
        vlc_mutex_unlock( &p_entry->lock );
        return VLC_EGENERIC;
    }
    char *psz_archive_uri = strdup( p_entry->psz_archive_uri );
    vlc_mutex_unlock( &p_entry->lock );
    if ( !psz_archive_uri )
        return VLC_ENOMEM;

    /* get archive and parse manifest */
    stream_t *p_stream;

    if ( psz_archive_uri[0] == '/' )
    {
        /* Relative path */
        char *psz_uri;
        if ( ! asprintf( &psz_uri, ADDONS_REPO_SCHEMEHOST"%s", psz_archive_uri ) )
        {
            free( psz_archive_uri );
            return VLC_ENOMEM;
        }
        p_stream = vlc_stream_NewURL_ND( p_finder, psz_uri );
        free( psz_uri );
    }
    else
    {
        p_stream = vlc_stream_NewURL_ND( p_finder, psz_archive_uri );
    }

    msg_Dbg( p_finder, "downloading archive %s", psz_archive_uri );
    free ( psz_archive_uri );
    if ( !p_stream ) return VLC_EGENERIC;

    /* In case of pf_ reuse */
    if ( p_finder->p_sys->psz_tempfile )
    {
        vlc_unlink( p_finder->p_sys->psz_tempfile );
        FREENULL( p_finder->p_sys->psz_tempfile );
    }

    p_finder->p_sys->psz_tempfile = tempnam( NULL, "vlp" );
    if ( !p_finder->p_sys->psz_tempfile )
    {
        msg_Err( p_finder, "Can't create temp storage file" );
        vlc_stream_Delete( p_stream );
        return VLC_EGENERIC;
    }

    FILE *p_destfile = vlc_fopen( p_finder->p_sys->psz_tempfile, "w" );
    if( !p_destfile )
    {
        msg_Err( p_finder, "Failed to open addon temp storage file" );
        FREENULL(p_finder->p_sys->psz_tempfile);
        vlc_stream_Delete( p_stream );
        return VLC_EGENERIC;
    }

    char buffer[1<<10];
    int i_read = 0;
    while ( ( i_read = vlc_stream_Read( p_stream, &buffer, 1<<10 ) ) > 0 )
    {
        if ( fwrite( &buffer, i_read, 1, p_destfile ) < 1 )
        {
            msg_Err( p_finder, "Failed to write to Addon file" );
            fclose( p_destfile );
            vlc_stream_Delete( p_stream );
            return VLC_EGENERIC;
        }
    }
    fclose( p_destfile );
    vlc_stream_Delete( p_stream );

    msg_Dbg( p_finder, "Reading manifest from %s", p_finder->p_sys->psz_tempfile );

    char *psz_tempfileuri = vlc_path2uri( p_finder->p_sys->psz_tempfile, NULL );
    if ( !psz_tempfileuri )
        return VLC_ENOMEM;

    char *psz_manifest_uri;
    if ( asprintf( &psz_manifest_uri, "%s#!/manifest.xml", psz_tempfileuri ) < 1 )
    {
        free( psz_tempfileuri );
        return VLC_ENOMEM;
    }

    p_stream = vlc_stream_NewMRL( p_finder, psz_manifest_uri );
    free( psz_manifest_uri );
    if ( !p_stream )
    {
        free( psz_tempfileuri );
        return VLC_EGENERIC;
    }

    vlc_mutex_lock( &p_entry->lock );
    int i_ret = ( ParseManifest( p_finder, p_entry, psz_tempfileuri, p_stream ) > 0 )
                    ? VLC_SUCCESS : VLC_EGENERIC;
    vlc_mutex_unlock( &p_entry->lock );
    free( psz_tempfileuri );
    vlc_stream_Delete( p_stream );

    return i_ret;
}
Ejemplo n.º 22
0
Archivo: update.c Proyecto: IAPark/vlc
/**
 * Get the update file and parse it
 * p_update has to be locked when calling this function
 *
 * \param p_update pointer to update struct
 * \return true if the update is valid and authenticated
 */
static bool GetUpdateFile( update_t *p_update )
{
    stream_t *p_stream = NULL;
    char *psz_version_line = NULL;
    char *psz_update_data = NULL;

    p_stream = vlc_stream_NewURL( p_update->p_libvlc, UPDATE_VLC_STATUS_URL );
    if( !p_stream )
    {
        msg_Err( p_update->p_libvlc, "Failed to open %s for reading",
                 UPDATE_VLC_STATUS_URL );
        goto error;
    }

    uint64_t i_read;
    if( vlc_stream_GetSize( p_stream, &i_read ) || i_read >= UINT16_MAX )
    {
        msg_Err(p_update->p_libvlc, "Status file too large");
        goto error;
    }

    psz_update_data = malloc( i_read + 1 ); /* terminating '\0' */
    if( !psz_update_data )
        goto error;

    if( vlc_stream_Read( p_stream, psz_update_data,
                         i_read ) != (ssize_t)i_read )
    {
        msg_Err( p_update->p_libvlc, "Couldn't download update file %s",
                UPDATE_VLC_STATUS_URL );
        goto error;
    }
    psz_update_data[i_read] = '\0';

    vlc_stream_Delete( p_stream );
    p_stream = NULL;

    /* first line : version number */
    char *psz_update_data_parser = psz_update_data;
    size_t i_len = strcspn( psz_update_data, "\r\n" );
    psz_update_data_parser += i_len;
    while( *psz_update_data_parser == '\r' || *psz_update_data_parser == '\n' )
        psz_update_data_parser++;

    if( !(psz_version_line = malloc( i_len + 1)) )
        goto error;
    strncpy( psz_version_line, psz_update_data, i_len );
    psz_version_line[i_len] = '\0';

    p_update->release.i_extra = 0;
    int ret = sscanf( psz_version_line, "%i.%i.%i.%i",
                    &p_update->release.i_major, &p_update->release.i_minor,
                    &p_update->release.i_revision, &p_update->release.i_extra);
    if( ret != 3 && ret != 4 )
    {
            msg_Err( p_update->p_libvlc, "Update version false formatted" );
            goto error;
    }

    /* second line : URL */
    i_len = strcspn( psz_update_data_parser, "\r\n" );
    if( i_len == 0 )
    {
        msg_Err( p_update->p_libvlc, "Update file %s is corrupted: URL missing",
                 UPDATE_VLC_STATUS_URL );

        goto error;
    }

    if( !(p_update->release.psz_url = malloc( i_len + 1)) )
        goto error;
    strncpy( p_update->release.psz_url, psz_update_data_parser, i_len );
    p_update->release.psz_url[i_len] = '\0';

    psz_update_data_parser += i_len;
    while( *psz_update_data_parser == '\r' || *psz_update_data_parser == '\n' )
        psz_update_data_parser++;

    /* Remaining data : description */
    i_len = strlen( psz_update_data_parser );
    if( i_len == 0 )
    {
        msg_Err( p_update->p_libvlc,
                "Update file %s is corrupted: description missing",
                UPDATE_VLC_STATUS_URL );
        goto error;
    }

    if( !(p_update->release.psz_desc = malloc( i_len + 1)) )
        goto error;
    strncpy( p_update->release.psz_desc, psz_update_data_parser, i_len );
    p_update->release.psz_desc[i_len] = '\0';

    /* Now that we know the status is valid, we must download its signature
     * to authenticate it */
    signature_packet_t sign;
    if( download_signature( VLC_OBJECT( p_update->p_libvlc ), &sign,
            UPDATE_VLC_STATUS_URL ) != VLC_SUCCESS )
    {
        msg_Err( p_update->p_libvlc, "Couldn't download signature of status file" );
        goto error;
    }

    if( sign.type != BINARY_SIGNATURE && sign.type != TEXT_SIGNATURE )
    {
        msg_Err( p_update->p_libvlc, "Invalid signature type" );
        goto error;
    }

    p_update->p_pkey = (public_key_t*)malloc( sizeof( public_key_t ) );
    if( !p_update->p_pkey )
        goto error;

    if( parse_public_key( videolan_public_key, sizeof( videolan_public_key ),
                        p_update->p_pkey, NULL ) != VLC_SUCCESS )
    {
        msg_Err( p_update->p_libvlc, "Couldn't parse embedded public key, something went really wrong..." );
        FREENULL( p_update->p_pkey );
        goto error;
    }

    memcpy( p_update->p_pkey->longid, videolan_public_key_longid, 8 );

    if( memcmp( sign.issuer_longid, p_update->p_pkey->longid , 8 ) != 0 )
    {
        msg_Dbg( p_update->p_libvlc, "Need to download the GPG key" );
        public_key_t *p_new_pkey = download_key(
                VLC_OBJECT(p_update->p_libvlc),
                sign.issuer_longid, videolan_public_key_longid );
        if( !p_new_pkey )
        {
            msg_Err( p_update->p_libvlc, "Couldn't download GPG key" );
            FREENULL( p_update->p_pkey );
            goto error;
        }

        uint8_t *p_hash = hash_from_public_key( p_new_pkey );
        if( !p_hash )
        {
            msg_Err( p_update->p_libvlc, "Failed to hash signature" );
            free( p_new_pkey );
            FREENULL( p_update->p_pkey );
            goto error;
        }

        if( verify_signature( &p_new_pkey->sig,
                    &p_update->p_pkey->key, p_hash ) == VLC_SUCCESS )
        {
            free( p_hash );
            msg_Info( p_update->p_libvlc, "Key authenticated" );
            free( p_update->p_pkey );
            p_update->p_pkey = p_new_pkey;
        }
        else
        {
            free( p_hash );
            msg_Err( p_update->p_libvlc, "Key signature invalid !" );
            goto error;
        }
    }

    uint8_t *p_hash = hash_from_text( psz_update_data, &sign );
    if( !p_hash )
    {
        msg_Warn( p_update->p_libvlc, "Can't compute hash for status file" );
        goto error;
    }

    else if( p_hash[0] != sign.hash_verification[0] ||
        p_hash[1] != sign.hash_verification[1] )
    {
        msg_Warn( p_update->p_libvlc, "Bad hash for status file" );
        free( p_hash );
        goto error;
    }

    else if( verify_signature( &sign, &p_update->p_pkey->key, p_hash )
            != VLC_SUCCESS )
    {
        msg_Err( p_update->p_libvlc, "BAD SIGNATURE for status file" );
        free( p_hash );
        goto error;
    }

    else
    {
        msg_Info( p_update->p_libvlc, "Status file authenticated" );
        free( p_hash );
        free( psz_version_line );
        free( psz_update_data );
        return true;
    }

error:
    if( p_stream )
        vlc_stream_Delete( p_stream );
    free( psz_version_line );
    free( psz_update_data );
    return false;
}
Ejemplo n.º 23
0
/*****************************************************************************
 * Handshake : Init audioscrobbler connection
 *****************************************************************************/
static int Handshake(intf_thread_t *p_this)
{
    char                *psz_username, *psz_password;
    char                *psz_scrobbler_url;
    time_t              timestamp;
    char                psz_timestamp[21];

    struct md5_s        p_struct_md5;

    stream_t            *p_stream;
    char                *psz_handshake_url;
    uint8_t             p_buffer[1024];
    char                *p_buffer_pos;

    int                 i_ret;
    char                *psz_url;

    intf_thread_t       *p_intf                 = (intf_thread_t*) p_this;
    intf_sys_t          *p_sys                  = p_this->p_sys;

    psz_username = var_InheritString(p_this, "lastfm-username");
    psz_password = var_InheritString(p_this, "lastfm-password");

    /* username or password have not been setup */
    if (EMPTY_STR(psz_username) || EMPTY_STR(psz_password))
    {
        free(psz_username);
        free(psz_password);
        return VLC_ENOVAR;
    }

    time(&timestamp);

    /* generates a md5 hash of the password */
    InitMD5(&p_struct_md5);
    AddMD5(&p_struct_md5, (uint8_t*) psz_password, strlen(psz_password));
    EndMD5(&p_struct_md5);

    free(psz_password);

    char *psz_password_md5 = psz_md5_hash(&p_struct_md5);
    if (!psz_password_md5)
    {
        free(psz_username);
        return VLC_ENOMEM;
    }

    snprintf(psz_timestamp, sizeof(psz_timestamp), "%"PRIu64,
              (uint64_t)timestamp);

    /* generates a md5 hash of :
     * - md5 hash of the password, plus
     * - timestamp in clear text
     */
    InitMD5(&p_struct_md5);
    AddMD5(&p_struct_md5, (uint8_t*) psz_password_md5, 32);
    AddMD5(&p_struct_md5, (uint8_t*) psz_timestamp, strlen(psz_timestamp));
    EndMD5(&p_struct_md5);
    free(psz_password_md5);

    char *psz_auth_token = psz_md5_hash(&p_struct_md5);
    if (!psz_auth_token)
    {
        free(psz_username);
        return VLC_ENOMEM;
    }

    psz_scrobbler_url = var_InheritString(p_this, "scrobbler-url");
    if (!psz_scrobbler_url)
    {
        free(psz_auth_token);
        free(psz_username);
        return VLC_ENOMEM;
    }

    i_ret = asprintf(&psz_handshake_url,
    "http://%s/?hs=true&p=1.2&c="CLIENT_NAME"&v="CLIENT_VERSION"&u=%s&t=%s&a=%s"
    , psz_scrobbler_url, psz_username, psz_timestamp, psz_auth_token);

    free(psz_auth_token);
    free(psz_scrobbler_url);
    free(psz_username);
    if (i_ret == -1)
        return VLC_ENOMEM;

    /* send the http handshake request */
    p_stream = vlc_stream_NewURL(p_intf, psz_handshake_url);
    free(psz_handshake_url);

    if (!p_stream)
        return VLC_EGENERIC;

    /* read answer */
    i_ret = vlc_stream_Read(p_stream, p_buffer, sizeof(p_buffer) - 1);
    if (i_ret <= 0)
    {
        vlc_stream_Delete(p_stream);
        return VLC_EGENERIC;
    }
    p_buffer[i_ret] = '\0';
    vlc_stream_Delete(p_stream);

    p_buffer_pos = strstr((char*) p_buffer, "FAILED ");
    if (p_buffer_pos)
    {
        /* handshake request failed, sorry */
        msg_Err(p_this, "last.fm handshake failed: %s", p_buffer_pos + 7);
        return VLC_EGENERIC;
    }

    if (strstr((char*) p_buffer, "BADAUTH"))
    {
        /* authentication failed, bad username/password combination */
        vlc_dialog_display_error(p_this,
            _("last.fm: Authentication failed"),
            "%s", _("last.fm username or password is incorrect. "
              "Please verify your settings and relaunch VLC."));
        return VLC_AUDIOSCROBBLER_EFATAL;
    }

    if (strstr((char*) p_buffer, "BANNED"))
    {
        /* oops, our version of vlc has been banned by last.fm servers */
        msg_Err(p_intf, "This version of VLC has been banned by last.fm. "
                         "You should upgrade VLC, or disable the last.fm plugin.");
        return VLC_AUDIOSCROBBLER_EFATAL;
    }

    if (strstr((char*) p_buffer, "BADTIME"))
    {
        /* The system clock isn't good */
        msg_Err(p_intf, "last.fm handshake failed because your clock is too "
                         "much shifted. Please correct it, and relaunch VLC.");
        return VLC_AUDIOSCROBBLER_EFATAL;
    }

    p_buffer_pos = strstr((char*) p_buffer, "OK");
    if (!p_buffer_pos)
        goto proto;

    p_buffer_pos = strstr(p_buffer_pos, "\n");
    if (!p_buffer_pos || strlen(p_buffer_pos) < 33)
        goto proto;
    p_buffer_pos++; /* we skip the '\n' */

    /* save the session ID */
    memcpy(p_sys->psz_auth_token, p_buffer_pos, 32);
    p_sys->psz_auth_token[32] = '\0';

    p_buffer_pos = strstr(p_buffer_pos, "http://");
    if (!p_buffer_pos || strlen(p_buffer_pos) == 7)
        goto proto;

    /* We need to read the nowplaying url */
    psz_url = strndup(p_buffer_pos, strcspn(p_buffer_pos, "\n"));
    if (!psz_url)
        goto oom;

    vlc_UrlParse(&p_sys->p_nowp_url, psz_url);
    free(psz_url);
    if (p_sys->p_nowp_url.psz_host == NULL ||
        p_sys->p_nowp_url.i_port == 0)
    {
        vlc_UrlClean(&p_sys->p_nowp_url);
        goto proto;
    }
    p_buffer_pos += strcspn(p_buffer_pos, "\n");

    p_buffer_pos = strstr(p_buffer_pos, "http://");
    if (!p_buffer_pos || strlen(p_buffer_pos) == 7)
        goto proto;

    /* We need to read the submission url */
    psz_url = strndup(p_buffer_pos, strcspn(p_buffer_pos, "\n"));
    if (!psz_url)
        goto oom;

    /* parse the submission url */
    vlc_UrlParse(&p_sys->p_submit_url, psz_url);
    free(psz_url);
    if (p_sys->p_submit_url.psz_host == NULL ||
        p_sys->p_submit_url.i_port == 0)
    {
        vlc_UrlClean(&p_sys->p_nowp_url);
        vlc_UrlClean(&p_sys->p_submit_url);
        goto proto;
    }

    return VLC_SUCCESS;

oom:
    return VLC_ENOMEM;

proto:
    msg_Err(p_intf, "Handshake: can't recognize server protocol");
    return VLC_EGENERIC;
}
Ejemplo n.º 24
0
int RarAccessOpen(vlc_object_t *object)
{
    access_t *access = (access_t*)object;

    const char *name = strchr(access->psz_location, '|');
    if (name == NULL)
        return VLC_EGENERIC;

    char *base = strndup(access->psz_location, name - access->psz_location);
    if (unlikely(base == NULL))
        return VLC_ENOMEM;

    name++;
    vlc_uri_decode(base);

    stream_t *s = vlc_stream_NewMRL(access, base);
    if (!s || RarProbe(s))
        goto error;

    struct
    {
        int filescount;
        rar_file_t **files;
        unsigned int i_nbvols;
    } newscheme = { 0, NULL, 0 }, oldscheme = { 0, NULL, 0 }, *p_scheme;

    if (RarParse(s, &newscheme.filescount, &newscheme.files, &newscheme.i_nbvols, false)
            || newscheme.filescount < 1 || newscheme.i_nbvols < 2 )
    {
        /* We might want to lookup old naming scheme, could be a part1.rar,part1.r00 */
        vlc_stream_Seek(s, 0);
        RarParse(s, &oldscheme.filescount, &oldscheme.files, &oldscheme.i_nbvols, true);
    }

    if (oldscheme.filescount >= newscheme.filescount && oldscheme.i_nbvols > newscheme.i_nbvols)
    {
        for (int i = 0; i < newscheme.filescount; i++)
            RarFileDelete(newscheme.files[i]);
        free(newscheme.files);
        p_scheme = &oldscheme;
        msg_Dbg(s, "using rar old naming for %d files nbvols %u", p_scheme->filescount, oldscheme.i_nbvols);
    }
    else if (newscheme.filescount)
    {
        for (int i = 0; i < oldscheme.filescount; i++)
            RarFileDelete(oldscheme.files[i]);
        free(oldscheme.files);
        p_scheme = &newscheme;
        msg_Dbg(s, "using rar new naming for %d files nbvols %u", p_scheme->filescount, oldscheme.i_nbvols);
    }
    else
    {
        msg_Info(s, "Invalid or unsupported RAR archive");
        for (int i = 0; i < oldscheme.filescount; i++)
            RarFileDelete(oldscheme.files[i]);
        free(oldscheme.files);
        for (int i = 0; i < newscheme.filescount; i++)
            RarFileDelete(newscheme.files[i]);
        free(newscheme.files);
        goto error;
    }

    rar_file_t *file = NULL;
    for (int i = 0; i < p_scheme->filescount; i++) {
        if (!file && !strcmp(p_scheme->files[i]->name, name))
            file = p_scheme->files[i];
        else
            RarFileDelete(p_scheme->files[i]);
    }
    free(p_scheme->files);
    if (!file)
        goto error;

    access_sys_t *sys = access->p_sys = malloc(sizeof(*sys));
    sys->s    = s;
    sys->file = file;

    access->pf_read    = Read;
    access->pf_block   = NULL;
    access->pf_control = Control;
    access->pf_seek    = Seek;

    rar_file_chunk_t dummy = {
        .mrl = base,
    };
    sys->chunk = &dummy;
    Seek(access, 0);

    free(base);
    return VLC_SUCCESS;

error:
    if (s)
        vlc_stream_Delete(s);
    free(base);
    return VLC_EGENERIC;
}