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); }
/** * @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); }
/* * 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)); }
/* * 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; }
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 }
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); }
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; }
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; }
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); }