Exemplo n.º 1
0
Arquivo: rar.c Projeto: Flameeyes/vlc
static int SkipEnd(stream_t *s, const rar_block_t *hdr)
{
    if (!(hdr->flags & RAR_BLOCK_END_HAS_NEXT))
        return VLC_EGENERIC;

    if (SkipBlock(s, hdr))
        return VLC_EGENERIC;

    /* Now, we need to look for a marker block,
     * It seems that there is garbage at EOF */
    for (;;) {
        const uint8_t *peek;

        if (stream_Peek(s, &peek, rar_marker_size) < rar_marker_size)
            return VLC_EGENERIC;

        if (!memcmp(peek, rar_marker, rar_marker_size))
            break;

        if (stream_Read(s, NULL, 1) != 1)
            return VLC_EGENERIC;
    }

    /* Skip marker and archive blocks */
    if (IgnoreBlock(s, RAR_BLOCK_MARKER))
        return VLC_EGENERIC;
    if (IgnoreBlock(s, RAR_BLOCK_ARCHIVE))
        return VLC_EGENERIC;

    return VLC_SUCCESS;
}
Exemplo n.º 2
0
Arquivo: rar.c Projeto: 0x0all/mpv
static int SkipEnd(struct stream *s, const rar_block_t *hdr)
{
    if (!(hdr->flags & RAR_BLOCK_END_HAS_NEXT))
        return -1;

    if (SkipBlock(s, hdr))
        return -1;

    /* Now, we need to look for a marker block,
     * It seems that there is garbage at EOF */
    for (;;) {
        bstr peek = stream_peek(s, rar_marker_size);

        if (peek.len < rar_marker_size)
            return -1;

        if (!memcmp(peek.start, rar_marker, rar_marker_size))
            break;

        if (!stream_skip(s, 1))
            return -1;
    }

    /* Skip marker and archive blocks */
    if (IgnoreBlock(s, RAR_BLOCK_MARKER))
        return -1;
    if (IgnoreBlock(s, RAR_BLOCK_ARCHIVE))
        return -1;

    return 0;
}
Exemplo n.º 3
0
int RarParse(stream_t *s, int *count, rar_file_t ***file)
{
    *count = 0;
    *file = NULL;

    /* Skip marker */
    if (IgnoreBlock(s, RAR_BLOCK_MARKER))
        return VLC_EGENERIC;

    /* Skip archive  */
    if (IgnoreBlock(s, RAR_BLOCK_ARCHIVE))
        return VLC_EGENERIC;

    /* */
    for (;;) {
        rar_block_t bk;
        int ret;

        if (PeekBlock(s, &bk))
            break;

        switch(bk.type) {
        case RAR_BLOCK_END:
            ret = SkipEnd(s, &bk);
            break;
        case RAR_BLOCK_FILE:
            ret = SkipFile(s, count, file, &bk);
            break;
        default:
            ret = SkipBlock(s, &bk);
            break;
        }
        if (ret)
            break;
    }

    return VLC_SUCCESS;
}
Exemplo n.º 4
0
Arquivo: rar.c Projeto: Flameeyes/vlc
int RarParse(stream_t *s, int *count, rar_file_t ***file)
{
    *count = 0;
    *file = NULL;

    const rar_pattern_t *pattern = FindVolumePattern(s->psz_path);
    int volume_offset = 0;

    char *volume_mrl;
    if (asprintf(&volume_mrl, "%s://%s",
                 s->psz_access, s->psz_path) < 0)
        return VLC_EGENERIC;

    stream_t *vol = s;
    for (;;) {
        /* Skip marker & archive */
        if (IgnoreBlock(vol, RAR_BLOCK_MARKER) ||
            IgnoreBlock(vol, RAR_BLOCK_ARCHIVE)) {
            if (vol != s)
                stream_Delete(vol);
            free(volume_mrl);
            return VLC_EGENERIC;
        }

        /* */
        bool has_next = false;
        for (;;) {
            rar_block_t bk;
            int ret;

            if (PeekBlock(vol, &bk))
                break;

            switch(bk.type) {
            case RAR_BLOCK_END:
                ret = SkipEnd(vol, &bk);
                has_next = ret && (bk.flags & RAR_BLOCK_END_HAS_NEXT);
                break;
            case RAR_BLOCK_FILE:
                ret = SkipFile(vol, count, file, &bk, volume_mrl);
                break;
            default:
                ret = SkipBlock(vol, &bk);
                break;
            }
            if (ret)
                break;
        }
        if (vol != s)
            stream_Delete(vol);

        if (!has_next || !pattern ||
            (*count > 0 && !(*file)[*count -1]->is_complete)) {
            free(volume_mrl);
            return VLC_SUCCESS;
        }

        /* Open next volume */
        const int volume_index = pattern->start + volume_offset++;
        if (volume_index > pattern->stop) {
            free(volume_mrl);
            return VLC_SUCCESS;
        }

        char *volume_base;
        if (asprintf(&volume_base, "%s://%.*s",
                     s->psz_access,
                     (int)(strlen(s->psz_path) - strlen(pattern->match)), s->psz_path) < 0) {
            free(volume_mrl);
            return VLC_SUCCESS;
        }

        free(volume_mrl);
        if (asprintf(&volume_mrl, pattern->format, volume_base, volume_index) < 0)
            volume_mrl = NULL;
        free(volume_base);

        if (!volume_mrl)
            return VLC_SUCCESS;
        vol = stream_UrlNew(s, volume_mrl);

        if (!vol) {
            free(volume_mrl);
            return VLC_SUCCESS;
        }
    }
}
Exemplo n.º 5
0
Arquivo: rar.c Projeto: 0x0all/mpv
int RarParse(struct stream *s, int *count, rar_file_t ***file)
{
    *count = 0;
    *file = NULL;

    const rar_pattern_t *pattern = FindVolumePattern(s->url);
    int volume_offset = 0;

    char *volume_mrl;
    if (asprintf(&volume_mrl, "%s", s->url) < 0)
        return -1;

    struct stream *vol = s;
    for (;;) {
        /* Skip marker & archive */
        if (IgnoreBlock(vol, RAR_BLOCK_MARKER) ||
            IgnoreBlock(vol, RAR_BLOCK_ARCHIVE)) {
            if (vol != s)
                free_stream(vol);
            free(volume_mrl);
            return -1;
        }

        /* */
        int has_next = -1;
        for (;;) {
            rar_block_t bk;
            int ret;

            if (PeekBlock(vol, &bk))
                break;

            switch(bk.type) {
            case RAR_BLOCK_END:
                ret = SkipEnd(vol, &bk);
                has_next = ret && (bk.flags & RAR_BLOCK_END_HAS_NEXT);
                break;
            case RAR_BLOCK_FILE:
                ret = SkipFile(vol, count, file, &bk, volume_mrl);
                break;
            default:
                ret = SkipBlock(vol, &bk);
                break;
            }
            if (ret)
                break;
        }
        if (has_next < 0 && *count > 0 && !(*file)[*count -1]->is_complete)
            has_next = 1;
        if (vol != s)
            free_stream(vol);

        if (!has_next || !pattern)
            goto done;

        /* Open next volume */
        const int volume_index = pattern->start + volume_offset++;
        if (volume_index > pattern->stop)
            goto done;

        char *volume_base;
        if (asprintf(&volume_base, "%.*s",
                     (int)(strlen(s->url) - strlen(pattern->match)), s->url) < 0) {
            goto done;
        }

        free(volume_mrl);
        if (pattern->start) {
            if (asprintf(&volume_mrl, pattern->format, volume_base, volume_index) < 0)
                volume_mrl = NULL;
        } else {
            if (asprintf(&volume_mrl, pattern->format, volume_base,
                         'r' + volume_index / 100, volume_index % 100) < 0)
                volume_mrl = NULL;
        }
        free(volume_base);

        if (!volume_mrl)
            goto done;

        vol = stream_create(volume_mrl, STREAM_READ | STREAM_NO_FILTERS,
                            s->cancel, s->global);

        if (!vol)
            goto done;
    }

done:
    free(volume_mrl);
    if (*count == 0) {
        talloc_free(*file);
        return -1;
    }
    return 0;
}
Exemplo n.º 6
0
Arquivo: rar.c Projeto: qdk0901/vlc
int RarParse(stream_t *s, int *count, rar_file_t ***file, unsigned int *pi_nbvols,
             bool b_extonly)
{
    *count = 0;
    *file = NULL;
    *pi_nbvols = 1;

    if( s->psz_url == NULL )
        return VLC_EGENERIC;

    const rar_pattern_t *pattern = FindVolumePattern(s->psz_url, b_extonly);
    int volume_offset = 0;

    char *volume_mrl = strdup(s->psz_url);
    if (volume_mrl == NULL)
        return VLC_ENOMEM;

    stream_t *vol = s;
    for (;;) {
        /* Skip marker & archive */
        if (IgnoreBlock(vol, RAR_BLOCK_MARKER) ||
            IgnoreBlock(vol, RAR_BLOCK_ARCHIVE)) {
            if (vol != s)
                stream_Delete(vol);
            free(volume_mrl);
            return VLC_EGENERIC;
        }

        /* */
        int has_next = -1;
        for (;;) {
            rar_block_t bk;
            int ret;

            if (PeekBlock(vol, &bk))
                break;

            switch(bk.type) {
            case RAR_BLOCK_END:
                ret = SkipEnd(vol, &bk);
                has_next = ret && (bk.flags & RAR_BLOCK_END_HAS_NEXT);
                break;
            case RAR_BLOCK_FILE:
                ret = SkipFile(vol, count, file, &bk, volume_mrl);
                break;
            default:
                ret = SkipBlock(vol, &bk);
                break;
            }
            if (ret)
                break;
        }
        if (has_next < 0 && *count > 0 && !(*file)[*count -1]->is_complete)
            has_next = 1;
        if (vol != s)
            stream_Delete(vol);
        free(volume_mrl);

        if (!has_next || !pattern)
            return VLC_SUCCESS;

        /* Open next volume */
        const int volume_index = pattern->start + volume_offset++;
        if (volume_index > pattern->stop)
            return VLC_SUCCESS;

        char *volume_base = strndup(s->psz_url,
                                  strlen(s->psz_url) - strlen(pattern->match));
        if (volume_base == NULL)
            return VLC_SUCCESS;

        if (pattern->start) {
            if (asprintf(&volume_mrl, pattern->format, volume_base, volume_index) < 0)
                volume_mrl = NULL;
        } else {
            if (asprintf(&volume_mrl, pattern->format, volume_base,
                         'r' + volume_index / 100, volume_index % 100) < 0)
                volume_mrl = NULL;
        }
        free(volume_base);

        if (!volume_mrl)
            return VLC_SUCCESS;

        const int s_flags = s->i_flags;
        s->i_flags |= OBJECT_FLAGS_NOINTERACT;
        vol = stream_UrlNew(s, volume_mrl);
        s->i_flags = s_flags;

        if (!vol) {
            free(volume_mrl);
            return VLC_SUCCESS;
        }
        (*pi_nbvols)++;
    }
}