int
archive_read_support_filter_all(struct archive *a)
{
	archive_check_magic(a, ARCHIVE_READ_MAGIC,
	    ARCHIVE_STATE_NEW, "archive_read_support_filter_all");

	/* Bzip falls back to "bunzip2" command-line */
	archive_read_support_filter_bzip2(a);
	/* The decompress code doesn't use an outside library. */
	archive_read_support_filter_compress(a);
	/* Gzip decompress falls back to "gunzip" command-line. */
	archive_read_support_filter_gzip(a);
	/* Lzip falls back to "unlzip" command-line program. */
	archive_read_support_filter_lzip(a);
	/* The LZMA file format has a very weak signature, so it
	 * may not be feasible to keep this here, but we'll try.
	 * This will come back out if there are problems. */
	/* Lzma falls back to "unlzma" command-line program. */
	archive_read_support_filter_lzma(a);
	/* Xz falls back to "unxz" command-line program. */
	archive_read_support_filter_xz(a);
	/* The decode code doesn't use an outside library. */
	archive_read_support_filter_uu(a);
	/* The decode code doesn't use an outside library. */
	archive_read_support_filter_rpm(a);

	/* Note: We always return ARCHIVE_OK here, even if some of the
	 * above return ARCHIVE_WARN.  The intent here is to enable
	 * "as much as possible."  Clients who need specific
	 * compression should enable those individually so they can
	 * verify the level of support. */
	/* Clear any warning messages set by the above functions. */
	archive_clear_error(a);
	return (ARCHIVE_OK);
}
Exemple #2
0
struct mp_archive *mp_archive_new(struct mp_log *log, struct stream *src,
                                  int flags)
{
    struct mp_archive *mpa = talloc_zero(NULL, struct mp_archive);
    mpa->log = log;
    mpa->locale = newlocale(LC_ALL_MASK, "C.UTF-8", (locale_t)0);
    if (!mpa->locale)
        goto err;
    mpa->arch = archive_read_new();
    mpa->primary_src = src;
    if (!mpa->arch)
        goto err;

    // first volume is the primary streame
    if (!add_volume(log ,mpa, src, src->url))
        goto err;

    // try to open other volumes
    char** volumes = find_volumes(src);
    for (int i = 0; volumes[i]; i++) {
        if (!add_volume(log, mpa, NULL, volumes[i])) {
            talloc_free(volumes);
            goto err;
        }
    }
    talloc_free(volumes);

    locale_t oldlocale = uselocale(mpa->locale);

    archive_read_support_format_7zip(mpa->arch);
    archive_read_support_format_iso9660(mpa->arch);
    archive_read_support_format_rar(mpa->arch);
    archive_read_support_format_zip(mpa->arch);
    archive_read_support_filter_bzip2(mpa->arch);
    archive_read_support_filter_gzip(mpa->arch);
    archive_read_support_filter_xz(mpa->arch);
    if (flags & MP_ARCHIVE_FLAG_UNSAFE) {
        archive_read_support_format_gnutar(mpa->arch);
        archive_read_support_format_tar(mpa->arch);
    }

    archive_read_set_read_callback(mpa->arch, read_cb);
    archive_read_set_skip_callback(mpa->arch, skip_cb);
    archive_read_set_switch_callback(mpa->arch, switch_cb);
    archive_read_set_open_callback(mpa->arch, open_cb);
    archive_read_set_close_callback(mpa->arch, close_cb);
    if (mpa->primary_src->seekable)
        archive_read_set_seek_callback(mpa->arch, seek_cb);
    bool fail = archive_read_open1(mpa->arch) < ARCHIVE_OK;

    uselocale(oldlocale);

    if (fail)
        goto err;
    return mpa;

err:
    mp_archive_free(mpa);
    return NULL;
}
void extract(char* filename) {
    archive *a = archive_read_new();
    archive_read_support_filter_bzip2(a);
    archive_read_support_format_7zip(a);

    archive_read_open_filename(a, filename, 10240);

    archive_entry *entry;
    archive_read_next_header(a, &entry);
    archive_read_data_into_fd(a, 1);

    archive_read_free(a);
}
void print_size(char* filename) {
    archive *a = archive_read_new();
    archive_read_support_filter_bzip2(a);
    archive_read_support_format_7zip(a);

    archive_read_open_filename(a, filename, 10240);

    archive_entry *entry;
    archive_read_next_header(a, &entry);

    std::cout << archive_entry_size(entry);

    archive_read_free(a);
}
/*
 * All of the sample files have the same contents; they're just
 * compressed in different ways.
 */
