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); }
/* * All of the sample files have the same contents; they're just * compressed in different ways. */ static void compat_xz(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, r; assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a)); r = archive_read_support_compression_xz(a); if (r == ARCHIVE_WARN) { skipping("xz reading not fully supported on this platform"); assertEqualInt(ARCHIVE_OK, archive_read_finish(a)); 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_XZ); assertEqualString(archive_compression_name(a), "xz"); assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR); assertEqualInt(ARCHIVE_OK, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, archive_read_finish(a)); }
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; }