int
archive_read_support_compression_all(struct archive *a)
{
	/* Bzip falls back to "bunzip2" command-line */
	archive_read_support_compression_bzip2(a);
	/* The decompress code doesn't use an outside library. */
	archive_read_support_compression_compress(a);
	/* Gzip decompress falls back to "gunzip" command-line. */
	archive_read_support_compression_gzip(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_compression_lzma(a);
	/* Xz falls back to "unxz" command-line program. */
	archive_read_support_compression_xz(a);
	/* The decode code doesn't use an outside library. */
	archive_read_support_compression_uu(a);
	/* The decode code doesn't use an outside library. */
#ifndef __minix
	archive_read_support_compression_rpm(a);
#endif
	/* 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);
}
Esempio n. 2
0
/**
 * @brief Creates a new FreeBSD package from a FILE pointer
 * @param fd A pointer to a FILE object containing a FreeBSD Package
 *
 * This creates a pkg object from a given file pointer.
 * It is able to then manipulate the package and install the it to the pkg_db.
 * @todo Write
 * @return A new package object or NULL
 */
struct pkg *
pkg_new_freebsd_from_file(FILE *fd)
{
	struct pkg *pkg;
	struct freebsd_package *fpkg;
	const char *pkg_name;

	if (fd == NULL)
		return NULL;

	/* Create the new package data object */
	fpkg = freebsd_package_new();
	if (fpkg == NULL)
		return NULL;

	fpkg->fd = fd;
	fpkg->pkg_type = fpkg_from_file;
	fpkg->archive = archive_read_new();
	archive_read_support_compression_bzip2(fpkg->archive);
	archive_read_support_compression_gzip(fpkg->archive);
	archive_read_support_format_tar(fpkg->archive);
	archive_read_open_stream(fpkg->archive, fd, 10240);
	
	/*
	 * Get the +CONTENTS file.
	 * We can't use the callbacks as we need the
	 * package name to use with pkg_new
	 */
	freebsd_open_control_files(fpkg);
	assert(fpkg->control != NULL);

	freebsd_parse_contents(fpkg);
	assert(fpkg->contents != NULL);
	if (fpkg->contents->lines[1].line_type != PKG_LINE_NAME) {
		/** @todo cleanup */
		return NULL;
	}

	pkg_name = fpkg->contents->lines[1].data;
	pkg = pkg_new(pkg_name, freebsd_get_control_files,
	    freebsd_get_control_file, freebsd_get_deps, freebsd_free);
	if (pkg == NULL) {
		/** @todo cleanup */
		return NULL;
	}
	pkg_add_callbacks_data(pkg, freebsd_get_version, freebsd_get_origin);
	pkg_add_callbacks_install(pkg, freebsd_get_next_file,
	    freebsd_run_script);
	pkg->data = fpkg;

	return pkg;
}
int
archive_read_support_compression_all(struct archive *a)
{
#if HAVE_BZLIB_H
	archive_read_support_compression_bzip2(a);
#endif
	/* The decompress code doesn't use an outside library. */
	archive_read_support_compression_compress(a);
#if HAVE_ZLIB_H
	archive_read_support_compression_gzip(a);
#endif
	return (ARCHIVE_OK);
}
Esempio n. 4
0
/*
 * 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_compression_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);

	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
	assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
}
Esempio n. 5
0
/*
 * Returns a pointer to be placed into the data of the Package object
 */
static struct freebsd_package *
freebsd_get_package(FILE *fd)
{
	struct freebsd_package *f_pkg;
	struct pkg_file *file;
	size_t control_size;
	unsigned int control_pos;

	f_pkg = malloc(sizeof(struct freebsd_package));
	if (!f_pkg) {
		return NULL;
	}

	/* Init the struct */
	f_pkg->next = NULL;
	f_pkg->control = NULL;
	f_pkg->contents = NULL;
	f_pkg->fd = fd;

	/* We only need to read from gzip and bzip2 as they
	 * are the only posible file types for FreeBSD packages
	 */
	f_pkg->archive = archive_read_new();
	archive_read_support_compression_bzip2(f_pkg->archive);
	archive_read_support_compression_gzip(f_pkg->archive);
	archive_read_support_format_tar(f_pkg->archive);

	if (archive_read_open_stream(f_pkg->archive, fd, 10240)
	    != ARCHIVE_OK) {
		freebsd_free_package(f_pkg);
		return NULL;
	}

	/* Read the first file and check it has the correct name */
	file = freebsd_get_next_entry(f_pkg->archive);
	if (!file) {
		freebsd_free_package(f_pkg);
		return NULL;
	} else if (strcmp(file->filename, "+CONTENTS")) {
		/* Package error */
		pkg_file_free(file);
		freebsd_free_package(f_pkg);
		return NULL;
	}
	/* Set the control files array to be big enough for
	 * the +CONTENTS file and a null terminator
	 */
	f_pkg->contents = pkg_freebsd_contents_new(file->contents);
	control_size = sizeof(struct pkg_file *) * 2;
	f_pkg->control = malloc(control_size);
	f_pkg->control[0] = file;
	f_pkg->control[1] = NULL;
	control_pos = 1;

	/* Add all the control files to the control array */
	while (1) {
		file = freebsd_get_next_entry(f_pkg->archive);
		if (file == NULL) {
			break;
		} else if (file->filename[0] != '+') {
			f_pkg->next = file;
			break;
		} else {
			control_size += sizeof(struct pkg_file *);
			f_pkg->control = realloc(f_pkg->control, control_size);
			f_pkg->control[control_pos] = file;
			control_pos++;
			f_pkg->control[control_pos] = NULL;
		}
	}

	return f_pkg;
}
Esempio n. 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

}
Esempio n. 7
0
void Package::readPackageFile(const std::string &package_path)
{
    if (!package_path.empty())
        mPackagePath = package_path;

    boost::filesystem::path unpacked_dir = mWorkDir;
    unpacked_dir /= mPackagePath.stem();
    mUnpackedDir = unpacked_dir;

    const void *buf;

    int r;

    struct archive *a = archive_read_new();
    struct archive_entry *entry;

    archive_read_support_compression_bzip2(a);
    archive_read_support_format_tar(a);


    struct archive *ext = archive_write_disk_new();
    int flags = ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_ACL | ARCHIVE_EXTRACT_FFLAGS;
    archive_write_disk_set_options(ext, flags);
    archive_write_disk_set_standard_lookup(ext);

    r = archive_read_open_filename(a, package_path.c_str(), 16384);
    if (r != ARCHIVE_OK) {
        archive_read_free(a);
        archive_write_free(ext);
        throw Exception(std::string("archive_read_open_filename() failed for file: ") + package_path);
    }

    while (true) {

        r = archive_read_next_header(a, &entry);
        if (r == ARCHIVE_EOF) {
            break;
        }
        if (r < ARCHIVE_OK) {
            std::cerr << archive_error_string(ext) << std::endl;
        }
        if (r < ARCHIVE_WARN) {
            archive_read_free(a);
            archive_write_free(ext);
            throw Exception(std::string("archive_read_next_header() failed:") + archive_error_string(a));
        }

        std::cout << std::string("extract: ") << archive_entry_pathname(entry) << std::endl;
        archive_entry_set_pathname(entry, (mUnpackedDir.string() + std::string("/") + archive_entry_pathname(entry)).c_str());

        r = archive_write_header(ext, entry);
        if (r < ARCHIVE_OK) {
            archive_read_free(a);
            archive_write_free(ext);
            throw Exception(std::string("archive_write_header() failed:") + archive_error_string(ext));
        } else if (archive_entry_size(entry) > 0) {

            size_t size;
            int64_t offset;
            while (true) {
                r = archive_read_data_block(a, &buf, &size, &offset);
                if (r == ARCHIVE_EOF)
                    break;
                if (r < ARCHIVE_WARN) {
                    archive_read_free(a);
                    archive_write_free(ext);
                    throw Exception(std::string(archive_error_string(ext)));
                }
                if (r < ARCHIVE_OK) {
                    std::cerr << archive_error_string(ext) << std::endl;
                    break;
                }

                r = archive_write_data_block(ext, buf, size, offset);
                if (r < ARCHIVE_WARN) {
                    archive_read_free(a);
                    archive_write_free(ext);
                    throw Exception(std::string(archive_error_string(ext)));
                }
                if (r < ARCHIVE_OK) {
                    std::cerr << archive_error_string(ext) << std::endl;
                    break;
                }
            }


            r = archive_write_finish_entry(ext);
            if (r < ARCHIVE_OK)
                std::cerr << archive_error_string(ext) << std::endl;
            if (r < ARCHIVE_WARN) {
                archive_read_free(a);
                archive_write_free(ext);
                throw Exception(std::string(archive_error_string(ext)));
            }
        }
    }
    archive_read_close(a);
    archive_read_free(a);
    archive_write_close(ext);
    archive_write_free(ext);
}
Esempio n. 8
0
int archive_extract_tar_bzip2(void) {
	struct archive *a;
	struct archive *ext;
	int r = 0;
	int flags = 0;
	int error = 0;
	
	a = archive_read_new();
	archive_read_support_format_tar(a);
	archive_read_support_compression_bzip2(a);
	
	ext = archive_write_disk_new();
	archive_write_disk_set_options(ext, flags);

	if ((r = archive_read_open_file(a, NULL, 10240))) {
		fprintf(stderr, "archiving: %s", archive_error_string(a));
		error = r;
	}
	else {
		for (;;) {
			struct archive_entry *entry;
			r = archive_read_next_header(a, &entry);
			if (r == ARCHIVE_EOF) { break; }
			if (r != ARCHIVE_OK) {
				fprintf(stderr, "archiving: %s", archive_error_string(a));
				error = 1;
				break;
			}
			if (archive_write_header(ext, entry) != ARCHIVE_OK) {
				fprintf(stderr, "archiving: %s", archive_error_string(ext));
			}
			else {
				const void *buff;
				size_t size;
				off_t offset;
				
				for (;;) {
					r = archive_read_data_block(a, &buff, &size, &offset);
					if (r == ARCHIVE_EOF) { r = ARCHIVE_OK; break; }
					if (r != ARCHIVE_OK) {
						fprintf(stderr, "archiving: %s", archive_error_string(ext));
						break;
					}
					r = archive_write_data_block(ext, buff, size, offset);
					if (r != ARCHIVE_OK) {
						fprintf(stderr, "archiving: %s", archive_error_string(ext));
						break;
					}
				}
				if (r != ARCHIVE_OK) {
					error = 1;
					break;
				}
				
				r = archive_write_finish_entry(ext);
				if (r != ARCHIVE_OK) {
					fprintf(stderr, "archiving: %s", archive_error_string(ext));
					error = 1;
					break;
				}
			}
		}
	}
	archive_read_close(a);
	archive_read_finish(a);
	
	return error;
}
Esempio n. 9
0
int HIDDEN
xbps_unpack_binary_pkg(struct xbps_handle *xhp, xbps_dictionary_t pkg_repod)
{
	struct archive *ar = NULL;
	struct stat st;
	const char *pkgver;
	char *bpkg = NULL;
	int pkg_fd = -1, rv = 0;

	assert(xbps_object_type(pkg_repod) == XBPS_TYPE_DICTIONARY);

	xbps_dictionary_get_cstring_nocopy(pkg_repod, "pkgver", &pkgver);
	xbps_set_cb_state(xhp, XBPS_STATE_UNPACK, 0, pkgver, NULL);

	bpkg = xbps_repository_pkg_path(xhp, pkg_repod);
	if (bpkg == NULL) {
		xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL,
		    errno, pkgver,
		    "%s: [unpack] cannot determine binary package "
		    "file for `%s': %s", pkgver, bpkg, strerror(errno));
		return errno;
	}

	if ((ar = archive_read_new()) == NULL) {
		free(bpkg);
		return ENOMEM;
	}
	/*
	 * Enable support for tar format and gzip/bzip2/lzma compression methods.
	 */
	archive_read_support_compression_gzip(ar);
	archive_read_support_compression_bzip2(ar);
	archive_read_support_compression_xz(ar);
	archive_read_support_format_tar(ar);

	pkg_fd = open(bpkg, O_RDONLY|O_CLOEXEC);
	if (pkg_fd == -1) {
		rv = errno;
		xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL,
		    rv, pkgver,
		    "%s: [unpack] failed to open binary package `%s': %s",
		    pkgver, bpkg, strerror(rv));
		goto out;
	}
	if (fstat(pkg_fd, &st) == -1) {
		rv = errno;
		xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL,
		    rv, pkgver,
		    "%s: [unpack] failed to fstat binary package `%s': %s",
		    pkgver, bpkg, strerror(rv));
		goto out;
	}
	if (archive_read_open_fd(ar, pkg_fd, st.st_blksize) == ARCHIVE_FATAL) {
		rv = archive_errno(ar);
		xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL,
		    rv, pkgver,
		    "%s: [unpack] failed to read binary package `%s': %s",
		    pkgver, bpkg, strerror(rv));
		goto out;
	}
	/*
	 * Extract archive files.
	 */
	if ((rv = unpack_archive(xhp, pkg_repod, pkgver, bpkg, ar)) != 0) {
		xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL,
		    rv, pkgver,
		    "%s: [unpack] failed to unpack files from archive: %s",
		    pkgver, strerror(rv));
		goto out;
	}
	/*
	 * Set package state to unpacked.
	 */
	if ((rv = xbps_set_pkg_state_installed(xhp, pkgver,
	    XBPS_PKG_STATE_UNPACKED)) != 0) {
		xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL,
		    rv, pkgver,
		    "%s: [unpack] failed to set state to unpacked: %s",
		    pkgver, strerror(rv));
	}
out:
	if (pkg_fd != -1)
		close(pkg_fd);
	if (ar)
		archive_read_finish(ar);
	if (bpkg)
		free(bpkg);

	return rv;
}
Esempio n. 10
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_compression_bzip2(a);
#endif
#ifndef NO_GZIP_EXTRACT
    archive_read_support_compression_gzip(a);
#endif
#ifndef NO_COMPRESS_EXTRACT
    archive_read_support_compression_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_file(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_finish(a);
    exit(0);
}