static void
compat_bzip2(const char *name)
{
	const char *n[7] = { "f1", "f2", "f3", "d1/f1", "d1/f2", "d1/f3", NULL };
	struct archive_entry *ae;
	struct archive *a;
	int i;

	assert((a = archive_read_new()) != NULL);
	if (ARCHIVE_OK != archive_read_support_filter_bzip2(a)) {
		skipping("Unsupported bzip2");
		return;
	}
	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
	extract_reference_file(name);
	assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 2));

	/* Read entries, match up names with list above. */
	for (i = 0; i < 6; ++i) {
		failure("Could not read file %d (%s) from %s", i, n[i], name);
		assertEqualIntA(a, ARCHIVE_OK,
		    archive_read_next_header(a, &ae));
		assertEqualString(n[i], archive_entry_pathname(ae));
	}

	/* Verify the end-of-archive. */
	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));

	/* Verify that the format detection worked. */
	assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_BZIP2);
	assertEqualString(archive_compression_name(a), "bzip2");
	assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR);

	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
	assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_BZIP2);
	assertEqualString(archive_compression_name(a), "bzip2");
	assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR);

	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
Exemple #6
0
static void extract_archive(const char *filename, const char *output)
{
    struct archive *a;
    struct archive *ext;
    struct archive_entry *entry;
    int flags;
    int r;

    flags = ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_SECURE_NODOTDOT;

    a = archive_read_new();
#if ARCHIVE_VERSION_NUMBER < 4000000
    archive_read_support_compression_bzip2(a);
#else
    archive_read_support_filter_bzip2(a);
#endif
    archive_read_support_format_tar(a);

    ext = archive_write_disk_new();
    archive_write_disk_set_options(ext, flags);
    archive_write_disk_set_standard_lookup(ext);

    r = archive_read_open_file(a, filename, 10240);

    if (r) {
        std::string msg = extract_archive_error(filename, output, a);

	archive_read_close(a);
#if ARCHIVE_VERSION_NUMBER < 4000000
        archive_read_finish(a);
#else
	archive_read_free(a);
#endif

        throw utils::InternalError(msg);
    }

    for (;;) {
        r = archive_read_next_header(a, &entry);
        if (r == ARCHIVE_EOF) {
            break;
        }

        if (r != ARCHIVE_OK) {
            std::string msg = extract_archive_error(filename, output, a);

            archive_read_close(a);
#if ARCHIVE_VERSION_NUMBER < 4000000
            archive_read_finish(a);
#else
            archive_read_free(a);
#endif

            archive_write_close(ext);
#if ARCHIVE_VERSION_NUMBER < 4000000
            archive_write_finish(ext);
#else
            archive_write_free(ext);
#endif

            throw utils::InternalError(msg);
        }

        if (r < ARCHIVE_WARN) {
            break;
        }

        r = archive_write_header(ext, entry);

        if (r != ARCHIVE_OK) {
            std::string msg = extract_archive_error(filename, output, a);

            archive_read_close(a);
#if ARCHIVE_VERSION_NUMBER < 4000000
            archive_read_finish(a);
#else
            archive_read_free(a);
#endif
            archive_write_close(ext);
#if ARCHIVE_VERSION_NUMBER < 4000000
            archive_write_finish(ext);
#else
            archive_write_free(ext);
#endif

            throw utils::InternalError(msg);
        } else {
            r = copy_data(a, ext);

            if (r != ARCHIVE_OK) {
                std::string msg = extract_archive_error(filename, output, a);

                archive_read_close(a);
#if ARCHIVE_VERSION_NUMBER < 4000000
                archive_read_finish(a);
#else
                archive_read_free(a);
#endif
                archive_write_close(ext);
#if ARCHIVE_VERSION_NUMBER < 4000000
                archive_write_finish(ext);
#else
                archive_write_free(ext);
#endif


                throw utils::InternalError(msg);
            }
        }
    }

    archive_read_close(a);
#if ARCHIVE_VERSION_NUMBER < 4000000
    archive_read_finish(a);
#else
    archive_read_free(a);
#endif
    archive_write_close(ext);
#if ARCHIVE_VERSION_NUMBER < 4000000
    archive_write_finish(ext);
#else
    archive_write_free(ext);
#endif

}
int
archive_read_append_filter(struct archive *_a, int code)
{
    int r1, r2, number_bidders, i;
    char str[20];
    struct archive_read_filter_bidder *bidder;
    struct archive_read_filter *filter;
    struct archive_read *a = (struct archive_read *)_a;

    r1 = r2 = (ARCHIVE_OK);
    switch (code)
    {
    case ARCHIVE_FILTER_NONE:
        /* No filter to add, so do nothing.
         * NOTE: An initial "NONE" type filter is always set at the end of the
         * filter chain.
         */
        r1 = (ARCHIVE_OK);
        break;
    case ARCHIVE_FILTER_GZIP:
        strcpy(str, "gzip");
        r1 = archive_read_support_filter_gzip(_a);
        break;
    case ARCHIVE_FILTER_BZIP2:
        strcpy(str, "bzip2");
        r1 = archive_read_support_filter_bzip2(_a);
        break;
    case ARCHIVE_FILTER_COMPRESS:
        strcpy(str, "compress (.Z)");
        r1 = archive_read_support_filter_compress(_a);
        break;
    case ARCHIVE_FILTER_PROGRAM:
        archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
                          "Cannot append program filter using archive_read_append_filter");
        return (ARCHIVE_FATAL);
    case ARCHIVE_FILTER_LZMA:
        strcpy(str, "lzma");
        r1 = archive_read_support_filter_lzma(_a);
        break;
    case ARCHIVE_FILTER_XZ:
        strcpy(str, "xz");
        r1 = archive_read_support_filter_xz(_a);
        break;
    case ARCHIVE_FILTER_UU:
        strcpy(str, "uu");
        r1 = archive_read_support_filter_uu(_a);
        break;
    case ARCHIVE_FILTER_RPM:
        strcpy(str, "rpm");
        r1 = archive_read_support_filter_rpm(_a);
        break;
    case ARCHIVE_FILTER_LZIP:
        strcpy(str, "lzip");
        r1 = archive_read_support_filter_lzip(_a);
        break;
    case ARCHIVE_FILTER_LRZIP:
        strcpy(str, "lrzip");
        r1 = archive_read_support_filter_lrzip(_a);
        break;
    default:
        archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
                          "Invalid filter code specified");
        return (ARCHIVE_FATAL);
    }

    if (code != ARCHIVE_FILTER_NONE)
    {
        number_bidders = sizeof(a->bidders) / sizeof(a->bidders[0]);

        bidder = a->bidders;
        for (i = 0; i < number_bidders; i++, bidder++)
        {
            if (!bidder->name || !strcmp(bidder->name, str))
                break;
        }
        if (!bidder->name || strcmp(bidder->name, str))
        {
            archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
                              "Internal error: Unable to append filter");
            return (ARCHIVE_FATAL);
        }

        filter
            = (struct archive_read_filter *)calloc(1, sizeof(*filter));
        if (filter == NULL)
        {
            archive_set_error(&a->archive, ENOMEM, "Out of memory");
            return (ARCHIVE_FATAL);
        }
        filter->bidder = bidder;
        filter->archive = a;
        filter->upstream = a->filter;
        a->filter = filter;
        r2 = (bidder->init)(a->filter);
        if (r2 != ARCHIVE_OK) {
            __archive_read_close_filters(a);
            __archive_read_free_filters(a);
            return (ARCHIVE_FATAL);
        }
    }

    a->bypass_filter_bidding = 1;
    return (r1 < r2) ? r1 : r2;
}
Exemple #8
0
static void
extract(const char *filename, int do_extract, int flags)
{
	struct archive *a;
	struct archive *ext;
	struct archive_entry *entry;
	int r;

	a = archive_read_new();
	ext = archive_write_disk_new();
	archive_write_disk_set_options(ext, flags);
#ifndef NO_BZIP2_EXTRACT
	archive_read_support_filter_bzip2(a);
#endif
#ifndef NO_GZIP_EXTRACT
	archive_read_support_filter_gzip(a);
#endif
#ifndef NO_COMPRESS_EXTRACT
	archive_read_support_filter_compress(a);
#endif
#ifndef NO_TAR_EXTRACT
	archive_read_support_format_tar(a);
#endif
#ifndef NO_CPIO_EXTRACT
	archive_read_support_format_cpio(a);
#endif
#ifndef NO_LOOKUP
	archive_write_disk_set_standard_lookup(ext);
#endif
	if (filename != NULL && strcmp(filename, "-") == 0)
		filename = NULL;
	if ((r = archive_read_open_filename(a, filename, 10240))) {
		errmsg(archive_error_string(a));
		errmsg("\n");
		exit(r);
	}
	for (;;) {
		r = archive_read_next_header(a, &entry);
		if (r == ARCHIVE_EOF)
			break;
		if (r != ARCHIVE_OK) {
			errmsg(archive_error_string(a));
			errmsg("\n");
			exit(1);
		}
		if (verbose && do_extract)
			msg("x ");
		if (verbose || !do_extract)
			msg(archive_entry_pathname(entry));
		if (do_extract) {
			r = archive_write_header(ext, entry);
			if (r != ARCHIVE_OK)
				errmsg(archive_error_string(a));
			else
				copy_data(a, ext);
		}
		if (verbose || !do_extract)
			msg("\n");
	}
	archive_read_close(a);
	archive_read_free(a);
	exit(0);
}
/* Deprecated; remove in libarchive 4.0 */
int
archive_read_support_compression_bzip2(struct archive *a)
{
	return archive_read_support_filter_bzip2(a);
}
Exemple #10
0
void mfu_flist_archive_extract(const char* filename, bool verbose, int flags)
{
    int r;

    /* TODO: this needs to be parallelized */

    /* initiate archive object for reading */
    struct archive* a = archive_read_new();

    /* initiate archive object for writing */
    struct archive* ext = archive_write_disk_new();
    archive_write_disk_set_options(ext, flags);

    /* we want all the format supports */
    archive_read_support_filter_bzip2(a);
    archive_read_support_filter_gzip(a);
    archive_read_support_filter_compress(a);
    archive_read_support_format_tar(a);

    archive_write_disk_set_standard_lookup(ext);

    if (filename != NULL && strcmp(filename, "-") == 0) {
        filename = NULL;
    }

    /* blocksize set to 1024K */
    if ((r = archive_read_open_filename(a, filename, 10240))) {
        errmsg(archive_error_string(a));
        exit(r);
    }

    struct archive_entry* entry;
    for (;;) {
        r = archive_read_next_header(a, &entry);
        if (r == ARCHIVE_EOF) {
            break;
        }
        if (r != ARCHIVE_OK) {
            errmsg(archive_error_string(a));
            exit(r);
        }

        if (verbose) {
            msg("x ");
        }

        if (verbose) {
            msg(archive_entry_pathname(entry));
        }

        r = archive_write_header(ext, entry);
        if (r != ARCHIVE_OK) {
            errmsg(archive_error_string(a));
        } else {
            copy_data(a, ext);
        }

        if (verbose) {
            msg("\n");
        }
    }

    archive_read_close(a);
    archive_read_free(a);
}
static void verify(unsigned char *d, size_t s,
    void (*f1)(struct archive *, struct archive_entry *),
    void (*f2)(struct archive *, struct archive_entry *),
    enum enc etype)
{
	struct archive_entry *ae;
	struct archive *a;
	unsigned char *buff;
	int r;

