struct archive_entry * archive_entry_clone(struct archive_entry *entry) { struct archive_entry *entry2; struct ae_xattr *xp; struct ae_sparse *sp; size_t s; const void *p; /* Allocate new structure and copy over all of the fields. */ /* TODO: Should we copy the archive over? Or require a new archive * as an argument? */ entry2 = archive_entry_new2(entry->archive); if (entry2 == NULL) return (NULL); entry2->ae_stat = entry->ae_stat; entry2->ae_fflags_set = entry->ae_fflags_set; entry2->ae_fflags_clear = entry->ae_fflags_clear; /* TODO: XXX If clone can have a different archive, what do we do here if * character sets are different? XXX */ archive_mstring_copy(&entry2->ae_fflags_text, &entry->ae_fflags_text); archive_mstring_copy(&entry2->ae_gname, &entry->ae_gname); archive_mstring_copy(&entry2->ae_hardlink, &entry->ae_hardlink); archive_mstring_copy(&entry2->ae_pathname, &entry->ae_pathname); archive_mstring_copy(&entry2->ae_sourcepath, &entry->ae_sourcepath); archive_mstring_copy(&entry2->ae_symlink, &entry->ae_symlink); entry2->ae_set = entry->ae_set; archive_mstring_copy(&entry2->ae_uname, &entry->ae_uname); /* Copy encryption status */ entry2->encryption = entry->encryption; /* Copy ACL data over. */ archive_acl_copy(&entry2->acl, &entry->acl); /* Copy Mac OS metadata. */ p = archive_entry_mac_metadata(entry, &s); archive_entry_copy_mac_metadata(entry2, p, s); /* Copy xattr data over. */ xp = entry->xattr_head; while (xp != NULL) { archive_entry_xattr_add_entry(entry2, xp->name, xp->value, xp->size); xp = xp->next; } /* Copy sparse data over. */ sp = entry->sparse_head; while (sp != NULL) { archive_entry_sparse_add_entry(entry2, sp->offset, sp->length); sp = sp->next; } return (entry2); }
/* * Apple shipped an extended version of GNU tar with Mac OS X 10.5 * and earlier. */ static void test_compat_mac_1(void) { char name[] = "test_compat_mac-1.tar.Z"; struct archive_entry *ae; struct archive *a; const void *attr; size_t attrSize; 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)); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString(TESTPATH, archive_entry_pathname(ae)); assertEqualInt(1275688109, archive_entry_mtime(ae)); assertEqualInt(95594, archive_entry_uid(ae)); assertEqualString("kientzle", archive_entry_uname(ae)); assertEqualInt(5000, archive_entry_gid(ae)); assertEqualString("", archive_entry_gname(ae)); assertEqualInt(040755, archive_entry_mode(ae)); attr = archive_entry_mac_metadata(ae, &attrSize); assert(attr == NULL); assertEqualInt(0, attrSize); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString(TESTPATH "dir/", archive_entry_pathname(ae)); assertEqualInt(1275687611, archive_entry_mtime(ae)); assertEqualInt(95594, archive_entry_uid(ae)); assertEqualString("kientzle", archive_entry_uname(ae)); assertEqualInt(5000, archive_entry_gid(ae)); assertEqualString("", archive_entry_gname(ae)); assertEqualInt(040755, archive_entry_mode(ae)); attr = archive_entry_mac_metadata(ae, &attrSize); assert(attr != NULL); assertEqualInt(225, attrSize); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString(TESTPATH "file", archive_entry_pathname(ae)); assertEqualInt(1275687588, archive_entry_mtime(ae)); assertEqualInt(95594, archive_entry_uid(ae)); assertEqualString("kientzle", archive_entry_uname(ae)); assertEqualInt(5000, archive_entry_gid(ae)); assertEqualString("", archive_entry_gname(ae)); assertEqualInt(0100644, archive_entry_mode(ae)); attr = archive_entry_mac_metadata(ae, &attrSize); assert(attr != NULL); assertEqualInt(225, attrSize); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString("dir/", archive_entry_pathname(ae)); assertEqualInt(1275688064, archive_entry_mtime(ae)); assertEqualInt(95594, archive_entry_uid(ae)); assertEqualString("kientzle", archive_entry_uname(ae)); assertEqualInt(5000, archive_entry_gid(ae)); assertEqualString("", archive_entry_gname(ae)); assertEqualInt(040755, archive_entry_mode(ae)); attr = archive_entry_mac_metadata(ae, &attrSize); assert(attr != NULL); assertEqualInt(225, attrSize); assertEqualMem("\x00\x05\x16\x07\x00\x02\x00\x00Mac OS X", attr, 16); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString("file", archive_entry_pathname(ae)); assertEqualInt(1275625860, archive_entry_mtime(ae)); assertEqualInt(95594, archive_entry_uid(ae)); assertEqualString("kientzle", archive_entry_uname(ae)); assertEqualInt(5000, archive_entry_gid(ae)); assertEqualString("", archive_entry_gname(ae)); assertEqualInt(0100644, archive_entry_mode(ae)); attr = archive_entry_mac_metadata(ae, &attrSize); assert(attr != NULL); assertEqualInt(225, attrSize); assertEqualMem("\x00\x05\x16\x07\x00\x02\x00\x00Mac OS X", attr, 16); /* Verify the end-of-archive. */ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); /* Verify that the format detection worked. */ assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_COMPRESS); assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_GNUTAR); assertEqualInt(ARCHIVE_OK, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); }
/* * Apple shipped a customized version of bsdtar starting with MacOS 10.6. */ static void test_compat_mac_2(void) { char name[] = "test_compat_mac-2.tar.Z"; struct archive_entry *ae; struct archive *a; const void *attr; size_t attrSize; 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)); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString("./", archive_entry_pathname(ae)); assertEqualInt(1303628303, archive_entry_mtime(ae)); assertEqualInt(501, archive_entry_uid(ae)); assertEqualString("tim", archive_entry_uname(ae)); assertEqualInt(20, archive_entry_gid(ae)); assertEqualString("staff", archive_entry_gname(ae)); assertEqualInt(040755, archive_entry_mode(ae)); attr = archive_entry_mac_metadata(ae, &attrSize); assert(attr == NULL); assertEqualInt(0, attrSize); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString("./mydir/", archive_entry_pathname(ae)); assertEqualInt(1303628303, archive_entry_mtime(ae)); assertEqualInt(501, archive_entry_uid(ae)); assertEqualString("tim", archive_entry_uname(ae)); assertEqualInt(20, archive_entry_gid(ae)); assertEqualString("staff", archive_entry_gname(ae)); assertEqualInt(040755, archive_entry_mode(ae)); attr = archive_entry_mac_metadata(ae, &attrSize); assert(attr != NULL); assertEqualInt(267, attrSize); assertEqualMem("\x00\x05\x16\x07\x00\x02\x00\x00Mac OS X", attr, 16); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString("./myfile", archive_entry_pathname(ae)); assertEqualInt(1303628303, archive_entry_mtime(ae)); assertEqualInt(501, archive_entry_uid(ae)); assertEqualString("tim", archive_entry_uname(ae)); assertEqualInt(20, archive_entry_gid(ae)); assertEqualString("staff", archive_entry_gname(ae)); assertEqualInt(0100644, archive_entry_mode(ae)); attr = archive_entry_mac_metadata(ae, &attrSize); assert(attr != NULL); assertEqualInt(267, attrSize); assertEqualMem("\x00\x05\x16\x07\x00\x02\x00\x00Mac OS X", attr, 16); /* Verify the end-of-archive. */ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); /* Verify that the format detection worked. */ assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_COMPRESS); assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR); assertEqualInt(ARCHIVE_OK, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); }