libarchive-static 1.0.6 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/extconf.rb +2 -9
- data/ext/libarchive-0.1.1/ext/archive_read_support_compression.c +6 -6
- data/ext/libarchive-0.1.1/ext/archive_read_support_compression.o +0 -0
- data/ext/libarchive-0.1.1/ext/archive_read_support_format.o +0 -0
- data/ext/libarchive-0.1.1/ext/archive_write_open_rb_str.c +1 -1
- data/ext/libarchive-0.1.1/ext/archive_write_open_rb_str.o +0 -0
- data/ext/libarchive-0.1.1/ext/archive_write_set_compression.c +5 -5
- data/ext/libarchive-0.1.1/ext/archive_write_set_compression.o +0 -0
- data/ext/libarchive-0.1.1/ext/config.h +23 -0
- data/ext/libarchive-0.1.1/ext/config.log +230 -0
- data/ext/libarchive-0.1.1/ext/config.status +671 -0
- data/ext/libarchive-0.1.1/ext/libarchive.c +1 -1
- data/ext/libarchive-0.1.1/ext/libarchive.o +0 -0
- data/ext/libarchive-0.1.1/ext/libarchive_archive.c +7 -7
- data/ext/libarchive-0.1.1/ext/libarchive_archive.o +0 -0
- data/ext/libarchive-0.1.1/ext/libarchive_entry.c +6 -0
- data/ext/libarchive-0.1.1/ext/libarchive_entry.o +0 -0
- data/ext/libarchive-0.1.1/ext/libarchive_reader.c +6 -4
- data/ext/libarchive-0.1.1/ext/libarchive_reader.o +0 -0
- data/ext/libarchive-0.1.1/ext/libarchive_ruby.so +0 -0
- data/ext/libarchive-0.1.1/ext/libarchive_win32.h +1 -1
- data/ext/libarchive-0.1.1/ext/libarchive_writer.c +2 -2
- data/ext/libarchive-0.1.1/ext/libarchive_writer.o +0 -0
- data/ext/libarchive-3.6.2/Makefile.in +16892 -0
- data/ext/libarchive-3.6.2/build/autoconf/ax_append_compile_flags.m4 +67 -0
- data/ext/libarchive-3.6.2/build/autoconf/ax_append_flag.m4 +71 -0
- data/ext/libarchive-3.6.2/build/autoconf/ax_check_compile_flag.m4 +74 -0
- data/ext/libarchive-3.6.2/build/autoconf/ax_require_defined.m4 +37 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/build/autoconf/check_stdcall_func.m4 +0 -0
- data/ext/libarchive-3.6.2/build/autoconf/compile +348 -0
- data/ext/libarchive-3.6.2/build/autoconf/config.guess +1754 -0
- data/ext/libarchive-3.6.2/build/autoconf/config.rpath +696 -0
- data/ext/libarchive-3.6.2/build/autoconf/config.sub +1890 -0
- data/ext/libarchive-3.6.2/build/autoconf/depcomp +791 -0
- data/ext/libarchive-3.6.2/build/autoconf/iconv.m4 +271 -0
- data/ext/libarchive-3.6.2/build/autoconf/install-sh +541 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/build/autoconf/la_uid_t.m4 +0 -0
- data/ext/libarchive-3.6.2/build/autoconf/lib-ld.m4 +109 -0
- data/ext/libarchive-3.6.2/build/autoconf/lib-link.m4 +777 -0
- data/ext/libarchive-3.6.2/build/autoconf/lib-prefix.m4 +224 -0
- data/ext/libarchive-3.6.2/build/autoconf/ltmain.sh +11251 -0
- data/ext/libarchive-3.6.2/build/autoconf/m4_ax_compile_check_sizeof.m4 +115 -0
- data/ext/libarchive-3.6.2/build/autoconf/missing +215 -0
- data/ext/libarchive-3.6.2/build/autoconf/test-driver +153 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/build/pkgconfig/libarchive.pc.in +4 -1
- data/ext/libarchive-3.6.2/config.h.in +1504 -0
- data/ext/libarchive-3.6.2/configure +25558 -0
- data/ext/libarchive-3.6.2/libarchive/archive.h +1212 -0
- data/ext/libarchive-3.6.2/libarchive/archive_acl.c +2097 -0
- data/ext/libarchive-3.6.2/libarchive/archive_acl_private.h +83 -0
- data/ext/libarchive-3.6.2/libarchive/archive_blake2.h +197 -0
- data/ext/libarchive-3.6.2/libarchive/archive_blake2_impl.h +161 -0
- data/ext/libarchive-3.6.2/libarchive/archive_blake2s_ref.c +369 -0
- data/ext/libarchive-3.6.2/libarchive/archive_blake2sp_ref.c +361 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_check_magic.c +63 -22
- data/ext/libarchive-3.6.2/libarchive/archive_cmdline.c +227 -0
- data/ext/libarchive-3.6.2/libarchive/archive_cmdline_private.h +47 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_crc32.h +17 -0
- data/ext/libarchive-3.6.2/libarchive/archive_cryptor.c +534 -0
- data/ext/libarchive-3.6.2/libarchive/archive_cryptor_private.h +188 -0
- data/ext/libarchive-3.6.2/libarchive/archive_digest.c +1505 -0
- data/ext/libarchive-3.6.2/libarchive/archive_digest_private.h +416 -0
- data/ext/libarchive-3.6.2/libarchive/archive_disk_acl_darwin.c +559 -0
- data/ext/libarchive-3.6.2/libarchive/archive_disk_acl_freebsd.c +712 -0
- data/ext/libarchive-3.6.2/libarchive/archive_disk_acl_linux.c +760 -0
- data/ext/libarchive-3.6.2/libarchive/archive_disk_acl_sunos.c +824 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_endian.h +48 -15
- data/ext/libarchive-3.6.2/libarchive/archive_entry.c +2149 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry.h +305 -106
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry_copy_bhfi.c +5 -4
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry_copy_stat.c +9 -3
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry_link_resolver.c +104 -62
- data/ext/libarchive-3.6.2/libarchive/archive_entry_locale.h +92 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry_private.h +65 -49
- data/ext/libarchive-3.6.2/libarchive/archive_entry_sparse.c +156 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry_stat.c +6 -6
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry_strmode.c +1 -1
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry_xattr.c +4 -6
- data/ext/libarchive-3.6.2/libarchive/archive_getdate.c +1165 -0
- data/ext/libarchive-3.6.2/libarchive/archive_getdate.h +39 -0
- data/ext/libarchive-3.6.2/libarchive/archive_hmac.c +334 -0
- data/ext/libarchive-3.6.2/libarchive/archive_hmac_private.h +117 -0
- data/ext/libarchive-3.6.2/libarchive/archive_match.c +1875 -0
- data/ext/libarchive-3.6.2/libarchive/archive_openssl_evp_private.h +53 -0
- data/ext/libarchive-3.6.2/libarchive/archive_openssl_hmac_private.h +54 -0
- data/ext/libarchive-3.6.2/libarchive/archive_options.c +218 -0
- data/ext/libarchive-3.6.2/libarchive/archive_options_private.h +51 -0
- data/ext/libarchive-3.6.2/libarchive/archive_pack_dev.c +337 -0
- data/ext/libarchive-3.6.2/libarchive/archive_pack_dev.h +49 -0
- data/ext/libarchive-3.6.2/libarchive/archive_pathmatch.c +463 -0
- data/ext/libarchive-3.6.2/libarchive/archive_pathmatch.h +52 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_platform.h +77 -9
- data/ext/libarchive-3.6.2/libarchive/archive_platform_acl.h +55 -0
- data/ext/libarchive-3.6.2/libarchive/archive_platform_xattr.h +47 -0
- data/ext/libarchive-3.6.2/libarchive/archive_ppmd7.c +1168 -0
- data/ext/libarchive-3.6.2/libarchive/archive_ppmd7_private.h +119 -0
- data/ext/libarchive-3.6.2/libarchive/archive_ppmd8.c +1287 -0
- data/ext/libarchive-3.6.2/libarchive/archive_ppmd8_private.h +148 -0
- data/ext/libarchive-3.6.2/libarchive/archive_ppmd_private.h +151 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_private.h +74 -18
- data/ext/libarchive-3.6.2/libarchive/archive_random.c +272 -0
- data/ext/libarchive-3.6.2/libarchive/archive_random_private.h +36 -0
- data/ext/libarchive-3.6.2/libarchive/archive_rb.c +709 -0
- data/ext/libarchive-3.6.2/libarchive/archive_rb.h +113 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read.c +1756 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_add_passphrase.c +190 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_append_filter.c +204 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_data_into_fd.c +64 -18
- data/ext/libarchive-3.6.2/libarchive/archive_read_disk_entry_from_file.c +1086 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_disk_posix.c +2732 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_disk_private.h +40 -4
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_disk_set_standard_lookup.c +21 -11
- data/ext/libarchive-3.6.2/libarchive/archive_read_disk_windows.c +2479 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_extract.c +60 -0
- data/ext/{libarchive-2.8.4/libarchive/archive_read_extract.c → libarchive-3.6.2/libarchive/archive_read_extract2.c} +34 -61
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_open_fd.c +70 -49
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_open_file.c +38 -23
- data/ext/libarchive-3.6.2/libarchive/archive_read_open_filename.c +586 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_open_memory.c +58 -28
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_private.h +127 -59
- data/ext/libarchive-3.6.2/libarchive/archive_read_set_format.c +117 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_set_options.c +133 -0
- data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_all.c → libarchive-3.6.2/libarchive/archive_read_support_filter_all.c} +35 -10
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_filter_by_code.c +83 -0
- data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_bzip2.c → libarchive-3.6.2/libarchive/archive_read_support_filter_bzip2.c} +38 -26
- data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_compress.c → libarchive-3.6.2/libarchive/archive_read_support_filter_compress.c} +52 -44
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_filter_grzip.c +112 -0
- data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_gzip.c → libarchive-3.6.2/libarchive/archive_read_support_filter_gzip.c} +108 -37
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_filter_lrzip.c +122 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_filter_lz4.c +742 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_filter_lzop.c +499 -0
- data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_none.c → libarchive-3.6.2/libarchive/archive_read_support_filter_none.c} +15 -3
- data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_program.c → libarchive-3.6.2/libarchive/archive_read_support_filter_program.c} +114 -77
- data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_rpm.c → libarchive-3.6.2/libarchive/archive_read_support_filter_rpm.c} +31 -31
- data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_uu.c → libarchive-3.6.2/libarchive/archive_read_support_filter_uu.c} +141 -85
- data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_xz.c → libarchive-3.6.2/libarchive/archive_read_support_filter_xz.c} +369 -284
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_filter_zstd.c +297 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_7zip.c +3900 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_all.c +89 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_support_format_ar.c +126 -72
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_by_code.c +92 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_cab.c +3228 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_cpio.c +1104 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_support_format_empty.c +14 -11
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_support_format_iso9660.c +990 -541
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_lha.c +2916 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_mtree.c +2150 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_rar.c +3797 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_rar5.c +4251 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_support_format_raw.c +38 -31
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_support_format_tar.c +1157 -629
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_warc.c +848 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_support_format_xar.c +439 -258
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_zip.c +4270 -0
- data/ext/libarchive-3.6.2/libarchive/archive_string.c +4240 -0
- data/ext/libarchive-3.6.2/libarchive/archive_string.h +243 -0
- data/ext/libarchive-3.6.2/libarchive/archive_string_composition.h +2292 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_string_sprintf.c +44 -16
- data/ext/libarchive-3.6.2/libarchive/archive_util.c +655 -0
- data/ext/libarchive-3.6.2/libarchive/archive_version_details.c +151 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_virtual.c +85 -16
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_windows.c +214 -541
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_windows.h +74 -106
- data/ext/libarchive-3.6.2/libarchive/archive_write.c +828 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter.c +72 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_b64encode.c +304 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_by_name.c +77 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_bzip2.c +401 -0
- data/ext/{libarchive-2.8.4/libarchive/archive_write_set_compression_compress.c → libarchive-3.6.2/libarchive/archive_write_add_filter_compress.c} +86 -131
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_grzip.c +135 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_gzip.c +442 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_lrzip.c +197 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_lz4.c +700 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_lzop.c +478 -0
- data/ext/{libarchive-2.8.4/libarchive/archive_read_support_format_all.c → libarchive-3.6.2/libarchive/archive_write_add_filter_none.c} +11 -11
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_program.c +391 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_uuencode.c +295 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_xz.c +545 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_zstd.c +418 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_disk_posix.c +4711 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_disk_private.h +9 -2
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_disk_set_standard_lookup.c +30 -29
- data/ext/libarchive-3.6.2/libarchive/archive_write_disk_windows.c +2842 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_open_fd.c +15 -10
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_open_file.c +15 -9
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_open_filename.c +128 -20
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_open_memory.c +7 -18
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_private.h +72 -29
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_set_format.c +56 -3
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_7zip.c +2322 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_set_format_ar.c +54 -34
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_set_format_by_name.c +20 -2
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_cpio.c +11 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_cpio_binary.c +610 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_cpio_newc.c +457 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_cpio_odc.c +500 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_filter_by_ext.c +142 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_gnutar.c +755 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_iso9660.c +8165 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_mtree.c +2217 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_set_format_pax.c +1049 -387
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_private.h +42 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_raw.c +125 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_set_format_shar.c +62 -47
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_set_format_ustar.c +279 -108
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_v7tar.c +638 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_warc.c +453 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_xar.c +3259 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_zip.c +1704 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_options.c +130 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_passphrase.c +95 -0
- data/ext/libarchive-3.6.2/libarchive/archive_xxhash.h +48 -0
- data/ext/libarchive-3.6.2/libarchive/config_freebsd.h +271 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/filter_fork.h +10 -5
- data/ext/{libarchive-2.8.4/libarchive/filter_fork.c → libarchive-3.6.2/libarchive/filter_fork_posix.c} +98 -19
- data/ext/libarchive-3.6.2/libarchive/filter_fork_windows.c +236 -0
- data/ext/libarchive-3.6.2/libarchive/xxhash.c +525 -0
- data/ext/libarchive-static-makefile +144 -80
- data/ext/libarchive-static-wrapper-makefile +1 -1
- data/ext/zlib-1.2.13/Makefile.in +404 -0
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/adler32.c +51 -34
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/compress.c +27 -21
- data/ext/zlib-1.2.13/configure +922 -0
- data/ext/zlib-1.2.13/crc32.c +1125 -0
- data/ext/zlib-1.2.13/crc32.h +9446 -0
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/deflate.c +842 -459
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/deflate.h +37 -33
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/gzclose.c +0 -0
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/gzguts.h +103 -16
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/gzlib.c +155 -53
- data/ext/zlib-1.2.13/gzread.c +650 -0
- data/ext/zlib-1.2.13/gzwrite.c +677 -0
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/infback.c +24 -12
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/inffast.c +49 -66
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/inffast.h +0 -0
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/inffixed.h +3 -3
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/inflate.c +209 -94
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/inflate.h +9 -5
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/inftrees.c +24 -50
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/inftrees.h +1 -1
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/trees.c +135 -198
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/trees.h +0 -0
- data/ext/zlib-1.2.13/uncompr.c +93 -0
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/zconf.h +182 -63
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/zlib.h +617 -295
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/zutil.c +50 -41
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/zutil.h +83 -82
- metadata +241 -133
- data/ext/libarchive-0.1.1/libarchive.c +0 -1762
- data/ext/libarchive-2.8.4/Makefile.in +0 -7076
- data/ext/libarchive-2.8.4/build/autoconf/compile +0 -143
- data/ext/libarchive-2.8.4/build/autoconf/config.guess +0 -1502
- data/ext/libarchive-2.8.4/build/autoconf/config.sub +0 -1708
- data/ext/libarchive-2.8.4/build/autoconf/depcomp +0 -630
- data/ext/libarchive-2.8.4/build/autoconf/install-sh +0 -291
- data/ext/libarchive-2.8.4/build/autoconf/ltmain.sh +0 -8406
- data/ext/libarchive-2.8.4/build/autoconf/missing +0 -376
- data/ext/libarchive-2.8.4/config.h.in +0 -772
- data/ext/libarchive-2.8.4/configure +0 -17916
- data/ext/libarchive-2.8.4/libarchive/archive.h +0 -741
- data/ext/libarchive-2.8.4/libarchive/archive_entry.c +0 -2202
- data/ext/libarchive-2.8.4/libarchive/archive_hash.h +0 -281
- data/ext/libarchive-2.8.4/libarchive/archive_read.c +0 -1249
- data/ext/libarchive-2.8.4/libarchive/archive_read_disk.c +0 -198
- data/ext/libarchive-2.8.4/libarchive/archive_read_disk_entry_from_file.c +0 -570
- data/ext/libarchive-2.8.4/libarchive/archive_read_open_filename.c +0 -272
- data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_cpio.c +0 -777
- data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_mtree.c +0 -1304
- data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_zip.c +0 -903
- data/ext/libarchive-2.8.4/libarchive/archive_string.c +0 -453
- data/ext/libarchive-2.8.4/libarchive/archive_string.h +0 -148
- data/ext/libarchive-2.8.4/libarchive/archive_util.c +0 -391
- data/ext/libarchive-2.8.4/libarchive/archive_write.c +0 -466
- data/ext/libarchive-2.8.4/libarchive/archive_write_disk.c +0 -2628
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_bzip2.c +0 -408
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_gzip.c +0 -477
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_none.c +0 -257
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_program.c +0 -347
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_xz.c +0 -438
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_cpio.c +0 -344
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_cpio_newc.c +0 -295
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_mtree.c +0 -1050
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_zip.c +0 -667
- data/ext/libarchive-2.8.4/libarchive/config_freebsd.h +0 -154
- data/ext/libarchive-2.8.4/libarchive/filter_fork_windows.c +0 -113
- data/ext/zlib-1.2.5/Makefile.in +0 -257
- data/ext/zlib-1.2.5/configure +0 -596
- data/ext/zlib-1.2.5/crc32.c +0 -442
- data/ext/zlib-1.2.5/crc32.h +0 -441
- data/ext/zlib-1.2.5/example.c +0 -565
- data/ext/zlib-1.2.5/gzread.c +0 -653
- data/ext/zlib-1.2.5/gzwrite.c +0 -531
- data/ext/zlib-1.2.5/minigzip.c +0 -440
- data/ext/zlib-1.2.5/uncompr.c +0 -59
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/*-
|
|
2
2
|
* Copyright (c) 2003-2007 Tim Kientzle
|
|
3
|
+
* Copyright (c) 2010-2012 Michihiro NAKAJIMA
|
|
4
|
+
* Copyright (c) 2016 Martin Matuska
|
|
3
5
|
* All rights reserved.
|
|
4
6
|
*
|
|
5
7
|
* Redistribution and use in source and binary forms, with or without
|
|
@@ -38,39 +40,66 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_pax.c 201162 20
|
|
|
38
40
|
|
|
39
41
|
#include "archive.h"
|
|
40
42
|
#include "archive_entry.h"
|
|
43
|
+
#include "archive_entry_locale.h"
|
|
41
44
|
#include "archive_private.h"
|
|
42
45
|
#include "archive_write_private.h"
|
|
46
|
+
#include "archive_write_set_format_private.h"
|
|
47
|
+
|
|
48
|
+
struct sparse_block {
|
|
49
|
+
struct sparse_block *next;
|
|
50
|
+
int is_hole;
|
|
51
|
+
uint64_t offset;
|
|
52
|
+
uint64_t remaining;
|
|
53
|
+
};
|
|
43
54
|
|
|
44
55
|
struct pax {
|
|
45
56
|
uint64_t entry_bytes_remaining;
|
|
46
57
|
uint64_t entry_padding;
|
|
58
|
+
struct archive_string l_url_encoded_name;
|
|
47
59
|
struct archive_string pax_header;
|
|
60
|
+
struct archive_string sparse_map;
|
|
61
|
+
size_t sparse_map_padding;
|
|
62
|
+
struct sparse_block *sparse_list;
|
|
63
|
+
struct sparse_block *sparse_tail;
|
|
64
|
+
struct archive_string_conv *sconv_utf8;
|
|
65
|
+
int opt_binary;
|
|
66
|
+
|
|
67
|
+
unsigned flags;
|
|
68
|
+
#define WRITE_SCHILY_XATTR (1 << 0)
|
|
69
|
+
#define WRITE_LIBARCHIVE_XATTR (1 << 1)
|
|
48
70
|
};
|
|
49
71
|
|
|
50
72
|
static void add_pax_attr(struct archive_string *, const char *key,
|
|
51
73
|
const char *value);
|
|
74
|
+
static void add_pax_attr_binary(struct archive_string *,
|
|
75
|
+
const char *key,
|
|
76
|
+
const char *value, size_t value_len);
|
|
52
77
|
static void add_pax_attr_int(struct archive_string *,
|
|
53
78
|
const char *key, int64_t value);
|
|
54
79
|
static void add_pax_attr_time(struct archive_string *,
|
|
55
80
|
const char *key, int64_t sec,
|
|
56
81
|
unsigned long nanos);
|
|
57
|
-
static
|
|
58
|
-
|
|
82
|
+
static int add_pax_acl(struct archive_write *,
|
|
83
|
+
struct archive_entry *, struct pax *, int);
|
|
59
84
|
static ssize_t archive_write_pax_data(struct archive_write *,
|
|
60
85
|
const void *, size_t);
|
|
61
|
-
static int
|
|
62
|
-
static int
|
|
86
|
+
static int archive_write_pax_close(struct archive_write *);
|
|
87
|
+
static int archive_write_pax_free(struct archive_write *);
|
|
63
88
|
static int archive_write_pax_finish_entry(struct archive_write *);
|
|
64
89
|
static int archive_write_pax_header(struct archive_write *,
|
|
65
90
|
struct archive_entry *);
|
|
91
|
+
static int archive_write_pax_options(struct archive_write *,
|
|
92
|
+
const char *, const char *);
|
|
66
93
|
static char *base64_encode(const char *src, size_t len);
|
|
94
|
+
static char *build_gnu_sparse_name(char *dest, const char *src);
|
|
67
95
|
static char *build_pax_attribute_name(char *dest, const char *src);
|
|
68
96
|
static char *build_ustar_entry_name(char *dest, const char *src,
|
|
69
97
|
size_t src_length, const char *insert);
|
|
70
98
|
static char *format_int(char *dest, int64_t);
|
|
71
|
-
static int has_non_ASCII(const
|
|
99
|
+
static int has_non_ASCII(const char *);
|
|
100
|
+
static void sparse_list_clear(struct pax *);
|
|
101
|
+
static int sparse_list_add(struct pax *, int64_t, int64_t);
|
|
72
102
|
static char *url_encode(const char *in);
|
|
73
|
-
static int write_nulls(struct archive_write *, size_t);
|
|
74
103
|
|
|
75
104
|
/*
|
|
76
105
|
* Set output format to 'restricted pax' format.
|
|
@@ -84,6 +113,10 @@ archive_write_set_format_pax_restricted(struct archive *_a)
|
|
|
84
113
|
{
|
|
85
114
|
struct archive_write *a = (struct archive_write *)_a;
|
|
86
115
|
int r;
|
|
116
|
+
|
|
117
|
+
archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
|
|
118
|
+
ARCHIVE_STATE_NEW, "archive_write_set_format_pax_restricted");
|
|
119
|
+
|
|
87
120
|
r = archive_write_set_format_pax(&a->archive);
|
|
88
121
|
a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED;
|
|
89
122
|
a->archive.archive_format_name = "restricted POSIX pax interchange";
|
|
@@ -99,29 +132,104 @@ archive_write_set_format_pax(struct archive *_a)
|
|
|
99
132
|
struct archive_write *a = (struct archive_write *)_a;
|
|
100
133
|
struct pax *pax;
|
|
101
134
|
|
|
102
|
-
|
|
103
|
-
|
|
135
|
+
archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
|
|
136
|
+
ARCHIVE_STATE_NEW, "archive_write_set_format_pax");
|
|
137
|
+
|
|
138
|
+
if (a->format_free != NULL)
|
|
139
|
+
(a->format_free)(a);
|
|
104
140
|
|
|
105
|
-
pax = (struct pax *)
|
|
141
|
+
pax = (struct pax *)calloc(1, sizeof(*pax));
|
|
106
142
|
if (pax == NULL) {
|
|
107
|
-
archive_set_error(&a->archive, ENOMEM,
|
|
143
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
144
|
+
"Can't allocate pax data");
|
|
108
145
|
return (ARCHIVE_FATAL);
|
|
109
146
|
}
|
|
110
|
-
|
|
111
|
-
a->format_data = pax;
|
|
147
|
+
pax->flags = WRITE_LIBARCHIVE_XATTR | WRITE_SCHILY_XATTR;
|
|
112
148
|
|
|
113
|
-
a->
|
|
149
|
+
a->format_data = pax;
|
|
114
150
|
a->format_name = "pax";
|
|
151
|
+
a->format_options = archive_write_pax_options;
|
|
115
152
|
a->format_write_header = archive_write_pax_header;
|
|
116
153
|
a->format_write_data = archive_write_pax_data;
|
|
117
|
-
a->
|
|
118
|
-
a->
|
|
154
|
+
a->format_close = archive_write_pax_close;
|
|
155
|
+
a->format_free = archive_write_pax_free;
|
|
119
156
|
a->format_finish_entry = archive_write_pax_finish_entry;
|
|
120
157
|
a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
|
|
121
158
|
a->archive.archive_format_name = "POSIX pax interchange";
|
|
122
159
|
return (ARCHIVE_OK);
|
|
123
160
|
}
|
|
124
161
|
|
|
162
|
+
static int
|
|
163
|
+
archive_write_pax_options(struct archive_write *a, const char *key,
|
|
164
|
+
const char *val)
|
|
165
|
+
{
|
|
166
|
+
struct pax *pax = (struct pax *)a->format_data;
|
|
167
|
+
int ret = ARCHIVE_FAILED;
|
|
168
|
+
|
|
169
|
+
if (strcmp(key, "hdrcharset") == 0) {
|
|
170
|
+
/*
|
|
171
|
+
* The character-set we can use are defined in
|
|
172
|
+
* IEEE Std 1003.1-2001
|
|
173
|
+
*/
|
|
174
|
+
if (val == NULL || val[0] == 0)
|
|
175
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
176
|
+
"pax: hdrcharset option needs a character-set name");
|
|
177
|
+
else if (strcmp(val, "BINARY") == 0 ||
|
|
178
|
+
strcmp(val, "binary") == 0) {
|
|
179
|
+
/*
|
|
180
|
+
* Specify binary mode. We will not convert
|
|
181
|
+
* filenames, uname and gname to any charsets.
|
|
182
|
+
*/
|
|
183
|
+
pax->opt_binary = 1;
|
|
184
|
+
ret = ARCHIVE_OK;
|
|
185
|
+
} else if (strcmp(val, "UTF-8") == 0) {
|
|
186
|
+
/*
|
|
187
|
+
* Specify UTF-8 character-set to be used for
|
|
188
|
+
* filenames. This is almost the test that
|
|
189
|
+
* running platform supports the string conversion.
|
|
190
|
+
* Especially libarchive_test needs this trick for
|
|
191
|
+
* its test.
|
|
192
|
+
*/
|
|
193
|
+
pax->sconv_utf8 = archive_string_conversion_to_charset(
|
|
194
|
+
&(a->archive), "UTF-8", 0);
|
|
195
|
+
if (pax->sconv_utf8 == NULL)
|
|
196
|
+
ret = ARCHIVE_FATAL;
|
|
197
|
+
else
|
|
198
|
+
ret = ARCHIVE_OK;
|
|
199
|
+
} else
|
|
200
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
201
|
+
"pax: invalid charset name");
|
|
202
|
+
return (ret);
|
|
203
|
+
} else if (strcmp(key, "xattrheader") == 0) {
|
|
204
|
+
if (val == NULL || val[0] == 0) {
|
|
205
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
206
|
+
"pax: xattrheader requires a value");
|
|
207
|
+
} else if (strcmp(val, "ALL") == 0 ||
|
|
208
|
+
strcmp(val, "all") == 0) {
|
|
209
|
+
pax->flags |= WRITE_LIBARCHIVE_XATTR | WRITE_SCHILY_XATTR;
|
|
210
|
+
ret = ARCHIVE_OK;
|
|
211
|
+
} else if (strcmp(val, "SCHILY") == 0 ||
|
|
212
|
+
strcmp(val, "schily") == 0) {
|
|
213
|
+
pax->flags |= WRITE_SCHILY_XATTR;
|
|
214
|
+
pax->flags &= ~WRITE_LIBARCHIVE_XATTR;
|
|
215
|
+
ret = ARCHIVE_OK;
|
|
216
|
+
} else if (strcmp(val, "LIBARCHIVE") == 0 ||
|
|
217
|
+
strcmp(val, "libarchive") == 0) {
|
|
218
|
+
pax->flags |= WRITE_LIBARCHIVE_XATTR;
|
|
219
|
+
pax->flags &= ~WRITE_SCHILY_XATTR;
|
|
220
|
+
ret = ARCHIVE_OK;
|
|
221
|
+
} else
|
|
222
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
223
|
+
"pax: invalid xattr header name");
|
|
224
|
+
return (ret);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/* Note: The "warn" return is just to inform the options
|
|
228
|
+
* supervisor that we didn't handle it. It will generate
|
|
229
|
+
* a suitable error if no one used this option. */
|
|
230
|
+
return (ARCHIVE_WARN);
|
|
231
|
+
}
|
|
232
|
+
|
|
125
233
|
/*
|
|
126
234
|
* Note: This code assumes that 'nanos' has the same sign as 'sec',
|
|
127
235
|
* which implies that sec=-1, nanos=200000000 represents -1.2 seconds
|
|
@@ -168,18 +276,17 @@ add_pax_attr_time(struct archive_string *as, const char *key,
|
|
|
168
276
|
static char *
|
|
169
277
|
format_int(char *t, int64_t i)
|
|
170
278
|
{
|
|
171
|
-
|
|
279
|
+
uint64_t ui;
|
|
172
280
|
|
|
173
|
-
if (i < 0)
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
sign = 1;
|
|
281
|
+
if (i < 0)
|
|
282
|
+
ui = (i == INT64_MIN) ? (uint64_t)(INT64_MAX) + 1 : (uint64_t)(-i);
|
|
283
|
+
else
|
|
284
|
+
ui = i;
|
|
178
285
|
|
|
179
286
|
do {
|
|
180
|
-
*--t = "0123456789"[
|
|
181
|
-
} while (
|
|
182
|
-
if (
|
|
287
|
+
*--t = "0123456789"[ui % 10];
|
|
288
|
+
} while (ui /= 10);
|
|
289
|
+
if (i < 0)
|
|
183
290
|
*--t = '-';
|
|
184
291
|
return (t);
|
|
185
292
|
}
|
|
@@ -193,112 +300,23 @@ add_pax_attr_int(struct archive_string *as, const char *key, int64_t value)
|
|
|
193
300
|
add_pax_attr(as, key, format_int(tmp + sizeof(tmp) - 1, value));
|
|
194
301
|
}
|
|
195
302
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
const wchar_t *wp;
|
|
201
|
-
unsigned long wc;
|
|
202
|
-
char *utf8_value, *p;
|
|
203
|
-
|
|
204
|
-
utf8len = 0;
|
|
205
|
-
for (wp = wval; *wp != L'\0'; ) {
|
|
206
|
-
wc = *wp++;
|
|
207
|
-
|
|
208
|
-
if (wc >= 0xd800 && wc <= 0xdbff
|
|
209
|
-
&& *wp >= 0xdc00 && *wp <= 0xdfff) {
|
|
210
|
-
/* This is a surrogate pair. Combine into a
|
|
211
|
-
* full Unicode value before encoding into
|
|
212
|
-
* UTF-8. */
|
|
213
|
-
wc = (wc - 0xd800) << 10; /* High 10 bits */
|
|
214
|
-
wc += (*wp++ - 0xdc00); /* Low 10 bits */
|
|
215
|
-
wc += 0x10000; /* Skip BMP */
|
|
216
|
-
}
|
|
217
|
-
if (wc <= 0x7f)
|
|
218
|
-
utf8len++;
|
|
219
|
-
else if (wc <= 0x7ff)
|
|
220
|
-
utf8len += 2;
|
|
221
|
-
else if (wc <= 0xffff)
|
|
222
|
-
utf8len += 3;
|
|
223
|
-
else if (wc <= 0x1fffff)
|
|
224
|
-
utf8len += 4;
|
|
225
|
-
else if (wc <= 0x3ffffff)
|
|
226
|
-
utf8len += 5;
|
|
227
|
-
else if (wc <= 0x7fffffff)
|
|
228
|
-
utf8len += 6;
|
|
229
|
-
/* Ignore larger values; UTF-8 can't encode them. */
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
utf8_value = (char *)malloc(utf8len + 1);
|
|
233
|
-
if (utf8_value == NULL) {
|
|
234
|
-
__archive_errx(1, "Not enough memory for attributes");
|
|
235
|
-
return (NULL);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
for (wp = wval, p = utf8_value; *wp != L'\0'; ) {
|
|
239
|
-
wc = *wp++;
|
|
240
|
-
if (wc >= 0xd800 && wc <= 0xdbff
|
|
241
|
-
&& *wp >= 0xdc00 && *wp <= 0xdfff) {
|
|
242
|
-
/* Combine surrogate pair. */
|
|
243
|
-
wc = (wc - 0xd800) << 10;
|
|
244
|
-
wc += *wp++ - 0xdc00 + 0x10000;
|
|
245
|
-
}
|
|
246
|
-
if (wc <= 0x7f) {
|
|
247
|
-
*p++ = (char)wc;
|
|
248
|
-
} else if (wc <= 0x7ff) {
|
|
249
|
-
p[0] = 0xc0 | ((wc >> 6) & 0x1f);
|
|
250
|
-
p[1] = 0x80 | (wc & 0x3f);
|
|
251
|
-
p += 2;
|
|
252
|
-
} else if (wc <= 0xffff) {
|
|
253
|
-
p[0] = 0xe0 | ((wc >> 12) & 0x0f);
|
|
254
|
-
p[1] = 0x80 | ((wc >> 6) & 0x3f);
|
|
255
|
-
p[2] = 0x80 | (wc & 0x3f);
|
|
256
|
-
p += 3;
|
|
257
|
-
} else if (wc <= 0x1fffff) {
|
|
258
|
-
p[0] = 0xf0 | ((wc >> 18) & 0x07);
|
|
259
|
-
p[1] = 0x80 | ((wc >> 12) & 0x3f);
|
|
260
|
-
p[2] = 0x80 | ((wc >> 6) & 0x3f);
|
|
261
|
-
p[3] = 0x80 | (wc & 0x3f);
|
|
262
|
-
p += 4;
|
|
263
|
-
} else if (wc <= 0x3ffffff) {
|
|
264
|
-
p[0] = 0xf8 | ((wc >> 24) & 0x03);
|
|
265
|
-
p[1] = 0x80 | ((wc >> 18) & 0x3f);
|
|
266
|
-
p[2] = 0x80 | ((wc >> 12) & 0x3f);
|
|
267
|
-
p[3] = 0x80 | ((wc >> 6) & 0x3f);
|
|
268
|
-
p[4] = 0x80 | (wc & 0x3f);
|
|
269
|
-
p += 5;
|
|
270
|
-
} else if (wc <= 0x7fffffff) {
|
|
271
|
-
p[0] = 0xfc | ((wc >> 30) & 0x01);
|
|
272
|
-
p[1] = 0x80 | ((wc >> 24) & 0x3f);
|
|
273
|
-
p[1] = 0x80 | ((wc >> 18) & 0x3f);
|
|
274
|
-
p[2] = 0x80 | ((wc >> 12) & 0x3f);
|
|
275
|
-
p[3] = 0x80 | ((wc >> 6) & 0x3f);
|
|
276
|
-
p[4] = 0x80 | (wc & 0x3f);
|
|
277
|
-
p += 6;
|
|
278
|
-
}
|
|
279
|
-
/* Ignore larger values; UTF-8 can't encode them. */
|
|
280
|
-
}
|
|
281
|
-
*p = '\0';
|
|
282
|
-
|
|
283
|
-
return (utf8_value);
|
|
284
|
-
}
|
|
285
|
-
|
|
303
|
+
/*
|
|
304
|
+
* Add a key/value attribute to the pax header. This function handles
|
|
305
|
+
* the length field and various other syntactic requirements.
|
|
306
|
+
*/
|
|
286
307
|
static void
|
|
287
|
-
|
|
308
|
+
add_pax_attr(struct archive_string *as, const char *key, const char *value)
|
|
288
309
|
{
|
|
289
|
-
|
|
290
|
-
if (utf8_value == NULL)
|
|
291
|
-
return;
|
|
292
|
-
add_pax_attr(as, key, utf8_value);
|
|
293
|
-
free(utf8_value);
|
|
310
|
+
add_pax_attr_binary(as, key, value, strlen(value));
|
|
294
311
|
}
|
|
295
312
|
|
|
296
313
|
/*
|
|
297
314
|
* Add a key/value attribute to the pax header. This function handles
|
|
298
|
-
*
|
|
315
|
+
* binary values.
|
|
299
316
|
*/
|
|
300
317
|
static void
|
|
301
|
-
|
|
318
|
+
add_pax_attr_binary(struct archive_string *as, const char *key,
|
|
319
|
+
const char *value, size_t value_len)
|
|
302
320
|
{
|
|
303
321
|
int digits, i, len, next_ten;
|
|
304
322
|
char tmp[1 + 3 * sizeof(int)]; /* < 3 base-10 digits per byte */
|
|
@@ -307,7 +325,7 @@ add_pax_attr(struct archive_string *as, const char *key, const char *value)
|
|
|
307
325
|
* PAX attributes have the following layout:
|
|
308
326
|
* <len> <space> <key> <=> <value> <nl>
|
|
309
327
|
*/
|
|
310
|
-
len = 1 + (int)strlen(key) + 1 + (int)
|
|
328
|
+
len = 1 + (int)strlen(key) + 1 + (int)value_len + 1;
|
|
311
329
|
|
|
312
330
|
/*
|
|
313
331
|
* The <len> field includes the length of the <len> field, so
|
|
@@ -338,55 +356,203 @@ add_pax_attr(struct archive_string *as, const char *key, const char *value)
|
|
|
338
356
|
archive_strappend_char(as, ' ');
|
|
339
357
|
archive_strcat(as, key);
|
|
340
358
|
archive_strappend_char(as, '=');
|
|
341
|
-
|
|
359
|
+
archive_array_append(as, value, value_len);
|
|
342
360
|
archive_strappend_char(as, '\n');
|
|
343
361
|
}
|
|
344
362
|
|
|
345
363
|
static void
|
|
346
|
-
|
|
364
|
+
archive_write_pax_header_xattr(struct pax *pax, const char *encoded_name,
|
|
365
|
+
const void *value, size_t value_len)
|
|
347
366
|
{
|
|
348
367
|
struct archive_string s;
|
|
368
|
+
char *encoded_value;
|
|
369
|
+
|
|
370
|
+
if (pax->flags & WRITE_LIBARCHIVE_XATTR) {
|
|
371
|
+
encoded_value = base64_encode((const char *)value, value_len);
|
|
372
|
+
|
|
373
|
+
if (encoded_name != NULL && encoded_value != NULL) {
|
|
374
|
+
archive_string_init(&s);
|
|
375
|
+
archive_strcpy(&s, "LIBARCHIVE.xattr.");
|
|
376
|
+
archive_strcat(&s, encoded_name);
|
|
377
|
+
add_pax_attr(&(pax->pax_header), s.s, encoded_value);
|
|
378
|
+
archive_string_free(&s);
|
|
379
|
+
}
|
|
380
|
+
free(encoded_value);
|
|
381
|
+
}
|
|
382
|
+
if (pax->flags & WRITE_SCHILY_XATTR) {
|
|
383
|
+
archive_string_init(&s);
|
|
384
|
+
archive_strcpy(&s, "SCHILY.xattr.");
|
|
385
|
+
archive_strcat(&s, encoded_name);
|
|
386
|
+
add_pax_attr_binary(&(pax->pax_header), s.s, value, value_len);
|
|
387
|
+
archive_string_free(&s);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
static int
|
|
392
|
+
archive_write_pax_header_xattrs(struct archive_write *a,
|
|
393
|
+
struct pax *pax, struct archive_entry *entry)
|
|
394
|
+
{
|
|
349
395
|
int i = archive_entry_xattr_reset(entry);
|
|
350
396
|
|
|
351
397
|
while (i--) {
|
|
352
398
|
const char *name;
|
|
353
399
|
const void *value;
|
|
354
|
-
char *encoded_value;
|
|
355
400
|
char *url_encoded_name = NULL, *encoded_name = NULL;
|
|
356
|
-
wchar_t *wcs_name = NULL;
|
|
357
401
|
size_t size;
|
|
402
|
+
int r;
|
|
358
403
|
|
|
359
404
|
archive_entry_xattr_next(entry, &name, &value, &size);
|
|
360
|
-
/* Name is URL-encoded, then converted to wchar_t,
|
|
361
|
-
* then UTF-8 encoded. */
|
|
362
405
|
url_encoded_name = url_encode(name);
|
|
363
406
|
if (url_encoded_name != NULL) {
|
|
364
|
-
/* Convert narrow-character to
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
if (wcs_name == NULL)
|
|
368
|
-
__archive_errx(1, "No memory for xattr conversion");
|
|
369
|
-
mbstowcs(wcs_name, url_encoded_name, wcs_length);
|
|
370
|
-
wcs_name[wcs_length] = 0;
|
|
407
|
+
/* Convert narrow-character to UTF-8. */
|
|
408
|
+
r = archive_strcpy_l(&(pax->l_url_encoded_name),
|
|
409
|
+
url_encoded_name, pax->sconv_utf8);
|
|
371
410
|
free(url_encoded_name); /* Done with this. */
|
|
411
|
+
if (r == 0)
|
|
412
|
+
encoded_name = pax->l_url_encoded_name.s;
|
|
413
|
+
else if (errno == ENOMEM) {
|
|
414
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
415
|
+
"Can't allocate memory for Linkname");
|
|
416
|
+
return (ARCHIVE_FATAL);
|
|
417
|
+
}
|
|
372
418
|
}
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
419
|
+
|
|
420
|
+
archive_write_pax_header_xattr(pax, encoded_name,
|
|
421
|
+
value, size);
|
|
422
|
+
|
|
423
|
+
}
|
|
424
|
+
return (ARCHIVE_OK);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
static int
|
|
428
|
+
get_entry_hardlink(struct archive_write *a, struct archive_entry *entry,
|
|
429
|
+
const char **name, size_t *length, struct archive_string_conv *sc)
|
|
430
|
+
{
|
|
431
|
+
int r;
|
|
432
|
+
|
|
433
|
+
r = archive_entry_hardlink_l(entry, name, length, sc);
|
|
434
|
+
if (r != 0) {
|
|
435
|
+
if (errno == ENOMEM) {
|
|
436
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
437
|
+
"Can't allocate memory for Linkname");
|
|
438
|
+
return (ARCHIVE_FATAL);
|
|
376
439
|
}
|
|
440
|
+
return (ARCHIVE_WARN);
|
|
441
|
+
}
|
|
442
|
+
return (ARCHIVE_OK);
|
|
443
|
+
}
|
|
377
444
|
|
|
378
|
-
|
|
445
|
+
static int
|
|
446
|
+
get_entry_pathname(struct archive_write *a, struct archive_entry *entry,
|
|
447
|
+
const char **name, size_t *length, struct archive_string_conv *sc)
|
|
448
|
+
{
|
|
449
|
+
int r;
|
|
379
450
|
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
451
|
+
r = archive_entry_pathname_l(entry, name, length, sc);
|
|
452
|
+
if (r != 0) {
|
|
453
|
+
if (errno == ENOMEM) {
|
|
454
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
455
|
+
"Can't allocate memory for Pathname");
|
|
456
|
+
return (ARCHIVE_FATAL);
|
|
386
457
|
}
|
|
387
|
-
|
|
388
|
-
|
|
458
|
+
return (ARCHIVE_WARN);
|
|
459
|
+
}
|
|
460
|
+
return (ARCHIVE_OK);
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
static int
|
|
464
|
+
get_entry_uname(struct archive_write *a, struct archive_entry *entry,
|
|
465
|
+
const char **name, size_t *length, struct archive_string_conv *sc)
|
|
466
|
+
{
|
|
467
|
+
int r;
|
|
468
|
+
|
|
469
|
+
r = archive_entry_uname_l(entry, name, length, sc);
|
|
470
|
+
if (r != 0) {
|
|
471
|
+
if (errno == ENOMEM) {
|
|
472
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
473
|
+
"Can't allocate memory for Uname");
|
|
474
|
+
return (ARCHIVE_FATAL);
|
|
475
|
+
}
|
|
476
|
+
return (ARCHIVE_WARN);
|
|
477
|
+
}
|
|
478
|
+
return (ARCHIVE_OK);
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
static int
|
|
482
|
+
get_entry_gname(struct archive_write *a, struct archive_entry *entry,
|
|
483
|
+
const char **name, size_t *length, struct archive_string_conv *sc)
|
|
484
|
+
{
|
|
485
|
+
int r;
|
|
486
|
+
|
|
487
|
+
r = archive_entry_gname_l(entry, name, length, sc);
|
|
488
|
+
if (r != 0) {
|
|
489
|
+
if (errno == ENOMEM) {
|
|
490
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
491
|
+
"Can't allocate memory for Gname");
|
|
492
|
+
return (ARCHIVE_FATAL);
|
|
493
|
+
}
|
|
494
|
+
return (ARCHIVE_WARN);
|
|
495
|
+
}
|
|
496
|
+
return (ARCHIVE_OK);
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
static int
|
|
500
|
+
get_entry_symlink(struct archive_write *a, struct archive_entry *entry,
|
|
501
|
+
const char **name, size_t *length, struct archive_string_conv *sc)
|
|
502
|
+
{
|
|
503
|
+
int r;
|
|
504
|
+
|
|
505
|
+
r = archive_entry_symlink_l(entry, name, length, sc);
|
|
506
|
+
if (r != 0) {
|
|
507
|
+
if (errno == ENOMEM) {
|
|
508
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
509
|
+
"Can't allocate memory for Linkname");
|
|
510
|
+
return (ARCHIVE_FATAL);
|
|
511
|
+
}
|
|
512
|
+
return (ARCHIVE_WARN);
|
|
389
513
|
}
|
|
514
|
+
return (ARCHIVE_OK);
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
/* Add ACL to pax header */
|
|
518
|
+
static int
|
|
519
|
+
add_pax_acl(struct archive_write *a,
|
|
520
|
+
struct archive_entry *entry, struct pax *pax, int flags)
|
|
521
|
+
{
|
|
522
|
+
char *p;
|
|
523
|
+
const char *attr;
|
|
524
|
+
int acl_types;
|
|
525
|
+
|
|
526
|
+
acl_types = archive_entry_acl_types(entry);
|
|
527
|
+
|
|
528
|
+
if ((acl_types & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0)
|
|
529
|
+
attr = "SCHILY.acl.ace";
|
|
530
|
+
else if ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0)
|
|
531
|
+
attr = "SCHILY.acl.access";
|
|
532
|
+
else if ((flags & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0)
|
|
533
|
+
attr = "SCHILY.acl.default";
|
|
534
|
+
else
|
|
535
|
+
return (ARCHIVE_FATAL);
|
|
536
|
+
|
|
537
|
+
p = archive_entry_acl_to_text_l(entry, NULL, flags, pax->sconv_utf8);
|
|
538
|
+
if (p == NULL) {
|
|
539
|
+
if (errno == ENOMEM) {
|
|
540
|
+
archive_set_error(&a->archive, ENOMEM, "%s %s",
|
|
541
|
+
"Can't allocate memory for ", attr);
|
|
542
|
+
return (ARCHIVE_FATAL);
|
|
543
|
+
}
|
|
544
|
+
archive_set_error(&a->archive,
|
|
545
|
+
ARCHIVE_ERRNO_FILE_FORMAT, "%s %s %s",
|
|
546
|
+
"Can't translate ", attr, " to UTF-8");
|
|
547
|
+
return(ARCHIVE_WARN);
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
if (*p != '\0') {
|
|
551
|
+
add_pax_attr(&(pax->pax_header),
|
|
552
|
+
attr, p);
|
|
553
|
+
}
|
|
554
|
+
free(p);
|
|
555
|
+
return(ARCHIVE_OK);
|
|
390
556
|
}
|
|
391
557
|
|
|
392
558
|
/*
|
|
@@ -394,6 +560,8 @@ archive_write_pax_header_xattrs(struct pax *pax, struct archive_entry *entry)
|
|
|
394
560
|
* archive_entry so that clients can specify them. Also, consider
|
|
395
561
|
* adding generic key/value tags so clients can add arbitrary
|
|
396
562
|
* key/value data.
|
|
563
|
+
*
|
|
564
|
+
* TODO: Break up this 700-line function!!!! Yowza!
|
|
397
565
|
*/
|
|
398
566
|
static int
|
|
399
567
|
archive_write_pax_header(struct archive_write *a,
|
|
@@ -401,28 +569,73 @@ archive_write_pax_header(struct archive_write *a,
|
|
|
401
569
|
{
|
|
402
570
|
struct archive_entry *entry_main;
|
|
403
571
|
const char *p;
|
|
404
|
-
char *t;
|
|
405
|
-
const wchar_t *wp;
|
|
406
572
|
const char *suffix;
|
|
407
573
|
int need_extension, r, ret;
|
|
574
|
+
int acl_types;
|
|
575
|
+
int sparse_count;
|
|
576
|
+
uint64_t sparse_total, real_size;
|
|
408
577
|
struct pax *pax;
|
|
409
|
-
const char *hdrcharset = NULL;
|
|
410
578
|
const char *hardlink;
|
|
411
579
|
const char *path = NULL, *linkpath = NULL;
|
|
412
580
|
const char *uname = NULL, *gname = NULL;
|
|
413
|
-
const
|
|
414
|
-
|
|
581
|
+
const void *mac_metadata;
|
|
582
|
+
size_t mac_metadata_size;
|
|
583
|
+
struct archive_string_conv *sconv;
|
|
584
|
+
size_t hardlink_length, path_length, linkpath_length;
|
|
585
|
+
size_t uname_length, gname_length;
|
|
415
586
|
|
|
416
587
|
char paxbuff[512];
|
|
417
588
|
char ustarbuff[512];
|
|
418
589
|
char ustar_entry_name[256];
|
|
419
590
|
char pax_entry_name[256];
|
|
591
|
+
char gnu_sparse_name[256];
|
|
592
|
+
struct archive_string entry_name;
|
|
420
593
|
|
|
421
594
|
ret = ARCHIVE_OK;
|
|
422
595
|
need_extension = 0;
|
|
423
596
|
pax = (struct pax *)a->format_data;
|
|
424
597
|
|
|
425
|
-
|
|
598
|
+
/* Sanity check. */
|
|
599
|
+
if (archive_entry_pathname(entry_original) == NULL) {
|
|
600
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
601
|
+
"Can't record entry in tar file without pathname");
|
|
602
|
+
return (ARCHIVE_FAILED);
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
/*
|
|
606
|
+
* Choose a header encoding.
|
|
607
|
+
*/
|
|
608
|
+
if (pax->opt_binary)
|
|
609
|
+
sconv = NULL;/* Binary mode. */
|
|
610
|
+
else {
|
|
611
|
+
/* Header encoding is UTF-8. */
|
|
612
|
+
if (pax->sconv_utf8 == NULL) {
|
|
613
|
+
/* Initialize the string conversion object
|
|
614
|
+
* we must need */
|
|
615
|
+
pax->sconv_utf8 = archive_string_conversion_to_charset(
|
|
616
|
+
&(a->archive), "UTF-8", 1);
|
|
617
|
+
if (pax->sconv_utf8 == NULL)
|
|
618
|
+
/* Couldn't allocate memory */
|
|
619
|
+
return (ARCHIVE_FAILED);
|
|
620
|
+
}
|
|
621
|
+
sconv = pax->sconv_utf8;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
r = get_entry_hardlink(a, entry_original, &hardlink,
|
|
625
|
+
&hardlink_length, sconv);
|
|
626
|
+
if (r == ARCHIVE_FATAL)
|
|
627
|
+
return (r);
|
|
628
|
+
else if (r != ARCHIVE_OK) {
|
|
629
|
+
r = get_entry_hardlink(a, entry_original, &hardlink,
|
|
630
|
+
&hardlink_length, NULL);
|
|
631
|
+
if (r == ARCHIVE_FATAL)
|
|
632
|
+
return (r);
|
|
633
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
634
|
+
"Can't translate linkname '%s' to %s", hardlink,
|
|
635
|
+
archive_string_conversion_charset_name(sconv));
|
|
636
|
+
ret = ARCHIVE_WARN;
|
|
637
|
+
sconv = NULL;/* The header charset switches to binary mode. */
|
|
638
|
+
}
|
|
426
639
|
|
|
427
640
|
/* Make sure this is a type of entry that we can handle here */
|
|
428
641
|
if (hardlink == NULL) {
|
|
@@ -434,90 +647,317 @@ archive_write_pax_header(struct archive_write *a,
|
|
|
434
647
|
case AE_IFREG:
|
|
435
648
|
break;
|
|
436
649
|
case AE_IFDIR:
|
|
650
|
+
{
|
|
437
651
|
/*
|
|
438
652
|
* Ensure a trailing '/'. Modify the original
|
|
439
653
|
* entry so the client sees the change.
|
|
440
654
|
*/
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
655
|
+
#if defined(_WIN32) && !defined(__CYGWIN__)
|
|
656
|
+
const wchar_t *wp;
|
|
657
|
+
|
|
658
|
+
wp = archive_entry_pathname_w(entry_original);
|
|
659
|
+
if (wp != NULL && wp[wcslen(wp) -1] != L'/') {
|
|
660
|
+
struct archive_wstring ws;
|
|
661
|
+
|
|
662
|
+
archive_string_init(&ws);
|
|
663
|
+
path_length = wcslen(wp);
|
|
664
|
+
if (archive_wstring_ensure(&ws,
|
|
665
|
+
path_length + 2) == NULL) {
|
|
666
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
667
|
+
"Can't allocate pax data");
|
|
668
|
+
archive_wstring_free(&ws);
|
|
669
|
+
return(ARCHIVE_FATAL);
|
|
670
|
+
}
|
|
671
|
+
/* Should we keep '\' ? */
|
|
672
|
+
if (wp[path_length -1] == L'\\')
|
|
673
|
+
path_length--;
|
|
674
|
+
archive_wstrncpy(&ws, wp, path_length);
|
|
675
|
+
archive_wstrappend_wchar(&ws, L'/');
|
|
676
|
+
archive_entry_copy_pathname_w(
|
|
677
|
+
entry_original, ws.s);
|
|
678
|
+
archive_wstring_free(&ws);
|
|
679
|
+
p = NULL;
|
|
680
|
+
} else
|
|
681
|
+
#endif
|
|
682
|
+
p = archive_entry_pathname(entry_original);
|
|
683
|
+
/*
|
|
684
|
+
* On Windows, this is a backup operation just in
|
|
685
|
+
* case getting WCS failed. On POSIX, this is a
|
|
686
|
+
* normal operation.
|
|
687
|
+
*/
|
|
688
|
+
if (p != NULL && p[0] != '\0' && p[strlen(p) - 1] != '/') {
|
|
689
|
+
struct archive_string as;
|
|
690
|
+
|
|
691
|
+
archive_string_init(&as);
|
|
692
|
+
path_length = strlen(p);
|
|
693
|
+
if (archive_string_ensure(&as,
|
|
694
|
+
path_length + 2) == NULL) {
|
|
445
695
|
archive_set_error(&a->archive, ENOMEM,
|
|
446
|
-
|
|
696
|
+
"Can't allocate pax data");
|
|
697
|
+
archive_string_free(&as);
|
|
447
698
|
return(ARCHIVE_FATAL);
|
|
448
699
|
}
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
700
|
+
#if defined(_WIN32) && !defined(__CYGWIN__)
|
|
701
|
+
/* NOTE: This might break the pathname
|
|
702
|
+
* if the current code page is CP932 and
|
|
703
|
+
* the pathname includes a character '\'
|
|
704
|
+
* as a part of its multibyte pathname. */
|
|
705
|
+
if (p[strlen(p) -1] == '\\')
|
|
706
|
+
path_length--;
|
|
707
|
+
else
|
|
708
|
+
#endif
|
|
709
|
+
archive_strncpy(&as, p, path_length);
|
|
710
|
+
archive_strappend_char(&as, '/');
|
|
711
|
+
archive_entry_copy_pathname(
|
|
712
|
+
entry_original, as.s);
|
|
713
|
+
archive_string_free(&as);
|
|
453
714
|
}
|
|
454
715
|
break;
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
return (
|
|
460
|
-
default:
|
|
461
|
-
archive_set_error(&a->archive,
|
|
462
|
-
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
463
|
-
"tar format cannot archive this (type=0%lo)",
|
|
464
|
-
(unsigned long)archive_entry_filetype(entry_original));
|
|
465
|
-
return (ARCHIVE_WARN);
|
|
716
|
+
}
|
|
717
|
+
default: /* AE_IFSOCK and unknown */
|
|
718
|
+
__archive_write_entry_filetype_unsupported(
|
|
719
|
+
&a->archive, entry_original, "pax");
|
|
720
|
+
return (ARCHIVE_FAILED);
|
|
466
721
|
}
|
|
467
722
|
}
|
|
468
723
|
|
|
724
|
+
/*
|
|
725
|
+
* If Mac OS metadata blob is here, recurse to write that
|
|
726
|
+
* as a separate entry. This is really a pretty poor design:
|
|
727
|
+
* In particular, it doubles the overhead for long filenames.
|
|
728
|
+
* TODO: Help Apple folks design something better and figure
|
|
729
|
+
* out how to transition from this legacy format.
|
|
730
|
+
*
|
|
731
|
+
* Note that this code is present on every platform; clients
|
|
732
|
+
* on non-Mac are unlikely to ever provide this data, but
|
|
733
|
+
* applications that copy entries from one archive to another
|
|
734
|
+
* should not lose data just because the local filesystem
|
|
735
|
+
* can't store it.
|
|
736
|
+
*/
|
|
737
|
+
mac_metadata =
|
|
738
|
+
archive_entry_mac_metadata(entry_original, &mac_metadata_size);
|
|
739
|
+
if (mac_metadata != NULL) {
|
|
740
|
+
const char *oname;
|
|
741
|
+
char *name, *bname;
|
|
742
|
+
size_t name_length;
|
|
743
|
+
struct archive_entry *extra = archive_entry_new2(&a->archive);
|
|
744
|
+
|
|
745
|
+
oname = archive_entry_pathname(entry_original);
|
|
746
|
+
name_length = strlen(oname);
|
|
747
|
+
name = malloc(name_length + 3);
|
|
748
|
+
if (name == NULL || extra == NULL) {
|
|
749
|
+
/* XXX error message */
|
|
750
|
+
archive_entry_free(extra);
|
|
751
|
+
free(name);
|
|
752
|
+
return (ARCHIVE_FAILED);
|
|
753
|
+
}
|
|
754
|
+
strcpy(name, oname);
|
|
755
|
+
/* Find last '/'; strip trailing '/' characters */
|
|
756
|
+
bname = strrchr(name, '/');
|
|
757
|
+
while (bname != NULL && bname[1] == '\0') {
|
|
758
|
+
*bname = '\0';
|
|
759
|
+
bname = strrchr(name, '/');
|
|
760
|
+
}
|
|
761
|
+
if (bname == NULL) {
|
|
762
|
+
memmove(name + 2, name, name_length + 1);
|
|
763
|
+
memmove(name, "._", 2);
|
|
764
|
+
} else {
|
|
765
|
+
bname += 1;
|
|
766
|
+
memmove(bname + 2, bname, strlen(bname) + 1);
|
|
767
|
+
memmove(bname, "._", 2);
|
|
768
|
+
}
|
|
769
|
+
archive_entry_copy_pathname(extra, name);
|
|
770
|
+
free(name);
|
|
771
|
+
|
|
772
|
+
archive_entry_set_size(extra, mac_metadata_size);
|
|
773
|
+
archive_entry_set_filetype(extra, AE_IFREG);
|
|
774
|
+
archive_entry_set_perm(extra,
|
|
775
|
+
archive_entry_perm(entry_original));
|
|
776
|
+
archive_entry_set_mtime(extra,
|
|
777
|
+
archive_entry_mtime(entry_original),
|
|
778
|
+
archive_entry_mtime_nsec(entry_original));
|
|
779
|
+
archive_entry_set_gid(extra,
|
|
780
|
+
archive_entry_gid(entry_original));
|
|
781
|
+
archive_entry_set_gname(extra,
|
|
782
|
+
archive_entry_gname(entry_original));
|
|
783
|
+
archive_entry_set_uid(extra,
|
|
784
|
+
archive_entry_uid(entry_original));
|
|
785
|
+
archive_entry_set_uname(extra,
|
|
786
|
+
archive_entry_uname(entry_original));
|
|
787
|
+
|
|
788
|
+
/* Recurse to write the special copyfile entry. */
|
|
789
|
+
r = archive_write_pax_header(a, extra);
|
|
790
|
+
archive_entry_free(extra);
|
|
791
|
+
if (r < ARCHIVE_WARN)
|
|
792
|
+
return (r);
|
|
793
|
+
if (r < ret)
|
|
794
|
+
ret = r;
|
|
795
|
+
r = (int)archive_write_pax_data(a, mac_metadata,
|
|
796
|
+
mac_metadata_size);
|
|
797
|
+
if (r < ARCHIVE_WARN)
|
|
798
|
+
return (r);
|
|
799
|
+
if (r < ret)
|
|
800
|
+
ret = r;
|
|
801
|
+
r = archive_write_pax_finish_entry(a);
|
|
802
|
+
if (r < ARCHIVE_WARN)
|
|
803
|
+
return (r);
|
|
804
|
+
if (r < ret)
|
|
805
|
+
ret = r;
|
|
806
|
+
}
|
|
807
|
+
|
|
469
808
|
/* Copy entry so we can modify it as needed. */
|
|
809
|
+
#if defined(_WIN32) && !defined(__CYGWIN__)
|
|
810
|
+
/* Make sure the path separators in pathname, hardlink and symlink
|
|
811
|
+
* are all slash '/', not the Windows path separator '\'. */
|
|
812
|
+
entry_main = __la_win_entry_in_posix_pathseparator(entry_original);
|
|
813
|
+
if (entry_main == entry_original)
|
|
814
|
+
entry_main = archive_entry_clone(entry_original);
|
|
815
|
+
#else
|
|
470
816
|
entry_main = archive_entry_clone(entry_original);
|
|
817
|
+
#endif
|
|
818
|
+
if (entry_main == NULL) {
|
|
819
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
820
|
+
"Can't allocate pax data");
|
|
821
|
+
return(ARCHIVE_FATAL);
|
|
822
|
+
}
|
|
471
823
|
archive_string_empty(&(pax->pax_header)); /* Blank our work area. */
|
|
824
|
+
archive_string_empty(&(pax->sparse_map));
|
|
825
|
+
sparse_total = 0;
|
|
826
|
+
sparse_list_clear(pax);
|
|
827
|
+
|
|
828
|
+
if (hardlink == NULL &&
|
|
829
|
+
archive_entry_filetype(entry_main) == AE_IFREG)
|
|
830
|
+
sparse_count = archive_entry_sparse_reset(entry_main);
|
|
831
|
+
else
|
|
832
|
+
sparse_count = 0;
|
|
833
|
+
if (sparse_count) {
|
|
834
|
+
int64_t offset, length, last_offset = 0;
|
|
835
|
+
/* Get the last entry of sparse block. */
|
|
836
|
+
while (archive_entry_sparse_next(
|
|
837
|
+
entry_main, &offset, &length) == ARCHIVE_OK)
|
|
838
|
+
last_offset = offset + length;
|
|
839
|
+
|
|
840
|
+
/* If the last sparse block does not reach the end of file,
|
|
841
|
+
* We have to add a empty sparse block as the last entry to
|
|
842
|
+
* manage storing file data. */
|
|
843
|
+
if (last_offset < archive_entry_size(entry_main))
|
|
844
|
+
archive_entry_sparse_add_entry(entry_main,
|
|
845
|
+
archive_entry_size(entry_main), 0);
|
|
846
|
+
sparse_count = archive_entry_sparse_reset(entry_main);
|
|
847
|
+
}
|
|
472
848
|
|
|
473
849
|
/*
|
|
474
850
|
* First, check the name fields and see if any of them
|
|
475
851
|
* require binary coding. If any of them does, then all of
|
|
476
852
|
* them do.
|
|
477
853
|
*/
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
854
|
+
r = get_entry_pathname(a, entry_main, &path, &path_length, sconv);
|
|
855
|
+
if (r == ARCHIVE_FATAL) {
|
|
856
|
+
archive_entry_free(entry_main);
|
|
857
|
+
return (r);
|
|
858
|
+
} else if (r != ARCHIVE_OK) {
|
|
859
|
+
r = get_entry_pathname(a, entry_main, &path,
|
|
860
|
+
&path_length, NULL);
|
|
861
|
+
if (r == ARCHIVE_FATAL) {
|
|
862
|
+
archive_entry_free(entry_main);
|
|
863
|
+
return (r);
|
|
864
|
+
}
|
|
482
865
|
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
483
|
-
"Can't translate pathname '%s' to
|
|
866
|
+
"Can't translate pathname '%s' to %s", path,
|
|
867
|
+
archive_string_conversion_charset_name(sconv));
|
|
484
868
|
ret = ARCHIVE_WARN;
|
|
485
|
-
|
|
869
|
+
sconv = NULL;/* The header charset switches to binary mode. */
|
|
486
870
|
}
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
871
|
+
r = get_entry_uname(a, entry_main, &uname, &uname_length, sconv);
|
|
872
|
+
if (r == ARCHIVE_FATAL) {
|
|
873
|
+
archive_entry_free(entry_main);
|
|
874
|
+
return (r);
|
|
875
|
+
} else if (r != ARCHIVE_OK) {
|
|
876
|
+
r = get_entry_uname(a, entry_main, &uname, &uname_length, NULL);
|
|
877
|
+
if (r == ARCHIVE_FATAL) {
|
|
878
|
+
archive_entry_free(entry_main);
|
|
879
|
+
return (r);
|
|
880
|
+
}
|
|
490
881
|
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
491
|
-
"Can't translate uname '%s' to
|
|
882
|
+
"Can't translate uname '%s' to %s", uname,
|
|
883
|
+
archive_string_conversion_charset_name(sconv));
|
|
492
884
|
ret = ARCHIVE_WARN;
|
|
493
|
-
|
|
885
|
+
sconv = NULL;/* The header charset switches to binary mode. */
|
|
494
886
|
}
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
887
|
+
r = get_entry_gname(a, entry_main, &gname, &gname_length, sconv);
|
|
888
|
+
if (r == ARCHIVE_FATAL) {
|
|
889
|
+
archive_entry_free(entry_main);
|
|
890
|
+
return (r);
|
|
891
|
+
} else if (r != ARCHIVE_OK) {
|
|
892
|
+
r = get_entry_gname(a, entry_main, &gname, &gname_length, NULL);
|
|
893
|
+
if (r == ARCHIVE_FATAL) {
|
|
894
|
+
archive_entry_free(entry_main);
|
|
895
|
+
return (r);
|
|
896
|
+
}
|
|
498
897
|
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
499
|
-
"Can't translate gname '%s' to
|
|
898
|
+
"Can't translate gname '%s' to %s", gname,
|
|
899
|
+
archive_string_conversion_charset_name(sconv));
|
|
500
900
|
ret = ARCHIVE_WARN;
|
|
501
|
-
|
|
901
|
+
sconv = NULL;/* The header charset switches to binary mode. */
|
|
502
902
|
}
|
|
503
903
|
linkpath = hardlink;
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
if (
|
|
509
|
-
|
|
904
|
+
linkpath_length = hardlink_length;
|
|
905
|
+
if (linkpath == NULL) {
|
|
906
|
+
r = get_entry_symlink(a, entry_main, &linkpath,
|
|
907
|
+
&linkpath_length, sconv);
|
|
908
|
+
if (r == ARCHIVE_FATAL) {
|
|
909
|
+
archive_entry_free(entry_main);
|
|
910
|
+
return (r);
|
|
911
|
+
} else if (r != ARCHIVE_OK) {
|
|
912
|
+
r = get_entry_symlink(a, entry_main, &linkpath,
|
|
913
|
+
&linkpath_length, NULL);
|
|
914
|
+
if (r == ARCHIVE_FATAL) {
|
|
915
|
+
archive_entry_free(entry_main);
|
|
916
|
+
return (r);
|
|
917
|
+
}
|
|
918
|
+
archive_set_error(&a->archive,
|
|
919
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
920
|
+
"Can't translate linkname '%s' to %s", linkpath,
|
|
921
|
+
archive_string_conversion_charset_name(sconv));
|
|
922
|
+
ret = ARCHIVE_WARN;
|
|
923
|
+
sconv = NULL;
|
|
924
|
+
}
|
|
510
925
|
}
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
926
|
+
|
|
927
|
+
/* If any string conversions failed, get all attributes
|
|
928
|
+
* in binary-mode. */
|
|
929
|
+
if (sconv == NULL && !pax->opt_binary) {
|
|
930
|
+
if (hardlink != NULL) {
|
|
931
|
+
r = get_entry_hardlink(a, entry_main, &hardlink,
|
|
932
|
+
&hardlink_length, NULL);
|
|
933
|
+
if (r == ARCHIVE_FATAL) {
|
|
934
|
+
archive_entry_free(entry_main);
|
|
935
|
+
return (r);
|
|
936
|
+
}
|
|
937
|
+
linkpath = hardlink;
|
|
938
|
+
linkpath_length = hardlink_length;
|
|
939
|
+
}
|
|
940
|
+
r = get_entry_pathname(a, entry_main, &path,
|
|
941
|
+
&path_length, NULL);
|
|
942
|
+
if (r == ARCHIVE_FATAL) {
|
|
943
|
+
archive_entry_free(entry_main);
|
|
944
|
+
return (r);
|
|
945
|
+
}
|
|
946
|
+
r = get_entry_uname(a, entry_main, &uname, &uname_length, NULL);
|
|
947
|
+
if (r == ARCHIVE_FATAL) {
|
|
948
|
+
archive_entry_free(entry_main);
|
|
949
|
+
return (r);
|
|
950
|
+
}
|
|
951
|
+
r = get_entry_gname(a, entry_main, &gname, &gname_length, NULL);
|
|
952
|
+
if (r == ARCHIVE_FATAL) {
|
|
953
|
+
archive_entry_free(entry_main);
|
|
954
|
+
return (r);
|
|
955
|
+
}
|
|
516
956
|
}
|
|
517
957
|
|
|
518
958
|
/* Store the header encoding first, to be nice to readers. */
|
|
519
|
-
if (
|
|
520
|
-
add_pax_attr(&(pax->pax_header), "hdrcharset",
|
|
959
|
+
if (sconv == NULL)
|
|
960
|
+
add_pax_attr(&(pax->pax_header), "hdrcharset", "BINARY");
|
|
521
961
|
|
|
522
962
|
|
|
523
963
|
/*
|
|
@@ -525,38 +965,25 @@ archive_write_pax_header(struct archive_write *a,
|
|
|
525
965
|
* 'path' to pax extended attrs. (Note that an unconvertible
|
|
526
966
|
* name must have non-ASCII characters.)
|
|
527
967
|
*/
|
|
528
|
-
if (path
|
|
529
|
-
/* We don't have a narrow version, so we have to store
|
|
530
|
-
* the wide version. */
|
|
531
|
-
add_pax_attr_w(&(pax->pax_header), "path", path_w);
|
|
532
|
-
archive_entry_set_pathname(entry_main, "@WidePath");
|
|
533
|
-
need_extension = 1;
|
|
534
|
-
} else if (has_non_ASCII(path_w)) {
|
|
968
|
+
if (has_non_ASCII(path)) {
|
|
535
969
|
/* We have non-ASCII characters. */
|
|
536
|
-
|
|
537
|
-
/* Can't do UTF-8, so store it raw. */
|
|
538
|
-
add_pax_attr(&(pax->pax_header), "path", path);
|
|
539
|
-
} else {
|
|
540
|
-
/* Store UTF-8 */
|
|
541
|
-
add_pax_attr_w(&(pax->pax_header),
|
|
542
|
-
"path", path_w);
|
|
543
|
-
}
|
|
970
|
+
add_pax_attr(&(pax->pax_header), "path", path);
|
|
544
971
|
archive_entry_set_pathname(entry_main,
|
|
545
972
|
build_ustar_entry_name(ustar_entry_name,
|
|
546
|
-
path,
|
|
973
|
+
path, path_length, NULL));
|
|
547
974
|
need_extension = 1;
|
|
548
975
|
} else {
|
|
549
976
|
/* We have an all-ASCII path; we'd like to just store
|
|
550
977
|
* it in the ustar header if it will fit. Yes, this
|
|
551
978
|
* duplicates some of the logic in
|
|
552
|
-
*
|
|
979
|
+
* archive_write_set_format_ustar.c
|
|
553
980
|
*/
|
|
554
|
-
if (
|
|
981
|
+
if (path_length <= 100) {
|
|
555
982
|
/* Fits in the old 100-char tar name field. */
|
|
556
983
|
} else {
|
|
557
984
|
/* Find largest suffix that will fit. */
|
|
558
985
|
/* Note: strlen() > 100, so strlen() - 100 - 1 >= 0 */
|
|
559
|
-
suffix = strchr(path +
|
|
986
|
+
suffix = strchr(path + path_length - 100 - 1, '/');
|
|
560
987
|
/* Don't attempt an empty prefix. */
|
|
561
988
|
if (suffix == path)
|
|
562
989
|
suffix = strchr(suffix + 1, '/');
|
|
@@ -571,18 +998,10 @@ archive_write_pax_header(struct archive_write *a,
|
|
|
571
998
|
|| suffix[1] == '\0' /* empty suffix */
|
|
572
999
|
|| suffix - path > 155) /* Prefix > 155 chars */
|
|
573
1000
|
{
|
|
574
|
-
|
|
575
|
-
/* Can't do UTF-8, so store it raw. */
|
|
576
|
-
add_pax_attr(&(pax->pax_header),
|
|
577
|
-
"path", path);
|
|
578
|
-
} else {
|
|
579
|
-
/* Store UTF-8 */
|
|
580
|
-
add_pax_attr_w(&(pax->pax_header),
|
|
581
|
-
"path", path_w);
|
|
582
|
-
}
|
|
1001
|
+
add_pax_attr(&(pax->pax_header), "path", path);
|
|
583
1002
|
archive_entry_set_pathname(entry_main,
|
|
584
1003
|
build_ustar_entry_name(ustar_entry_name,
|
|
585
|
-
path,
|
|
1004
|
+
path, path_length, NULL));
|
|
586
1005
|
need_extension = 1;
|
|
587
1006
|
}
|
|
588
1007
|
}
|
|
@@ -591,21 +1010,9 @@ archive_write_pax_header(struct archive_write *a,
|
|
|
591
1010
|
if (linkpath != NULL) {
|
|
592
1011
|
/* If link name is too long or has non-ASCII characters, add
|
|
593
1012
|
* 'linkpath' to pax extended attrs. */
|
|
594
|
-
if (
|
|
595
|
-
|
|
596
|
-
if (
|
|
597
|
-
/* If the linkpath is not convertible
|
|
598
|
-
* to wide, or we're encoding in
|
|
599
|
-
* binary anyway, store it raw. */
|
|
600
|
-
add_pax_attr(&(pax->pax_header),
|
|
601
|
-
"linkpath", linkpath);
|
|
602
|
-
else
|
|
603
|
-
/* If the link is long or has a
|
|
604
|
-
* non-ASCII character, store it as a
|
|
605
|
-
* pax extended attribute. */
|
|
606
|
-
add_pax_attr_w(&(pax->pax_header),
|
|
607
|
-
"linkpath", linkpath_w);
|
|
608
|
-
if (strlen(linkpath) > 100) {
|
|
1013
|
+
if (linkpath_length > 100 || has_non_ASCII(linkpath)) {
|
|
1014
|
+
add_pax_attr(&(pax->pax_header), "linkpath", linkpath);
|
|
1015
|
+
if (linkpath_length > 100) {
|
|
609
1016
|
if (hardlink != NULL)
|
|
610
1017
|
archive_entry_set_hardlink(entry_main,
|
|
611
1018
|
"././@LongHardLink");
|
|
@@ -616,11 +1023,13 @@ archive_write_pax_header(struct archive_write *a,
|
|
|
616
1023
|
need_extension = 1;
|
|
617
1024
|
}
|
|
618
1025
|
}
|
|
1026
|
+
/* Save a pathname since it will be renamed if `entry_main` has
|
|
1027
|
+
* sparse blocks. */
|
|
1028
|
+
archive_string_init(&entry_name);
|
|
1029
|
+
archive_strcpy(&entry_name, archive_entry_pathname(entry_main));
|
|
619
1030
|
|
|
620
|
-
/* If file size is too large,
|
|
1031
|
+
/* If file size is too large, we need pax extended attrs. */
|
|
621
1032
|
if (archive_entry_size(entry_main) >= (((int64_t)1) << 33)) {
|
|
622
|
-
add_pax_attr_int(&(pax->pax_header), "size",
|
|
623
|
-
archive_entry_size(entry_main));
|
|
624
1033
|
need_extension = 1;
|
|
625
1034
|
}
|
|
626
1035
|
|
|
@@ -634,17 +1043,8 @@ archive_write_pax_header(struct archive_write *a,
|
|
|
634
1043
|
/* If group name is too large or has non-ASCII characters, add
|
|
635
1044
|
* 'gname' to pax extended attrs. */
|
|
636
1045
|
if (gname != NULL) {
|
|
637
|
-
if (
|
|
638
|
-
|
|
639
|
-
|| has_non_ASCII(gname_w))
|
|
640
|
-
{
|
|
641
|
-
if (gname_w == NULL || hdrcharset != NULL) {
|
|
642
|
-
add_pax_attr(&(pax->pax_header),
|
|
643
|
-
"gname", gname);
|
|
644
|
-
} else {
|
|
645
|
-
add_pax_attr_w(&(pax->pax_header),
|
|
646
|
-
"gname", gname_w);
|
|
647
|
-
}
|
|
1046
|
+
if (gname_length > 31 || has_non_ASCII(gname)) {
|
|
1047
|
+
add_pax_attr(&(pax->pax_header), "gname", gname);
|
|
648
1048
|
need_extension = 1;
|
|
649
1049
|
}
|
|
650
1050
|
}
|
|
@@ -658,17 +1058,8 @@ archive_write_pax_header(struct archive_write *a,
|
|
|
658
1058
|
|
|
659
1059
|
/* Add 'uname' to pax extended attrs if necessary. */
|
|
660
1060
|
if (uname != NULL) {
|
|
661
|
-
if (
|
|
662
|
-
|
|
663
|
-
|| has_non_ASCII(uname_w))
|
|
664
|
-
{
|
|
665
|
-
if (uname_w == NULL || hdrcharset != NULL) {
|
|
666
|
-
add_pax_attr(&(pax->pax_header),
|
|
667
|
-
"uname", uname);
|
|
668
|
-
} else {
|
|
669
|
-
add_pax_attr_w(&(pax->pax_header),
|
|
670
|
-
"uname", uname_w);
|
|
671
|
-
}
|
|
1061
|
+
if (uname_length > 31 || has_non_ASCII(uname)) {
|
|
1062
|
+
add_pax_attr(&(pax->pax_header), "uname", uname);
|
|
672
1063
|
need_extension = 1;
|
|
673
1064
|
}
|
|
674
1065
|
}
|
|
@@ -690,7 +1081,7 @@ archive_write_pax_header(struct archive_write *a,
|
|
|
690
1081
|
* If rdevmajor is too large, add 'SCHILY.devmajor' to
|
|
691
1082
|
* extended attributes.
|
|
692
1083
|
*/
|
|
693
|
-
|
|
1084
|
+
int rdevmajor, rdevminor;
|
|
694
1085
|
rdevmajor = archive_entry_rdevmajor(entry_main);
|
|
695
1086
|
rdevminor = archive_entry_rdevminor(entry_main);
|
|
696
1087
|
if (rdevmajor >= (1 << 18)) {
|
|
@@ -742,37 +1133,31 @@ archive_write_pax_header(struct archive_write *a,
|
|
|
742
1133
|
if (!need_extension && p != NULL && *p != '\0')
|
|
743
1134
|
need_extension = 1;
|
|
744
1135
|
|
|
745
|
-
/* If there are
|
|
746
|
-
if (!need_extension &&
|
|
747
|
-
ARCHIVE_ENTRY_ACL_TYPE_ACCESS) > 0)
|
|
1136
|
+
/* If there are extended attributes, we need an extension */
|
|
1137
|
+
if (!need_extension && archive_entry_xattr_count(entry_original) > 0)
|
|
748
1138
|
need_extension = 1;
|
|
749
1139
|
|
|
750
|
-
/* If there are
|
|
751
|
-
if (!need_extension &&
|
|
752
|
-
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) > 0)
|
|
1140
|
+
/* If there are sparse info, we need an extension */
|
|
1141
|
+
if (!need_extension && sparse_count > 0)
|
|
753
1142
|
need_extension = 1;
|
|
754
1143
|
|
|
755
|
-
|
|
756
|
-
|
|
1144
|
+
acl_types = archive_entry_acl_types(entry_original);
|
|
1145
|
+
|
|
1146
|
+
/* If there are any ACL entries, we need an extension */
|
|
1147
|
+
if (!need_extension && acl_types != 0)
|
|
1148
|
+
need_extension = 1;
|
|
1149
|
+
|
|
1150
|
+
/* If the symlink type is defined, we need an extension */
|
|
1151
|
+
if (!need_extension && archive_entry_symlink_type(entry_main) > 0)
|
|
757
1152
|
need_extension = 1;
|
|
758
1153
|
|
|
759
1154
|
/*
|
|
760
|
-
*
|
|
761
|
-
* restricted
|
|
762
|
-
*
|
|
763
|
-
*
|
|
764
|
-
* may as well include these).
|
|
1155
|
+
* Libarchive used to include these in extended headers for
|
|
1156
|
+
* restricted pax format, but that confused people who
|
|
1157
|
+
* expected ustar-like time semantics. So now we only include
|
|
1158
|
+
* them in full pax format.
|
|
765
1159
|
*/
|
|
766
|
-
if (a->archive.archive_format != ARCHIVE_FORMAT_TAR_PAX_RESTRICTED
|
|
767
|
-
need_extension) {
|
|
768
|
-
|
|
769
|
-
if (archive_entry_mtime(entry_main) < 0 ||
|
|
770
|
-
archive_entry_mtime(entry_main) >= 0x7fffffff ||
|
|
771
|
-
archive_entry_mtime_nsec(entry_main) != 0)
|
|
772
|
-
add_pax_attr_time(&(pax->pax_header), "mtime",
|
|
773
|
-
archive_entry_mtime(entry_main),
|
|
774
|
-
archive_entry_mtime_nsec(entry_main));
|
|
775
|
-
|
|
1160
|
+
if (a->archive.archive_format != ARCHIVE_FORMAT_TAR_PAX_RESTRICTED) {
|
|
776
1161
|
if (archive_entry_ctime(entry_main) != 0 ||
|
|
777
1162
|
archive_entry_ctime_nsec(entry_main) != 0)
|
|
778
1163
|
add_pax_attr_time(&(pax->pax_header), "ctime",
|
|
@@ -793,6 +1178,23 @@ archive_write_pax_header(struct archive_write *a,
|
|
|
793
1178
|
"LIBARCHIVE.creationtime",
|
|
794
1179
|
archive_entry_birthtime(entry_main),
|
|
795
1180
|
archive_entry_birthtime_nsec(entry_main));
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
/*
|
|
1184
|
+
* The following items are handled differently in "pax
|
|
1185
|
+
* restricted" format. In particular, in "pax restricted"
|
|
1186
|
+
* format they won't be added unless need_extension is
|
|
1187
|
+
* already set (we're already generating an extended header, so
|
|
1188
|
+
* may as well include these).
|
|
1189
|
+
*/
|
|
1190
|
+
if (a->archive.archive_format != ARCHIVE_FORMAT_TAR_PAX_RESTRICTED ||
|
|
1191
|
+
need_extension) {
|
|
1192
|
+
if (archive_entry_mtime(entry_main) < 0 ||
|
|
1193
|
+
archive_entry_mtime(entry_main) >= 0x7fffffff ||
|
|
1194
|
+
archive_entry_mtime_nsec(entry_main) != 0)
|
|
1195
|
+
add_pax_attr_time(&(pax->pax_header), "mtime",
|
|
1196
|
+
archive_entry_mtime(entry_main),
|
|
1197
|
+
archive_entry_mtime_nsec(entry_main));
|
|
796
1198
|
|
|
797
1199
|
/* I use a star-compatible file flag attribute. */
|
|
798
1200
|
p = archive_entry_fflags_text(entry_main);
|
|
@@ -800,31 +1202,108 @@ archive_write_pax_header(struct archive_write *a,
|
|
|
800
1202
|
add_pax_attr(&(pax->pax_header), "SCHILY.fflags", p);
|
|
801
1203
|
|
|
802
1204
|
/* I use star-compatible ACL attributes. */
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
1205
|
+
if ((acl_types & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
|
|
1206
|
+
ret = add_pax_acl(a, entry_original, pax,
|
|
1207
|
+
ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID |
|
|
1208
|
+
ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA |
|
|
1209
|
+
ARCHIVE_ENTRY_ACL_STYLE_COMPACT);
|
|
1210
|
+
if (ret == ARCHIVE_FATAL) {
|
|
1211
|
+
archive_entry_free(entry_main);
|
|
1212
|
+
archive_string_free(&entry_name);
|
|
1213
|
+
return (ARCHIVE_FATAL);
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
if (acl_types & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) {
|
|
1217
|
+
ret = add_pax_acl(a, entry_original, pax,
|
|
1218
|
+
ARCHIVE_ENTRY_ACL_TYPE_ACCESS |
|
|
1219
|
+
ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID |
|
|
1220
|
+
ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA);
|
|
1221
|
+
if (ret == ARCHIVE_FATAL) {
|
|
1222
|
+
archive_entry_free(entry_main);
|
|
1223
|
+
archive_string_free(&entry_name);
|
|
1224
|
+
return (ARCHIVE_FATAL);
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1227
|
+
if (acl_types & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) {
|
|
1228
|
+
ret = add_pax_acl(a, entry_original, pax,
|
|
1229
|
+
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT |
|
|
1230
|
+
ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID |
|
|
1231
|
+
ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA);
|
|
1232
|
+
if (ret == ARCHIVE_FATAL) {
|
|
1233
|
+
archive_entry_free(entry_main);
|
|
1234
|
+
archive_string_free(&entry_name);
|
|
1235
|
+
return (ARCHIVE_FATAL);
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
/* We use GNU-tar-compatible sparse attributes. */
|
|
1240
|
+
if (sparse_count > 0) {
|
|
1241
|
+
int64_t soffset, slength;
|
|
1242
|
+
|
|
1243
|
+
add_pax_attr_int(&(pax->pax_header),
|
|
1244
|
+
"GNU.sparse.major", 1);
|
|
1245
|
+
add_pax_attr_int(&(pax->pax_header),
|
|
1246
|
+
"GNU.sparse.minor", 0);
|
|
1247
|
+
/*
|
|
1248
|
+
* Make sure to store the original path, since
|
|
1249
|
+
* truncation to ustar limit happened already.
|
|
1250
|
+
*/
|
|
1251
|
+
add_pax_attr(&(pax->pax_header),
|
|
1252
|
+
"GNU.sparse.name", path);
|
|
1253
|
+
add_pax_attr_int(&(pax->pax_header),
|
|
1254
|
+
"GNU.sparse.realsize",
|
|
1255
|
+
archive_entry_size(entry_main));
|
|
1256
|
+
|
|
1257
|
+
/* Rename the file name which will be used for
|
|
1258
|
+
* ustar header to a special name, which GNU
|
|
1259
|
+
* PAX Format 1.0 requires */
|
|
1260
|
+
archive_entry_set_pathname(entry_main,
|
|
1261
|
+
build_gnu_sparse_name(gnu_sparse_name,
|
|
1262
|
+
entry_name.s));
|
|
1263
|
+
|
|
1264
|
+
/*
|
|
1265
|
+
* - Make a sparse map, which will precede a file data.
|
|
1266
|
+
* - Get the total size of available data of sparse.
|
|
1267
|
+
*/
|
|
1268
|
+
archive_string_sprintf(&(pax->sparse_map), "%d\n",
|
|
1269
|
+
sparse_count);
|
|
1270
|
+
while (archive_entry_sparse_next(entry_main,
|
|
1271
|
+
&soffset, &slength) == ARCHIVE_OK) {
|
|
1272
|
+
archive_string_sprintf(&(pax->sparse_map),
|
|
1273
|
+
"%jd\n%jd\n",
|
|
1274
|
+
(intmax_t)soffset,
|
|
1275
|
+
(intmax_t)slength);
|
|
1276
|
+
sparse_total += slength;
|
|
1277
|
+
if (sparse_list_add(pax, soffset, slength)
|
|
1278
|
+
!= ARCHIVE_OK) {
|
|
1279
|
+
archive_set_error(&a->archive,
|
|
1280
|
+
ENOMEM,
|
|
1281
|
+
"Can't allocate memory");
|
|
1282
|
+
archive_entry_free(entry_main);
|
|
1283
|
+
archive_string_free(&entry_name);
|
|
1284
|
+
return (ARCHIVE_FATAL);
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
825
1288
|
|
|
826
1289
|
/* Store extended attributes */
|
|
827
|
-
archive_write_pax_header_xattrs(pax, entry_original)
|
|
1290
|
+
if (archive_write_pax_header_xattrs(a, pax, entry_original)
|
|
1291
|
+
== ARCHIVE_FATAL) {
|
|
1292
|
+
archive_entry_free(entry_main);
|
|
1293
|
+
archive_string_free(&entry_name);
|
|
1294
|
+
return (ARCHIVE_FATAL);
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1297
|
+
/* Store extended symlink information */
|
|
1298
|
+
if (archive_entry_symlink_type(entry_main) ==
|
|
1299
|
+
AE_SYMLINK_TYPE_FILE) {
|
|
1300
|
+
add_pax_attr(&(pax->pax_header),
|
|
1301
|
+
"LIBARCHIVE.symlinktype", "file");
|
|
1302
|
+
} else if (archive_entry_symlink_type(entry_main) ==
|
|
1303
|
+
AE_SYMLINK_TYPE_DIRECTORY) {
|
|
1304
|
+
add_pax_attr(&(pax->pax_header),
|
|
1305
|
+
"LIBARCHIVE.symlinktype", "dir");
|
|
1306
|
+
}
|
|
828
1307
|
}
|
|
829
1308
|
|
|
830
1309
|
/* Only regular files have data. */
|
|
@@ -852,6 +1331,26 @@ archive_write_pax_header(struct archive_write *a,
|
|
|
852
1331
|
if (hardlink != NULL)
|
|
853
1332
|
archive_entry_set_size(entry_main, 0);
|
|
854
1333
|
|
|
1334
|
+
/* Save a real file size. */
|
|
1335
|
+
real_size = archive_entry_size(entry_main);
|
|
1336
|
+
/*
|
|
1337
|
+
* Overwrite a file size by the total size of sparse blocks and
|
|
1338
|
+
* the size of sparse map info. That file size is the length of
|
|
1339
|
+
* the data, which we will exactly store into an archive file.
|
|
1340
|
+
*/
|
|
1341
|
+
if (archive_strlen(&(pax->sparse_map))) {
|
|
1342
|
+
size_t mapsize = archive_strlen(&(pax->sparse_map));
|
|
1343
|
+
pax->sparse_map_padding = 0x1ff & (-(ssize_t)mapsize);
|
|
1344
|
+
archive_entry_set_size(entry_main,
|
|
1345
|
+
mapsize + pax->sparse_map_padding + sparse_total);
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1348
|
+
/* If file size is too large, add 'size' to pax extended attrs. */
|
|
1349
|
+
if (archive_entry_size(entry_main) >= (((int64_t)1) << 33)) {
|
|
1350
|
+
add_pax_attr_int(&(pax->pax_header), "size",
|
|
1351
|
+
archive_entry_size(entry_main));
|
|
1352
|
+
}
|
|
1353
|
+
|
|
855
1354
|
/* Format 'ustar' header for main entry.
|
|
856
1355
|
*
|
|
857
1356
|
* The trouble with file size: If the reader can't understand
|
|
@@ -878,30 +1377,34 @@ archive_write_pax_header(struct archive_write *a,
|
|
|
878
1377
|
* The non-strict formatter uses similar logic for other
|
|
879
1378
|
* numeric fields, though they're less critical.
|
|
880
1379
|
*/
|
|
881
|
-
__archive_write_format_header_ustar(a, ustarbuff, entry_main, -1, 0
|
|
1380
|
+
if (__archive_write_format_header_ustar(a, ustarbuff, entry_main, -1, 0,
|
|
1381
|
+
NULL) == ARCHIVE_FATAL) {
|
|
1382
|
+
archive_entry_free(entry_main);
|
|
1383
|
+
archive_string_free(&entry_name);
|
|
1384
|
+
return (ARCHIVE_FATAL);
|
|
1385
|
+
}
|
|
882
1386
|
|
|
883
1387
|
/* If we built any extended attributes, write that entry first. */
|
|
884
1388
|
if (archive_strlen(&(pax->pax_header)) > 0) {
|
|
885
1389
|
struct archive_entry *pax_attr_entry;
|
|
886
1390
|
time_t s;
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
mode_t mode;
|
|
1391
|
+
int64_t uid, gid;
|
|
1392
|
+
int mode;
|
|
890
1393
|
|
|
891
|
-
pax_attr_entry =
|
|
892
|
-
p =
|
|
1394
|
+
pax_attr_entry = archive_entry_new2(&a->archive);
|
|
1395
|
+
p = entry_name.s;
|
|
893
1396
|
archive_entry_set_pathname(pax_attr_entry,
|
|
894
1397
|
build_pax_attribute_name(pax_entry_name, p));
|
|
895
1398
|
archive_entry_set_size(pax_attr_entry,
|
|
896
1399
|
archive_strlen(&(pax->pax_header)));
|
|
897
1400
|
/* Copy uid/gid (but clip to ustar limits). */
|
|
898
1401
|
uid = archive_entry_uid(entry_main);
|
|
899
|
-
if (
|
|
900
|
-
uid = (
|
|
1402
|
+
if (uid >= 1 << 18)
|
|
1403
|
+
uid = (1 << 18) - 1;
|
|
901
1404
|
archive_entry_set_uid(pax_attr_entry, uid);
|
|
902
1405
|
gid = archive_entry_gid(entry_main);
|
|
903
|
-
if (
|
|
904
|
-
gid = (
|
|
1406
|
+
if (gid >= 1 << 18)
|
|
1407
|
+
gid = (1 << 18) - 1;
|
|
905
1408
|
archive_entry_set_gid(pax_attr_entry, gid);
|
|
906
1409
|
/* Copy mode over (but not setuid/setgid bits) */
|
|
907
1410
|
mode = archive_entry_mode(entry_main);
|
|
@@ -935,57 +1438,76 @@ archive_write_pax_header(struct archive_write *a,
|
|
|
935
1438
|
archive_entry_set_ctime(pax_attr_entry, 0, 0);
|
|
936
1439
|
|
|
937
1440
|
r = __archive_write_format_header_ustar(a, paxbuff,
|
|
938
|
-
pax_attr_entry, 'x', 1);
|
|
1441
|
+
pax_attr_entry, 'x', 1, NULL);
|
|
939
1442
|
|
|
940
1443
|
archive_entry_free(pax_attr_entry);
|
|
941
1444
|
|
|
942
1445
|
/* Note that the 'x' header shouldn't ever fail to format */
|
|
943
|
-
if (r
|
|
944
|
-
|
|
945
|
-
"
|
|
946
|
-
|
|
947
|
-
(
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
1446
|
+
if (r < ARCHIVE_WARN) {
|
|
1447
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
1448
|
+
"archive_write_pax_header: "
|
|
1449
|
+
"'x' header failed?! This can't happen.\n");
|
|
1450
|
+
archive_entry_free(entry_main);
|
|
1451
|
+
archive_string_free(&entry_name);
|
|
1452
|
+
return (ARCHIVE_FATAL);
|
|
1453
|
+
} else if (r < ret)
|
|
1454
|
+
ret = r;
|
|
1455
|
+
r = __archive_write_output(a, paxbuff, 512);
|
|
951
1456
|
if (r != ARCHIVE_OK) {
|
|
1457
|
+
sparse_list_clear(pax);
|
|
952
1458
|
pax->entry_bytes_remaining = 0;
|
|
953
1459
|
pax->entry_padding = 0;
|
|
1460
|
+
archive_entry_free(entry_main);
|
|
1461
|
+
archive_string_free(&entry_name);
|
|
954
1462
|
return (ARCHIVE_FATAL);
|
|
955
1463
|
}
|
|
956
1464
|
|
|
957
1465
|
pax->entry_bytes_remaining = archive_strlen(&(pax->pax_header));
|
|
958
|
-
pax->entry_padding =
|
|
1466
|
+
pax->entry_padding =
|
|
1467
|
+
0x1ff & (-(int64_t)pax->entry_bytes_remaining);
|
|
959
1468
|
|
|
960
|
-
r = (a
|
|
1469
|
+
r = __archive_write_output(a, pax->pax_header.s,
|
|
961
1470
|
archive_strlen(&(pax->pax_header)));
|
|
962
1471
|
if (r != ARCHIVE_OK) {
|
|
963
1472
|
/* If a write fails, we're pretty much toast. */
|
|
1473
|
+
archive_entry_free(entry_main);
|
|
1474
|
+
archive_string_free(&entry_name);
|
|
964
1475
|
return (ARCHIVE_FATAL);
|
|
965
1476
|
}
|
|
966
1477
|
/* Pad out the end of the entry. */
|
|
967
|
-
r =
|
|
1478
|
+
r = __archive_write_nulls(a, (size_t)pax->entry_padding);
|
|
968
1479
|
if (r != ARCHIVE_OK) {
|
|
969
1480
|
/* If a write fails, we're pretty much toast. */
|
|
1481
|
+
archive_entry_free(entry_main);
|
|
1482
|
+
archive_string_free(&entry_name);
|
|
970
1483
|
return (ARCHIVE_FATAL);
|
|
971
1484
|
}
|
|
972
1485
|
pax->entry_bytes_remaining = pax->entry_padding = 0;
|
|
973
1486
|
}
|
|
974
1487
|
|
|
975
1488
|
/* Write the header for main entry. */
|
|
976
|
-
r = (a
|
|
977
|
-
if (r != ARCHIVE_OK)
|
|
1489
|
+
r = __archive_write_output(a, ustarbuff, 512);
|
|
1490
|
+
if (r != ARCHIVE_OK) {
|
|
1491
|
+
archive_entry_free(entry_main);
|
|
1492
|
+
archive_string_free(&entry_name);
|
|
978
1493
|
return (r);
|
|
1494
|
+
}
|
|
979
1495
|
|
|
980
1496
|
/*
|
|
981
1497
|
* Inform the client of the on-disk size we're using, so
|
|
982
1498
|
* they can avoid unnecessarily writing a body for something
|
|
983
1499
|
* that we're just going to ignore.
|
|
984
1500
|
*/
|
|
985
|
-
archive_entry_set_size(entry_original,
|
|
986
|
-
pax->
|
|
987
|
-
|
|
1501
|
+
archive_entry_set_size(entry_original, real_size);
|
|
1502
|
+
if (pax->sparse_list == NULL && real_size > 0) {
|
|
1503
|
+
/* This is not a sparse file but we handle its data as
|
|
1504
|
+
* a sparse block. */
|
|
1505
|
+
sparse_list_add(pax, 0, real_size);
|
|
1506
|
+
sparse_total = real_size;
|
|
1507
|
+
}
|
|
1508
|
+
pax->entry_padding = 0x1ff & (-(int64_t)sparse_total);
|
|
988
1509
|
archive_entry_free(entry_main);
|
|
1510
|
+
archive_string_free(&entry_name);
|
|
989
1511
|
|
|
990
1512
|
return (ret);
|
|
991
1513
|
}
|
|
@@ -1136,7 +1658,7 @@ build_ustar_entry_name(char *dest, const char *src, size_t src_length,
|
|
|
1136
1658
|
*
|
|
1137
1659
|
* Joerg Schilling has argued that this is unnecessary because, in
|
|
1138
1660
|
* practice, if the pax extended attributes get extracted as regular
|
|
1139
|
-
* files,
|
|
1661
|
+
* files, no one is going to bother reading those attributes to
|
|
1140
1662
|
* manually restore them. Based on this, 'star' uses
|
|
1141
1663
|
* /tmp/PaxHeader/'basename' as the ustar header name. This is a
|
|
1142
1664
|
* tempting argument, in part because it's simpler than the SUSv3
|
|
@@ -1195,32 +1717,71 @@ build_pax_attribute_name(char *dest, const char *src)
|
|
|
1195
1717
|
* to having clients override it.
|
|
1196
1718
|
*/
|
|
1197
1719
|
#if HAVE_GETPID && 0 /* Disable this for now; see above comment. */
|
|
1198
|
-
|
|
1720
|
+
snprintf(buff, sizeof(buff), "PaxHeader.%d", getpid());
|
|
1199
1721
|
#else
|
|
1200
1722
|
/* If the platform can't fetch the pid, don't include it. */
|
|
1201
1723
|
strcpy(buff, "PaxHeader");
|
|
1202
1724
|
#endif
|
|
1203
|
-
/* General case: build a ustar-compatible name adding
|
|
1725
|
+
/* General case: build a ustar-compatible name adding
|
|
1726
|
+
* "/PaxHeader/". */
|
|
1204
1727
|
build_ustar_entry_name(dest, src, p - src, buff);
|
|
1205
1728
|
|
|
1206
1729
|
return (dest);
|
|
1207
1730
|
}
|
|
1208
1731
|
|
|
1209
|
-
/*
|
|
1210
|
-
|
|
1211
|
-
|
|
1732
|
+
/*
|
|
1733
|
+
* GNU PAX Format 1.0 requires the special name, which pattern is:
|
|
1734
|
+
* <dir>/GNUSparseFile.<pid>/<original file name>
|
|
1735
|
+
*
|
|
1736
|
+
* Since reproducible archives are more important, use 0 as pid.
|
|
1737
|
+
*
|
|
1738
|
+
* This function is used for only Sparse file, a file type of which
|
|
1739
|
+
* is regular file.
|
|
1740
|
+
*/
|
|
1741
|
+
static char *
|
|
1742
|
+
build_gnu_sparse_name(char *dest, const char *src)
|
|
1212
1743
|
{
|
|
1213
|
-
|
|
1744
|
+
const char *p;
|
|
1214
1745
|
|
|
1215
|
-
|
|
1216
|
-
|
|
1746
|
+
/* Handle the null filename case. */
|
|
1747
|
+
if (src == NULL || *src == '\0') {
|
|
1748
|
+
strcpy(dest, "GNUSparseFile/blank");
|
|
1749
|
+
return (dest);
|
|
1750
|
+
}
|
|
1217
1751
|
|
|
1218
|
-
|
|
1219
|
-
|
|
1752
|
+
/* Prune final '/' and other unwanted final elements. */
|
|
1753
|
+
p = src + strlen(src);
|
|
1754
|
+
for (;;) {
|
|
1755
|
+
/* Ends in "/", remove the '/' */
|
|
1756
|
+
if (p > src && p[-1] == '/') {
|
|
1757
|
+
--p;
|
|
1758
|
+
continue;
|
|
1759
|
+
}
|
|
1760
|
+
/* Ends in "/.", remove the '.' */
|
|
1761
|
+
if (p > src + 1 && p[-1] == '.'
|
|
1762
|
+
&& p[-2] == '/') {
|
|
1763
|
+
--p;
|
|
1764
|
+
continue;
|
|
1765
|
+
}
|
|
1766
|
+
break;
|
|
1767
|
+
}
|
|
1768
|
+
|
|
1769
|
+
/* General case: build a ustar-compatible name adding
|
|
1770
|
+
* "/GNUSparseFile/". */
|
|
1771
|
+
build_ustar_entry_name(dest, src, p - src, "GNUSparseFile.0");
|
|
1772
|
+
|
|
1773
|
+
return (dest);
|
|
1220
1774
|
}
|
|
1221
1775
|
|
|
1776
|
+
/* Write two null blocks for the end of archive */
|
|
1222
1777
|
static int
|
|
1223
|
-
|
|
1778
|
+
archive_write_pax_close(struct archive_write *a)
|
|
1779
|
+
{
|
|
1780
|
+
return (__archive_write_nulls(a, 512 * 2));
|
|
1781
|
+
}
|
|
1782
|
+
|
|
1783
|
+
static int
|
|
1784
|
+
archive_write_pax_free(struct archive_write *a)
|
|
1224
1785
|
{
|
|
1225
1786
|
struct pax *pax;
|
|
1226
1787
|
|
|
@@ -1229,6 +1790,9 @@ archive_write_pax_destroy(struct archive_write *a)
|
|
|
1229
1790
|
return (ARCHIVE_OK);
|
|
1230
1791
|
|
|
1231
1792
|
archive_string_free(&pax->pax_header);
|
|
1793
|
+
archive_string_free(&pax->sparse_map);
|
|
1794
|
+
archive_string_free(&pax->l_url_encoded_name);
|
|
1795
|
+
sparse_list_clear(pax);
|
|
1232
1796
|
free(pax);
|
|
1233
1797
|
a->format_data = NULL;
|
|
1234
1798
|
return (ARCHIVE_OK);
|
|
@@ -1238,56 +1802,97 @@ static int
|
|
|
1238
1802
|
archive_write_pax_finish_entry(struct archive_write *a)
|
|
1239
1803
|
{
|
|
1240
1804
|
struct pax *pax;
|
|
1805
|
+
uint64_t remaining;
|
|
1241
1806
|
int ret;
|
|
1242
1807
|
|
|
1243
1808
|
pax = (struct pax *)a->format_data;
|
|
1244
|
-
|
|
1809
|
+
remaining = pax->entry_bytes_remaining;
|
|
1810
|
+
if (remaining == 0) {
|
|
1811
|
+
while (pax->sparse_list) {
|
|
1812
|
+
struct sparse_block *sb;
|
|
1813
|
+
if (!pax->sparse_list->is_hole)
|
|
1814
|
+
remaining += pax->sparse_list->remaining;
|
|
1815
|
+
sb = pax->sparse_list->next;
|
|
1816
|
+
free(pax->sparse_list);
|
|
1817
|
+
pax->sparse_list = sb;
|
|
1818
|
+
}
|
|
1819
|
+
}
|
|
1820
|
+
ret = __archive_write_nulls(a, (size_t)(remaining + pax->entry_padding));
|
|
1245
1821
|
pax->entry_bytes_remaining = pax->entry_padding = 0;
|
|
1246
1822
|
return (ret);
|
|
1247
1823
|
}
|
|
1248
1824
|
|
|
1249
|
-
static
|
|
1250
|
-
|
|
1825
|
+
static ssize_t
|
|
1826
|
+
archive_write_pax_data(struct archive_write *a, const void *buff, size_t s)
|
|
1251
1827
|
{
|
|
1828
|
+
struct pax *pax;
|
|
1829
|
+
size_t ws;
|
|
1830
|
+
size_t total;
|
|
1252
1831
|
int ret;
|
|
1253
|
-
size_t to_write;
|
|
1254
1832
|
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1833
|
+
pax = (struct pax *)a->format_data;
|
|
1834
|
+
|
|
1835
|
+
/*
|
|
1836
|
+
* According to GNU PAX format 1.0, write a sparse map
|
|
1837
|
+
* before the body.
|
|
1838
|
+
*/
|
|
1839
|
+
if (archive_strlen(&(pax->sparse_map))) {
|
|
1840
|
+
ret = __archive_write_output(a, pax->sparse_map.s,
|
|
1841
|
+
archive_strlen(&(pax->sparse_map)));
|
|
1258
1842
|
if (ret != ARCHIVE_OK)
|
|
1259
1843
|
return (ret);
|
|
1260
|
-
|
|
1844
|
+
ret = __archive_write_nulls(a, pax->sparse_map_padding);
|
|
1845
|
+
if (ret != ARCHIVE_OK)
|
|
1846
|
+
return (ret);
|
|
1847
|
+
archive_string_empty(&(pax->sparse_map));
|
|
1261
1848
|
}
|
|
1262
|
-
return (ARCHIVE_OK);
|
|
1263
|
-
}
|
|
1264
1849
|
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
struct pax *pax;
|
|
1269
|
-
int ret;
|
|
1850
|
+
total = 0;
|
|
1851
|
+
while (total < s) {
|
|
1852
|
+
const unsigned char *p;
|
|
1270
1853
|
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1854
|
+
while (pax->sparse_list != NULL &&
|
|
1855
|
+
pax->sparse_list->remaining == 0) {
|
|
1856
|
+
struct sparse_block *sb = pax->sparse_list->next;
|
|
1857
|
+
free(pax->sparse_list);
|
|
1858
|
+
pax->sparse_list = sb;
|
|
1859
|
+
}
|
|
1274
1860
|
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1861
|
+
if (pax->sparse_list == NULL)
|
|
1862
|
+
return (total);
|
|
1863
|
+
|
|
1864
|
+
p = ((const unsigned char *)buff) + total;
|
|
1865
|
+
ws = s - total;
|
|
1866
|
+
if (ws > pax->sparse_list->remaining)
|
|
1867
|
+
ws = (size_t)pax->sparse_list->remaining;
|
|
1868
|
+
|
|
1869
|
+
if (pax->sparse_list->is_hole) {
|
|
1870
|
+
/* Current block is hole thus we do not write
|
|
1871
|
+
* the body. */
|
|
1872
|
+
pax->sparse_list->remaining -= ws;
|
|
1873
|
+
total += ws;
|
|
1874
|
+
continue;
|
|
1875
|
+
}
|
|
1876
|
+
|
|
1877
|
+
ret = __archive_write_output(a, p, ws);
|
|
1878
|
+
pax->sparse_list->remaining -= ws;
|
|
1879
|
+
total += ws;
|
|
1880
|
+
if (ret != ARCHIVE_OK)
|
|
1881
|
+
return (ret);
|
|
1882
|
+
}
|
|
1883
|
+
return (total);
|
|
1281
1884
|
}
|
|
1282
1885
|
|
|
1283
1886
|
static int
|
|
1284
|
-
has_non_ASCII(const
|
|
1887
|
+
has_non_ASCII(const char *_p)
|
|
1285
1888
|
{
|
|
1286
|
-
|
|
1889
|
+
const unsigned char *p = (const unsigned char *)_p;
|
|
1890
|
+
|
|
1891
|
+
if (p == NULL)
|
|
1287
1892
|
return (1);
|
|
1288
|
-
while (*
|
|
1289
|
-
|
|
1290
|
-
return (*
|
|
1893
|
+
while (*p != '\0' && *p < 128)
|
|
1894
|
+
p++;
|
|
1895
|
+
return (*p != '\0');
|
|
1291
1896
|
}
|
|
1292
1897
|
|
|
1293
1898
|
/*
|
|
@@ -1384,3 +1989,60 @@ base64_encode(const char *s, size_t len)
|
|
|
1384
1989
|
*d = '\0';
|
|
1385
1990
|
return (out);
|
|
1386
1991
|
}
|
|
1992
|
+
|
|
1993
|
+
static void
|
|
1994
|
+
sparse_list_clear(struct pax *pax)
|
|
1995
|
+
{
|
|
1996
|
+
while (pax->sparse_list != NULL) {
|
|
1997
|
+
struct sparse_block *sb = pax->sparse_list;
|
|
1998
|
+
pax->sparse_list = sb->next;
|
|
1999
|
+
free(sb);
|
|
2000
|
+
}
|
|
2001
|
+
pax->sparse_tail = NULL;
|
|
2002
|
+
}
|
|
2003
|
+
|
|
2004
|
+
static int
|
|
2005
|
+
_sparse_list_add_block(struct pax *pax, int64_t offset, int64_t length,
|
|
2006
|
+
int is_hole)
|
|
2007
|
+
{
|
|
2008
|
+
struct sparse_block *sb;
|
|
2009
|
+
|
|
2010
|
+
sb = (struct sparse_block *)malloc(sizeof(*sb));
|
|
2011
|
+
if (sb == NULL)
|
|
2012
|
+
return (ARCHIVE_FATAL);
|
|
2013
|
+
sb->next = NULL;
|
|
2014
|
+
sb->is_hole = is_hole;
|
|
2015
|
+
sb->offset = offset;
|
|
2016
|
+
sb->remaining = length;
|
|
2017
|
+
if (pax->sparse_list == NULL || pax->sparse_tail == NULL)
|
|
2018
|
+
pax->sparse_list = pax->sparse_tail = sb;
|
|
2019
|
+
else {
|
|
2020
|
+
pax->sparse_tail->next = sb;
|
|
2021
|
+
pax->sparse_tail = sb;
|
|
2022
|
+
}
|
|
2023
|
+
return (ARCHIVE_OK);
|
|
2024
|
+
}
|
|
2025
|
+
|
|
2026
|
+
static int
|
|
2027
|
+
sparse_list_add(struct pax *pax, int64_t offset, int64_t length)
|
|
2028
|
+
{
|
|
2029
|
+
int64_t last_offset;
|
|
2030
|
+
int r;
|
|
2031
|
+
|
|
2032
|
+
if (pax->sparse_tail == NULL)
|
|
2033
|
+
last_offset = 0;
|
|
2034
|
+
else {
|
|
2035
|
+
last_offset = pax->sparse_tail->offset +
|
|
2036
|
+
pax->sparse_tail->remaining;
|
|
2037
|
+
}
|
|
2038
|
+
if (last_offset < offset) {
|
|
2039
|
+
/* Add a hole block. */
|
|
2040
|
+
r = _sparse_list_add_block(pax, last_offset,
|
|
2041
|
+
offset - last_offset, 1);
|
|
2042
|
+
if (r != ARCHIVE_OK)
|
|
2043
|
+
return (r);
|
|
2044
|
+
}
|
|
2045
|
+
/* Add data block. */
|
|
2046
|
+
return (_sparse_list_add_block(pax, offset, length, 0));
|
|
2047
|
+
}
|
|
2048
|
+
|