	assert((a = archive_read_new()) != NULL);
	switch (etype) {
	case BZIP2:
		/* This is only check whether bzip is supported or not.
		 * This filter won't be used this test.  */
		if (ARCHIVE_OK != archive_read_support_filter_bzip2(a)) {
			skipping("Unsupported bzip2");
			assertEqualInt(ARCHIVE_OK, archive_read_free(a));
			return;
		}
		break;
	case GZIP:
		/* This gzip must be needed. archive_read_support_format_xar()
		 * will return a warning if gzip is unsupported. */
		break;
	}
	assertA(0 == archive_read_support_filter_all(a));
	r = archive_read_support_format_xar(a);
	if (r == ARCHIVE_WARN) {
		skipping("xar reading not fully supported on this platform");
		assertEqualInt(ARCHIVE_OK, archive_read_free(a));
		return;
	}
	assert((buff = malloc(100000)) != NULL);
	if (buff == NULL)
		return;
	memcpy(buff, d, s);
	memset(buff + s, 0, 2048);

	assertA(0 == archive_read_support_format_all(a));
	assertA(0 == archive_read_open_memory(a, buff, s + 1024));
	assertA(0 == archive_read_next_header(a, &ae));
	assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_NONE);
	assertEqualInt(archive_format(a), ARCHIVE_FORMAT_XAR);
	/* Verify the only entry. */
	f1(a, ae);
	if (f2) {
		assertA(0 == archive_read_next_header(a, &ae));
		assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_NONE);
		assertEqualInt(archive_format(a), ARCHIVE_FORMAT_XAR);
		/* Verify the only entry. */
		f2(a, ae);
		assertEqualInt(2, archive_file_count(a));
	} else {
		assertEqualInt(1, archive_file_count(a));
	}
	/* End of archive. */
	assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae));

	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
	free(buff);
}