static void verify(unsigned char *d, size_t s, void (*f)(struct archive_entry *), int compression, int format) { struct archive_entry *ae; struct archive *a; unsigned char *buff = malloc(100000); memcpy(buff, d, s); memset(buff + s, 0, 2048); assert((a = archive_read_new()) != NULL); assertA(0 == archive_read_support_compression_all(a)); 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), compression); assertEqualInt(archive_format(a), format); /* Verify the only entry. */ f(ae); assert(0 == archive_read_close(a)); #if ARCHIVE_VERSION_NUMBER < 2000000 archive_read_finish(a); #else assert(0 == archive_read_finish(a)); #endif free(buff); }
/* This function doesn't work as well as one might think, as size of database * entries varies considerably. Adding signatures nearly doubles the size of a * single entry; deltas also can make for large variations in size. These * current values are heavily influenced by Arch Linux; databases with no * deltas and a single signature per package. */ static size_t estimate_package_count(struct stat *st, struct archive *archive) { int per_package; switch(archive_compression(archive)) { case ARCHIVE_COMPRESSION_NONE: per_package = 3015; break; case ARCHIVE_COMPRESSION_GZIP: case ARCHIVE_COMPRESSION_COMPRESS: per_package = 464; break; case ARCHIVE_COMPRESSION_BZIP2: per_package = 394; break; case ARCHIVE_COMPRESSION_LZMA: case ARCHIVE_COMPRESSION_XZ: per_package = 400; break; #ifdef ARCHIVE_COMPRESSION_UU case ARCHIVE_COMPRESSION_UU: per_package = 3015 * 4 / 3; break; #endif default: /* assume it is at least somewhat compressed */ per_package = 500; } return (size_t)((st->st_size / per_package) + 1); }
/* For sequentially stepping through all files in the archive */ static int arxive_get_next_header(arc_handle_t ar, tar_header* hdr) { char buffer[ARC_BLOCKSIZE]; off_t o = 0; size_t s = sizeof(buffer); const char* p = buffer; file_ptr_t entry; if (archive_read_next_header(ar, &entry) != ARCHIVE_OK) return -1; hdr->compressed = archive_compression(ar); hdr->size = archive_entry_size(entry); hdr->hdr_offset = archive_read_header_position(ar); hdr->data_offset = archive_read_data_position(ar); hdr->atime = archive_entry_atime(entry); hdr->mtime = archive_entry_mtime(entry); hdr->mode = archive_entry_mode(entry); hdr->uid = archive_entry_uid(entry); hdr->gid = archive_entry_gid(entry); hdr->reg_file = S_ISREG(hdr->mode); strncpy(hdr->name, archive_entry_pathname(entry), sizeof(hdr->name) - 1); return 0; }
/* * An archive file has no entry. */ static void test_empty_archive() { const char *refname = "test_read_format_7zip_empty_archive.7z"; struct archive_entry *ae; struct archive *a; extract_reference_file(refname); assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240)); /* End of archive. */ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); assertEqualInt(0, archive_file_count(a)); /* Verify archive format. */ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a)); assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a)); /* Close the archive. */ assertEqualInt(ARCHIVE_OK, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); }
static void test_compat_tar_hardlink_1(void) { char name[] = "test_compat_tar_hardlink_1.tar"; struct archive_entry *ae; struct archive *a; assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); extract_reference_file(name); assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240)); /* Read first entry, which is a regular file. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString("xmcd-3.3.2/docs_d/READMf", archive_entry_pathname(ae)); assertEqualString(NULL, archive_entry_hardlink(ae)); assertEqualInt(321, archive_entry_size(ae)); assertEqualInt(1082575645, archive_entry_mtime(ae)); assertEqualInt(1851, archive_entry_uid(ae)); assertEqualInt(3, archive_entry_gid(ae)); assertEqualInt(0100444, archive_entry_mode(ae)); /* Read second entry, which is a hard link at the end of archive. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString("xmcd-3.3.2/README", archive_entry_pathname(ae)); assertEqualString( "xmcd-3.3.2/docs_d/READMf", archive_entry_hardlink(ae)); assertEqualInt(0, archive_entry_size(ae)); assertEqualInt(1082575645, archive_entry_mtime(ae)); assertEqualInt(1851, archive_entry_uid(ae)); assertEqualInt(3, archive_entry_gid(ae)); assertEqualInt(0100444, archive_entry_mode(ae)); /* Verify the end-of-archive. */ /* * This failed in libarchive 2.4.12 because the tar reader * tried to obey the size field for the hard link and ended * up running past the end of the file. */ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); /* Verify that the format detection worked. */ assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_NONE); assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR); assertEqualInt(ARCHIVE_OK, archive_read_close(a)); #if ARCHIVE_VERSION_NUMBER < 2000000 archive_read_finish(a); #else assertEqualInt(ARCHIVE_OK, archive_read_finish(a)); #endif }
/* * 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)); }
static void test_read_format_cab_filename_CP932_eucJP(const char *refname) { struct archive *a; struct archive_entry *ae; /* * Read CAB filename in ja_JP.eucJP with "hdrcharset=CP932" option. */ if (NULL == setlocale(LC_ALL, "ja_JP.eucJP")) { skipping("ja_JP.eucJP locale not available on this system."); return; } assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP932")) { skipping("This system cannot convert character-set" " from CP932 to eucJP."); goto cleanup; } assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240)); /* Verify regular file. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString( "\xc9\xbd\xa4\xc0\xa4\xe8\x2f\xb4\xc1\xbb\xfa\x2e\x74\x78\x74", archive_entry_pathname(ae)); assertEqualInt(5, archive_entry_size(ae)); /* Verify regular file. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString( "\xc9\xbd\xa4\xc0\xa4\xe8\x2f\xb0\xec\xcd\xf7\xc9\xbd\x2e\x74\x78\x74", archive_entry_pathname(ae)); assertEqualInt(5, archive_entry_size(ae)); /* End of archive. */ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); /* Verify archive format. */ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a)); assertEqualIntA(a, ARCHIVE_FORMAT_CAB, archive_format(a)); /* Close the archive. */ cleanup: assertEqualInt(ARCHIVE_OK, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); }
/* * Extract a file compressed with PPMd. */ static void test_ppmd() { const char *refname = "test_read_format_7zip_ppmd.7z"; struct archive_entry *ae; struct archive *a; size_t remaining; ssize_t bytes; char buff[1024]; extract_reference_file(refname); assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240)); /* Verify regular file1. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualInt((AE_IFREG | 0777), archive_entry_mode(ae)); assertEqualString("ppmd_test.txt", archive_entry_pathname(ae)); assertEqualInt(1322464589, archive_entry_mtime(ae)); assertEqualInt(102400, archive_entry_size(ae)); remaining = (size_t)archive_entry_size(ae); while (remaining) { if (remaining < sizeof(buff)) assertEqualInt(remaining, bytes = archive_read_data(a, buff, sizeof(buff))); else assertEqualInt(sizeof(buff), bytes = archive_read_data(a, buff, sizeof(buff))); if (bytes > 0) remaining -= bytes; else break; } assertEqualInt(0, remaining); assertEqualInt(1, archive_file_count(a)); /* End of archive. */ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); /* Verify archive format. */ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a)); assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a)); /* Close the archive. */ assertEqualInt(ARCHIVE_OK, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); }
/* Copy this function for each test file and adjust it accordingly. */ static void test_compat_zip_1(void) { char name[] = "test_compat_zip_1.zip"; struct archive_entry *ae; struct archive *a; int r; assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); extract_reference_file(name); assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240)); /* Read first entry. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString("META-INF/MANIFEST.MF", archive_entry_pathname(ae)); /* Read second entry. */ r = archive_read_next_header(a, &ae); if (r != ARCHIVE_OK) { if (strcmp(archive_error_string(a), "libarchive compiled without deflate support (no libz)") == 0) { skipping("Skipping ZIP compression check: %s", archive_error_string(a)); goto finish; } } assertEqualIntA(a, ARCHIVE_OK, r); assertEqualString("tmp.class", archive_entry_pathname(ae)); assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_NONE); assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ZIP); assertEqualInt(ARCHIVE_OK, archive_read_close(a)); finish: #if ARCHIVE_VERSION_NUMBER < 2000000 archive_read_finish(a); #else assertEqualInt(ARCHIVE_OK, archive_read_finish(a)); #endif }
static void test_symname() { const char *refname = "test_read_format_7zip_symbolic_name.7z"; struct archive_entry *ae; struct archive *a; char buff[128]; extract_reference_file(refname); assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240)); /* Verify regular file1. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); assertEqualString("file1", archive_entry_pathname(ae)); assertEqualInt(86401, archive_entry_mtime(ae)); assertEqualInt(32, archive_entry_size(ae)); assertEqualInt(32, archive_read_data(a, buff, sizeof(buff))); assertEqualMem(buff, "hellohellohello\nhellohellohello\n", 32); /* Verify symbolic-linke symlinkfile. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualInt((AE_IFLNK | 0755), archive_entry_mode(ae)); assertEqualString("symlinkfile", archive_entry_pathname(ae)); assertEqualString("file1", archive_entry_symlink(ae)); assertEqualInt(86401, archive_entry_mtime(ae)); assertEqualInt(2, archive_file_count(a)); /* End of archive. */ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); /* Verify archive format. */ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a)); assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a)); /* Close the archive. */ assertEqualInt(ARCHIVE_OK, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); }
static void verifyEmpty(void) { struct archive_entry *ae; struct archive *a; assert((a = archive_read_new()) != NULL); assertA(0 == archive_read_support_compression_all(a)); assertA(0 == archive_read_support_format_all(a)); assertA(0 == archive_read_open_memory(a, archiveEmpty, 512)); assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_NONE); failure("512 zero bytes should be recognized as a tar archive."); assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR); assert(0 == archive_read_close(a)); #if ARCHIVE_API_VERSION > 1 assert(0 == archive_read_finish(a)); #else archive_read_finish(a); #endif }
static void test2(void) { struct archive_entry *ae; struct archive *a; const char *name = "test_read_format_iso_2.iso.Z"; extract_reference_file(name); assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 512)); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString(".", archive_entry_pathname(ae)); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString("A", archive_entry_pathname(ae)); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString("A/B", archive_entry_pathname(ae)); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString("C", archive_entry_pathname(ae)); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString("C/D", archive_entry_pathname(ae)); assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_COMPRESS); assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660); assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, archive_read_finish(a)); }
/* Copy this function for each test file and adjust it accordingly. */ static void test_compat_zip_1(void) { char name[] = "test_compat_zip_1.zip"; struct archive_entry *ae; struct archive *a; int r; assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); extract_reference_file(name); assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240)); /* Read first entry. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString("META-INF/MANIFEST.MF", archive_entry_pathname(ae)); /* Read second entry. */ r = archive_read_next_header(a, &ae); if (r == ARCHIVE_FATAL && !libz_enabled) { skipping("Skipping ZIP compression check: %s", archive_error_string(a)); goto finish; } assertEqualIntA(a, ARCHIVE_OK, r); assertEqualString("tmp.class", archive_entry_pathname(ae)); assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_NONE); assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ZIP); finish: assertEqualInt(ARCHIVE_OK, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); }
/* * Extract an encoded file. * The header of the 7z archive files is not encoded. */ static void test_plain_header(const char *refname) { struct archive_entry *ae; struct archive *a; char buff[128]; extract_reference_file(refname); assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240)); /* Verify regular file1. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); assertEqualString("file1", archive_entry_pathname(ae)); assertEqualInt(1322058763, archive_entry_mtime(ae)); assertEqualInt(2844, archive_entry_size(ae)); assertEqualInt(sizeof(buff), archive_read_data(a, buff, sizeof(buff))); assertEqualMem(buff, "The libarchive distribution ", 28); assertEqualInt(1, archive_file_count(a)); /* End of archive. */ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); /* Verify archive format. */ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a)); assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a)); /* Close the archive. */ assertEqualInt(ARCHIVE_OK, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, 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); }
static void test_read_uu_sub(const char *uudata, size_t uusize, int no_nl) { struct archive_entry *ae; struct archive *a; char *buff; char extradata_no_nl[sizeof(extradata)]; const char *extradata_ptr; int extra; size_t size; if (no_nl) { /* Remove '\n' from extra data to make a very long line. */ char *p; memcpy(extradata_no_nl, extradata, sizeof(extradata)); extradata_ptr = extradata_no_nl; for (p = extradata_no_nl; *p && (p = strchr(p, '\n')) != NULL; p++) *p = ' ';/* Replace '\n' with ' ' a space character. */ } else extradata_ptr = extradata; assert(NULL != (buff = malloc(uusize + 1024 * 1024))); if (buff == NULL) return; for (extra = 0; extra <= 64; extra = extra==0?1:extra*2) { char *p = buff; size = extra * 1024; /* Add extra text size of which is from 1K bytes to * 64Kbytes before uuencoded data. */ while (size) { if (size > sizeof(extradata)-1) { memcpy(p, extradata_ptr, sizeof(extradata)-1); p += sizeof(extradata)-1; size -= sizeof(extradata)-1; } else { memcpy(p, extradata_ptr, size-1); p += size-1; *p++ = '\n';/* the last of extra text must have * '\n' character. */ break; } } memcpy(p, uudata, uusize); size = extra * 1024 + uusize; assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, buff, size, 2)); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); failure("archive_compression_name(a)=\"%s\"" "extra %d, NL %d", archive_compression_name(a), extra, !no_nl); assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_COMPRESS); failure("archive_format_name(a)=\"%s\"" "extra %d, NL %d", archive_format_name(a), extra, !no_nl); assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR); assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); } /* UUdecode bidder shouldn't scan too much data; make sure it * fails if we put 512k of data before the start. */ size = 512 * 1024; for (extra = 0; (size_t)extra < size; ++extra) buff[extra + 1024] = buff[extra]; buff[size - 1] = '\n'; memcpy(buff + size, uudata, uusize); size += uusize; assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); assertEqualIntA(a, ARCHIVE_FATAL, read_open_memory(a, buff, size, 2)); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); free(buff); }
void tar_mode_u(struct bsdtar *bsdtar) { off_t end_offset; struct archive *a; struct archive_entry *entry; int format; struct archive_dir_entry *p; struct archive_dir archive_dir; bsdtar->archive_dir = &archive_dir; memset(&archive_dir, 0, sizeof(archive_dir)); format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED; /* Sanity-test some arguments and the file. */ test_for_append(bsdtar); bsdtar->fd = open(bsdtar->filename, O_RDWR); if (bsdtar->fd < 0) bsdtar_errc(bsdtar, 1, errno, "Cannot open %s", bsdtar->filename); a = archive_read_new(); archive_read_support_compression_all(a); archive_read_support_format_tar(a); archive_read_support_format_gnutar(a); if (archive_read_open_fd(a, bsdtar->fd, bsdtar->bytes_per_block != 0 ? bsdtar->bytes_per_block : DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) { bsdtar_errc(bsdtar, 1, 0, "Can't open %s: %s", bsdtar->filename, archive_error_string(a)); } /* Build a list of all entries and their recorded mod times. */ while (0 == archive_read_next_header(a, &entry)) { if (archive_compression(a) != ARCHIVE_COMPRESSION_NONE) { archive_read_finish(a); close(bsdtar->fd); bsdtar_errc(bsdtar, 1, 0, "Cannot append to compressed archive."); } add_dir_list(bsdtar, archive_entry_pathname(entry), archive_entry_mtime(entry), archive_entry_mtime_nsec(entry)); /* Record the last format determination we see */ format = archive_format(a); /* Keep going until we hit end-of-archive */ } end_offset = archive_read_header_position(a); archive_read_finish(a); /* Re-open archive for writing. */ a = archive_write_new(); archive_write_set_compression_none(a); /* * Set format to same one auto-detected above, except that * we don't write GNU tar format, so use ustar instead. */ if (format == ARCHIVE_FORMAT_TAR_GNUTAR) format = ARCHIVE_FORMAT_TAR_USTAR; archive_write_set_format(a, format); if (bsdtar->bytes_per_block != 0) { archive_write_set_bytes_per_block(a, bsdtar->bytes_per_block); archive_write_set_bytes_in_last_block(a, bsdtar->bytes_per_block); } else archive_write_set_bytes_per_block(a, DEFAULT_BYTES_PER_BLOCK); lseek(bsdtar->fd, end_offset, SEEK_SET); ftruncate(bsdtar->fd, end_offset); if (ARCHIVE_OK != archive_write_set_options(a, bsdtar->option_options)) bsdtar_errc(bsdtar, 1, 0, archive_error_string(a)); if (ARCHIVE_OK != archive_write_open_fd(a, bsdtar->fd)) bsdtar_errc(bsdtar, 1, 0, archive_error_string(a)); write_archive(a, bsdtar); close(bsdtar->fd); bsdtar->fd = -1; while (bsdtar->archive_dir->head != NULL) { p = bsdtar->archive_dir->head->next; free(bsdtar->archive_dir->head->name); free(bsdtar->archive_dir->head); bsdtar->archive_dir->head = p; } bsdtar->archive_dir->tail = NULL; }
static int arxive_is_compressed(arc_handle_t ar) { return archive_compression(ar) == ARCHIVE_COMPRESSION_NONE; }
static DEB_RESULT process_meta_file(struct archive *debarchive, struct archive_entry *entry, DEB_FILE *file) { if(!debarchive || !entry || !file) return DEB_RESULT_NULL_PARAM; DEB_RESULT result = DEB_RESULT_OK; int64_t size = archive_entry_size(entry); char *buf = DEB_ALLOC(char *, size); struct archive *controlarchive = prepare_read_new_archive(); if(!controlarchive) { result = DEB_RESULT_ARCHIVE_FAIL; goto cleanup; } /* the meta data (control.tar.gz) is usually so small that it would be a waste of effort to extract it to disk.. do everything in memory :) */ if(archive_read_data(debarchive, buf, (size_t) size) != size) { result = DEB_RESULT_READ_FAIL; goto cleanup; } if(archive_read_open_memory(controlarchive, buf, (size_t) size) != ARCHIVE_OK) { result = DEB_RESULT_META_ARCHIVE_CORRUPT; goto cleanup; } DEB_COMPRESSION compression = lookup_compression( archive_compression(controlarchive) ); deb_file_set_meta_compression(file, compression); DEB_ARCHFORMAT archformat = lookup_archformat( archive_format(controlarchive) ); /* because we're reading from memory, libarchive will almost always set the archive format to 0, default to TAR */ if(archformat == DEB_ARCHFORMAT_INVALID) { archformat = DEB_ARCHFORMAT_TAR; } deb_file_set_meta_archformat(file, archformat); /* extract control file and scripts */ result = process_meta_file_contents(controlarchive, file); if(deb_result_is_bad(result)) { goto cleanup; } cleanup: if(controlarchive) { archive_read_close(controlarchive); } if(buf) { free(buf); } return result; }
/* * test_compat_gtar_1.tgz exercises reading long filenames and * symlink targets stored in the GNU tar format. */ static void test_compat_gtar_1(void) { char name[] = "test_compat_gtar_1.tar"; struct archive_entry *ae; struct archive *a; int r; assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); extract_reference_file(name); assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240)); /* Read first entry. */ assertEqualIntA(a, ARCHIVE_OK, r = archive_read_next_header(a, &ae)); if (r != ARCHIVE_OK) { archive_read_free(a); return; } assertEqualString( "12345678901234567890123456789012345678901234567890" "12345678901234567890123456789012345678901234567890" "12345678901234567890123456789012345678901234567890" "12345678901234567890123456789012345678901234567890", archive_entry_pathname(ae)); assertEqualInt(1197179003, archive_entry_mtime(ae)); assertEqualInt(1000, archive_entry_uid(ae)); assertEqualString("tim", archive_entry_uname(ae)); assertEqualInt(1000, archive_entry_gid(ae)); assertEqualString("tim", archive_entry_gname(ae)); assertEqualInt(0100644, archive_entry_mode(ae)); /* Read second entry. */ assertEqualIntA(a, ARCHIVE_OK, r = archive_read_next_header(a, &ae)); if (r != ARCHIVE_OK) { archive_read_free(a); return; } assertEqualString( "abcdefghijabcdefghijabcdefghijabcdefghijabcdefghij" "abcdefghijabcdefghijabcdefghijabcdefghijabcdefghij" "abcdefghijabcdefghijabcdefghijabcdefghijabcdefghij" "abcdefghijabcdefghijabcdefghijabcdefghijabcdefghij", archive_entry_pathname(ae)); assertEqualString( "12345678901234567890123456789012345678901234567890" "12345678901234567890123456789012345678901234567890" "12345678901234567890123456789012345678901234567890" "12345678901234567890123456789012345678901234567890", archive_entry_symlink(ae)); assertEqualInt(1197179043, archive_entry_mtime(ae)); assertEqualInt(1000, archive_entry_uid(ae)); assertEqualString("tim", archive_entry_uname(ae)); assertEqualInt(1000, archive_entry_gid(ae)); assertEqualString("tim", archive_entry_gname(ae)); assertEqualInt(0120755, archive_entry_mode(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_NONE); assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_GNUTAR); assertEqualInt(ARCHIVE_OK, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); }
bool LibArchiveInterface::addFiles(const QStringList& files, const CompressionOptions& options) { const bool creatingNewFile = !QFileInfo(filename()).exists(); const QString tempFilename = filename() + QLatin1String( ".arkWriting" ); const QString globalWorkDir = options.value(QLatin1String( "GlobalWorkDir" )).toString(); if (!globalWorkDir.isEmpty()) { kDebug() << "GlobalWorkDir is set, changing dir to " << globalWorkDir; m_workDir.setPath(globalWorkDir); QDir::setCurrent(globalWorkDir); } m_writtenFiles.clear(); ArchiveRead arch_reader; if (!creatingNewFile) { arch_reader.reset(archive_read_new()); if (!(arch_reader.data())) { emit error(i18n("The archive reader could not be initialized.")); return false; } if (archive_read_support_compression_all(arch_reader.data()) != ARCHIVE_OK) { return false; } if (archive_read_support_format_all(arch_reader.data()) != ARCHIVE_OK) { return false; } if (archive_read_open_filename(arch_reader.data(), QFile::encodeName(filename()), 10240) != ARCHIVE_OK) { emit error(i18n("The source file could not be read.")); return false; } } ArchiveWrite arch_writer(archive_write_new()); if (!(arch_writer.data())) { emit error(i18n("The archive writer could not be initialized.")); return false; } //pax_restricted is the libarchive default, let's go with that. archive_write_set_format_pax_restricted(arch_writer.data()); int ret; if (creatingNewFile) { if (filename().right(2).toUpper() == QLatin1String( "GZ" )) { kDebug() << "Detected gzip compression for new file"; ret = archive_write_set_compression_gzip(arch_writer.data()); } else if (filename().right(3).toUpper() == QLatin1String( "BZ2" )) { kDebug() << "Detected bzip2 compression for new file"; ret = archive_write_set_compression_bzip2(arch_writer.data()); #ifdef HAVE_LIBARCHIVE_XZ_SUPPORT } else if (filename().right(2).toUpper() == QLatin1String( "XZ" )) { kDebug() << "Detected xz compression for new file"; ret = archive_write_set_compression_xz(arch_writer.data()); #endif #ifdef HAVE_LIBARCHIVE_LZMA_SUPPORT } else if (filename().right(4).toUpper() == QLatin1String( "LZMA" )) { kDebug() << "Detected lzma compression for new file"; ret = archive_write_set_compression_lzma(arch_writer.data()); #endif } else if (filename().right(3).toUpper() == QLatin1String( "TAR" )) { kDebug() << "Detected no compression for new file (pure tar)"; ret = archive_write_set_compression_none(arch_writer.data()); } else { kDebug() << "Falling back to gzip"; ret = archive_write_set_compression_gzip(arch_writer.data()); } if (ret != ARCHIVE_OK) { emit error(i18nc("@info", "Setting the compression method failed with the following error: <message>%1</message>", QLatin1String(archive_error_string(arch_writer.data())))); return false; } } else { switch (archive_compression(arch_reader.data())) { case ARCHIVE_COMPRESSION_GZIP: ret = archive_write_set_compression_gzip(arch_writer.data()); break; case ARCHIVE_COMPRESSION_BZIP2: ret = archive_write_set_compression_bzip2(arch_writer.data()); break; #ifdef HAVE_LIBARCHIVE_XZ_SUPPORT case ARCHIVE_COMPRESSION_XZ: ret = archive_write_set_compression_xz(arch_writer.data()); break; #endif #ifdef HAVE_LIBARCHIVE_LZMA_SUPPORT case ARCHIVE_COMPRESSION_LZMA: ret = archive_write_set_compression_lzma(arch_writer.data()); break; #endif case ARCHIVE_COMPRESSION_NONE: ret = archive_write_set_compression_none(arch_writer.data()); break; default: emit error(i18n("The compression type '%1' is not supported by Ark.", QLatin1String(archive_compression_name(arch_reader.data())))); return false; } if (ret != ARCHIVE_OK) { emit error(i18nc("@info", "Setting the compression method failed with the following error: <message>%1</message>", QLatin1String(archive_error_string(arch_writer.data())))); return false; } } ret = archive_write_open_filename(arch_writer.data(), QFile::encodeName(tempFilename)); if (ret != ARCHIVE_OK) { emit error(i18nc("@info", "Opening the archive for writing failed with the following error: <message>%1</message>", QLatin1String(archive_error_string(arch_writer.data())))); return false; } //**************** first write the new files foreach(const QString& selectedFile, files) { bool success; success = writeFile(selectedFile, arch_writer.data()); if (!success) { QFile::remove(tempFilename); return false; } if (QFileInfo(selectedFile).isDir()) { QDirIterator it(selectedFile, QDir::AllEntries | QDir::Readable | QDir::Hidden | QDir::NoDotAndDotDot, QDirIterator::Subdirectories); while (it.hasNext()) { const QString path = it.next(); if ((it.fileName() == QLatin1String("..")) || (it.fileName() == QLatin1String("."))) { continue; } const bool isRealDir = it.fileInfo().isDir() && !it.fileInfo().isSymLink(); success = writeFile(path + (isRealDir ? QLatin1String( "/" ) : QLatin1String( "" )), arch_writer.data()); if (!success) { QFile::remove(tempFilename); return false; } } } }
/* * Extract a mixed archive file which has both LZMA and LZMA2 encoded files. * LZMA: file1, file2, file3, file4 * LZMA2: zfile1, zfile2, zfile3, zfile4 */ static void test_extract_all_files2(const char *refname) { struct archive_entry *ae; struct archive *a; char buff[128]; extract_reference_file(refname); assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240)); /* Verify regular file1. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); assertEqualString("dir1/file1", archive_entry_pathname(ae)); assertEqualInt(86401, archive_entry_mtime(ae)); assertEqualInt(13, archive_entry_size(ae)); assertEqualInt(13, archive_read_data(a, buff, sizeof(buff))); assertEqualMem(buff, "aaaaaaaaaaaa\n", 13); /* Verify regular file2. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); assertEqualString("file2", archive_entry_pathname(ae)); assertEqualInt(86401, archive_entry_mtime(ae)); assertEqualInt(26, archive_entry_size(ae)); assertEqualInt(26, archive_read_data(a, buff, sizeof(buff))); assertEqualMem(buff, "aaaaaaaaaaaa\nbbbbbbbbbbbb\n", 26); /* Verify regular file3. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); assertEqualString("file3", archive_entry_pathname(ae)); assertEqualInt(86401, archive_entry_mtime(ae)); assertEqualInt(39, archive_entry_size(ae)); assertEqualInt(39, archive_read_data(a, buff, sizeof(buff))); assertEqualMem(buff, "aaaaaaaaaaaa\nbbbbbbbbbbbb\ncccccccccccc\n", 39); /* Verify regular file4. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); assertEqualString("file4", archive_entry_pathname(ae)); assertEqualInt(86401, archive_entry_mtime(ae)); assertEqualInt(52, archive_entry_size(ae)); assertEqualInt(52, archive_read_data(a, buff, sizeof(buff))); assertEqualMem(buff, "aaaaaaaaaaaa\nbbbbbbbbbbbb\ncccccccccccc\ndddddddddddd\n", 52); /* Verify regular zfile1. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); assertEqualString("dir1/zfile1", archive_entry_pathname(ae)); assertEqualInt(5184001, archive_entry_mtime(ae)); assertEqualInt(13, archive_entry_size(ae)); assertEqualInt(13, archive_read_data(a, buff, sizeof(buff))); assertEqualMem(buff, "aaaaaaaaaaaa\n", 13); /* Verify regular zfile2. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); assertEqualString("zfile2", archive_entry_pathname(ae)); assertEqualInt(5184001, archive_entry_mtime(ae)); assertEqualInt(26, archive_entry_size(ae)); assertEqualInt(26, archive_read_data(a, buff, sizeof(buff))); assertEqualMem(buff, "aaaaaaaaaaaa\nbbbbbbbbbbbb\n", 26); /* Verify regular zfile3. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); assertEqualString("zfile3", archive_entry_pathname(ae)); assertEqualInt(5184001, archive_entry_mtime(ae)); assertEqualInt(39, archive_entry_size(ae)); assertEqualInt(39, archive_read_data(a, buff, sizeof(buff))); assertEqualMem(buff, "aaaaaaaaaaaa\nbbbbbbbbbbbb\ncccccccccccc\n", 39); /* Verify regular zfile4. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); assertEqualString("zfile4", archive_entry_pathname(ae)); assertEqualInt(5184001, archive_entry_mtime(ae)); assertEqualInt(52, archive_entry_size(ae)); assertEqualInt(52, archive_read_data(a, buff, sizeof(buff))); assertEqualMem(buff, "aaaaaaaaaaaa\nbbbbbbbbbbbb\ncccccccccccc\ndddddddddddd\n", 52); /* Verify directory dir1. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualInt((AE_IFDIR | 0755), archive_entry_mode(ae)); assertEqualString("dir1/", archive_entry_pathname(ae)); assertEqualInt(2764801, archive_entry_mtime(ae)); assertEqualInt(9, archive_file_count(a)); /* End of archive. */ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); /* Verify archive format. */ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a)); assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a)); /* Close the archive. */ assertEqualInt(ARCHIVE_OK, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); }
void tar_mode_u(struct bsdtar *bsdtar) { int64_t end_offset; struct archive *a; struct archive_entry *entry; int format; struct archive_dir_entry *p; struct archive_dir archive_dir; bsdtar->archive_dir = &archive_dir; memset(&archive_dir, 0, sizeof(archive_dir)); format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED; /* Sanity-test some arguments and the file. */ test_for_append(bsdtar); bsdtar->fd = open(bsdtar->filename, O_RDWR | O_BINARY); if (bsdtar->fd < 0) lafe_errc(1, errno, "Cannot open %s", bsdtar->filename); a = archive_read_new(); archive_read_support_filter_all(a); archive_read_support_format_tar(a); archive_read_support_format_gnutar(a); if (archive_read_open_fd(a, bsdtar->fd, bsdtar->bytes_per_block) != ARCHIVE_OK) { lafe_errc(1, 0, "Can't open %s: %s", bsdtar->filename, archive_error_string(a)); } /* Build a list of all entries and their recorded mod times. */ while (0 == archive_read_next_header(a, &entry)) { if (archive_compression(a) != ARCHIVE_COMPRESSION_NONE) { archive_read_free(a); close(bsdtar->fd); lafe_errc(1, 0, "Cannot append to compressed archive."); } add_dir_list(bsdtar, archive_entry_pathname(entry), archive_entry_mtime(entry), archive_entry_mtime_nsec(entry)); /* Record the last format determination we see */ format = archive_format(a); /* Keep going until we hit end-of-archive */ } end_offset = archive_read_header_position(a); archive_read_free(a); /* Re-open archive for writing. */ a = archive_write_new(); /* * Set format to same one auto-detected above. */ archive_write_set_format(a, format); archive_write_set_bytes_per_block(a, bsdtar->bytes_per_block); archive_write_set_bytes_in_last_block(a, bsdtar->bytes_in_last_block); if (lseek(bsdtar->fd, end_offset, SEEK_SET) < 0) lafe_errc(1, errno, "Could not seek to archive end"); if (ARCHIVE_OK != archive_write_set_options(a, bsdtar->option_options)) lafe_errc(1, 0, "%s", archive_error_string(a)); if (ARCHIVE_OK != archive_write_open_fd(a, bsdtar->fd)) lafe_errc(1, 0, "%s", archive_error_string(a)); write_archive(a, bsdtar); close(bsdtar->fd); bsdtar->fd = -1; while (bsdtar->archive_dir->head != NULL) { p = bsdtar->archive_dir->head->next; free(bsdtar->archive_dir->head->name); free(bsdtar->archive_dir->head); bsdtar->archive_dir->head = p; } bsdtar->archive_dir->tail = NULL; }
/* * Same as 'c', except we only support tar or empty formats in * uncompressed files on disk. */ void tar_mode_r(struct bsdtar *bsdtar) { int64_t end_offset; int format; struct archive *a; struct archive_entry *entry; int r; /* Sanity-test some arguments and the file. */ test_for_append(bsdtar); format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED; #if defined(__BORLANDC__) bsdtar->fd = open(bsdtar->filename, O_RDWR | O_CREAT | O_BINARY); #else bsdtar->fd = open(bsdtar->filename, O_RDWR | O_CREAT | O_BINARY, 0666); #endif if (bsdtar->fd < 0) lafe_errc(1, errno, "Cannot open %s", bsdtar->filename); a = archive_read_new(); archive_read_support_filter_all(a); archive_read_support_format_tar(a); archive_read_support_format_gnutar(a); r = archive_read_open_fd(a, bsdtar->fd, 10240); if (r != ARCHIVE_OK) lafe_errc(1, archive_errno(a), "Can't read archive %s: %s", bsdtar->filename, archive_error_string(a)); while (0 == archive_read_next_header(a, &entry)) { if (archive_compression(a) != ARCHIVE_COMPRESSION_NONE) { archive_read_free(a); close(bsdtar->fd); lafe_errc(1, 0, "Cannot append to compressed archive."); } /* Keep going until we hit end-of-archive */ format = archive_format(a); } end_offset = archive_read_header_position(a); archive_read_free(a); /* Re-open archive for writing */ a = archive_write_new(); /* * Set the format to be used for writing. To allow people to * extend empty files, we need to allow them to specify the format, * which opens the possibility that they will specify a format that * doesn't match the existing format. Hence, the following bit * of arcane ugliness. */ if (bsdtar->create_format != NULL) { /* If the user requested a format, use that, but ... */ archive_write_set_format_by_name(a, bsdtar->create_format); /* ... complain if it's not compatible. */ format &= ARCHIVE_FORMAT_BASE_MASK; if (format != (int)(archive_format(a) & ARCHIVE_FORMAT_BASE_MASK) && format != ARCHIVE_FORMAT_EMPTY) { lafe_errc(1, 0, "Format %s is incompatible with the archive %s.", bsdtar->create_format, bsdtar->filename); } } else { /* * Just preserve the current format, with a little care * for formats that libarchive can't write. */ if (format == ARCHIVE_FORMAT_EMPTY) format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED; archive_write_set_format(a, format); } if (lseek(bsdtar->fd, end_offset, SEEK_SET) < 0) lafe_errc(1, errno, "Could not seek to archive end"); if (ARCHIVE_OK != archive_write_set_options(a, bsdtar->option_options)) lafe_errc(1, 0, "%s", archive_error_string(a)); if (ARCHIVE_OK != archive_write_open_fd(a, bsdtar->fd)) lafe_errc(1, 0, "%s", archive_error_string(a)); write_archive(a, bsdtar); /* XXX check return val XXX */ close(bsdtar->fd); bsdtar->fd = -1; }
static void test_read_format_cab_filename_CP932_UTF8(const char *refname) { struct archive *a; struct archive_entry *ae; /* * Read CAB filename in en_US.UTF-8 with "hdrcharset=CP932" option. */ if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) { skipping("en_US.UTF-8 locale not available on this system."); return; } assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP932")) { skipping("This system cannot convert character-set" " from CP932 to UTF-8."); goto cleanup; } assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240)); /* Verify regular file. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); #if defined(__APPLE__) /* Compare NFD string. */ assertEqualUTF8String( "\xe8\xa1\xa8\xe3\x81\x9f\xe3\x82\x99\xe3\x82\x88\x2f" "\xe6\xbc\xa2\xe5\xad\x97\x2e\x74\x78\x74", archive_entry_pathname(ae)); assertEqualInt(5, archive_entry_size(ae)); #else /* Compare NFC string. */ assertEqualUTF8String( "\xe8\xa1\xa8\xe3\x81\xa0\xe3\x82\x88\x2f" "\xe6\xbc\xa2\xe5\xad\x97\x2e\x74\x78\x74", archive_entry_pathname(ae)); assertEqualInt(5, archive_entry_size(ae)); #endif /* Verify regular file. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); #if defined(__APPLE__) /* Compare NFD string. */ assertEqualUTF8String( "\xe8\xa1\xa8\xe3\x81\x9f\xe3\x82\x99\xe3\x82\x88\x2f" "\xe4\xb8\x80\xe8\xa6\xa7\xe8\xa1\xa8\x2e\x74\x78\x74", archive_entry_pathname(ae)); #else /* Compare NFC string. */ assertEqualUTF8String( "\xe8\xa1\xa8\xe3\x81\xa0\xe3\x82\x88\x2f" "\xe4\xb8\x80\xe8\xa6\xa7\xe8\xa1\xa8\x2e\x74\x78\x74", archive_entry_pathname(ae)); #endif assertEqualInt(5, archive_entry_size(ae)); /* End of archive. */ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); /* Verify archive format. */ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a)); assertEqualIntA(a, ARCHIVE_FORMAT_CAB, archive_format(a)); /* Close the archive. */ cleanup: assertEqualInt(ARCHIVE_OK, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); }