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
|
@@ -0,0 +1,2217 @@
|
|
|
1
|
+
/*-
|
|
2
|
+
* Copyright (c) 2008 Joerg Sonnenberger
|
|
3
|
+
* Copyright (c) 2009-2012 Michihiro NAKAJIMA
|
|
4
|
+
* All rights reserved.
|
|
5
|
+
*
|
|
6
|
+
* Redistribution and use in source and binary forms, with or without
|
|
7
|
+
* modification, are permitted provided that the following conditions
|
|
8
|
+
* are met:
|
|
9
|
+
* 1. Redistributions of source code must retain the above copyright
|
|
10
|
+
* notice, this list of conditions and the following disclaimer.
|
|
11
|
+
* 2. Redistributions in binary form must reproduce the above copyright
|
|
12
|
+
* notice, this list of conditions and the following disclaimer in the
|
|
13
|
+
* documentation and/or other materials provided with the distribution.
|
|
14
|
+
*
|
|
15
|
+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
|
16
|
+
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
17
|
+
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
18
|
+
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
19
|
+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
20
|
+
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
21
|
+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
22
|
+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
23
|
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
24
|
+
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
#include "archive_platform.h"
|
|
28
|
+
__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_mtree.c 201171 2009-12-29 06:39:07Z kientzle $");
|
|
29
|
+
|
|
30
|
+
#ifdef HAVE_SYS_TYPES_H
|
|
31
|
+
#include <sys/types.h>
|
|
32
|
+
#endif
|
|
33
|
+
#include <errno.h>
|
|
34
|
+
#include <stdlib.h>
|
|
35
|
+
#include <string.h>
|
|
36
|
+
|
|
37
|
+
#include "archive.h"
|
|
38
|
+
#include "archive_digest_private.h"
|
|
39
|
+
#include "archive_entry.h"
|
|
40
|
+
#include "archive_entry_private.h"
|
|
41
|
+
#include "archive_private.h"
|
|
42
|
+
#include "archive_rb.h"
|
|
43
|
+
#include "archive_string.h"
|
|
44
|
+
#include "archive_write_private.h"
|
|
45
|
+
|
|
46
|
+
#define INDENTNAMELEN 15
|
|
47
|
+
#define MAXLINELEN 80
|
|
48
|
+
#define SET_KEYS \
|
|
49
|
+
(F_FLAGS | F_GID | F_GNAME | F_MODE | F_TYPE | F_UID | F_UNAME)
|
|
50
|
+
|
|
51
|
+
struct attr_counter {
|
|
52
|
+
struct attr_counter *prev;
|
|
53
|
+
struct attr_counter *next;
|
|
54
|
+
struct mtree_entry *m_entry;
|
|
55
|
+
int count;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
struct att_counter_set {
|
|
59
|
+
struct attr_counter *uid_list;
|
|
60
|
+
struct attr_counter *gid_list;
|
|
61
|
+
struct attr_counter *mode_list;
|
|
62
|
+
struct attr_counter *flags_list;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
struct mtree_chain {
|
|
66
|
+
struct mtree_entry *first;
|
|
67
|
+
struct mtree_entry **last;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/*
|
|
71
|
+
* The Data only for a directory file.
|
|
72
|
+
*/
|
|
73
|
+
struct dir_info {
|
|
74
|
+
struct archive_rb_tree rbtree;
|
|
75
|
+
struct mtree_chain children;
|
|
76
|
+
struct mtree_entry *chnext;
|
|
77
|
+
int virtual;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/*
|
|
81
|
+
* The Data only for a regular file.
|
|
82
|
+
*/
|
|
83
|
+
struct reg_info {
|
|
84
|
+
int compute_sum;
|
|
85
|
+
uint32_t crc;
|
|
86
|
+
struct ae_digest digest;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
struct mtree_entry {
|
|
90
|
+
struct archive_rb_node rbnode;
|
|
91
|
+
struct mtree_entry *next;
|
|
92
|
+
struct mtree_entry *parent;
|
|
93
|
+
struct dir_info *dir_info;
|
|
94
|
+
struct reg_info *reg_info;
|
|
95
|
+
|
|
96
|
+
struct archive_string parentdir;
|
|
97
|
+
struct archive_string basename;
|
|
98
|
+
struct archive_string pathname;
|
|
99
|
+
struct archive_string symlink;
|
|
100
|
+
struct archive_string uname;
|
|
101
|
+
struct archive_string gname;
|
|
102
|
+
struct archive_string fflags_text;
|
|
103
|
+
unsigned int nlink;
|
|
104
|
+
mode_t filetype;
|
|
105
|
+
mode_t mode;
|
|
106
|
+
int64_t size;
|
|
107
|
+
int64_t uid;
|
|
108
|
+
int64_t gid;
|
|
109
|
+
time_t mtime;
|
|
110
|
+
long mtime_nsec;
|
|
111
|
+
unsigned long fflags_set;
|
|
112
|
+
unsigned long fflags_clear;
|
|
113
|
+
dev_t rdevmajor;
|
|
114
|
+
dev_t rdevminor;
|
|
115
|
+
dev_t devmajor;
|
|
116
|
+
dev_t devminor;
|
|
117
|
+
int64_t ino;
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
struct mtree_writer {
|
|
121
|
+
struct mtree_entry *mtree_entry;
|
|
122
|
+
struct mtree_entry *root;
|
|
123
|
+
struct mtree_entry *cur_dirent;
|
|
124
|
+
struct archive_string cur_dirstr;
|
|
125
|
+
struct mtree_chain file_list;
|
|
126
|
+
|
|
127
|
+
struct archive_string ebuf;
|
|
128
|
+
struct archive_string buf;
|
|
129
|
+
int first;
|
|
130
|
+
uint64_t entry_bytes_remaining;
|
|
131
|
+
|
|
132
|
+
/*
|
|
133
|
+
* Set global value.
|
|
134
|
+
*/
|
|
135
|
+
struct {
|
|
136
|
+
int processing;
|
|
137
|
+
mode_t type;
|
|
138
|
+
int keys;
|
|
139
|
+
int64_t uid;
|
|
140
|
+
int64_t gid;
|
|
141
|
+
mode_t mode;
|
|
142
|
+
unsigned long fflags_set;
|
|
143
|
+
unsigned long fflags_clear;
|
|
144
|
+
} set;
|
|
145
|
+
struct att_counter_set acs;
|
|
146
|
+
int classic;
|
|
147
|
+
int depth;
|
|
148
|
+
|
|
149
|
+
/* check sum */
|
|
150
|
+
int compute_sum;
|
|
151
|
+
uint32_t crc;
|
|
152
|
+
uint64_t crc_len;
|
|
153
|
+
#ifdef ARCHIVE_HAS_MD5
|
|
154
|
+
archive_md5_ctx md5ctx;
|
|
155
|
+
#endif
|
|
156
|
+
#ifdef ARCHIVE_HAS_RMD160
|
|
157
|
+
archive_rmd160_ctx rmd160ctx;
|
|
158
|
+
#endif
|
|
159
|
+
#ifdef ARCHIVE_HAS_SHA1
|
|
160
|
+
archive_sha1_ctx sha1ctx;
|
|
161
|
+
#endif
|
|
162
|
+
#ifdef ARCHIVE_HAS_SHA256
|
|
163
|
+
archive_sha256_ctx sha256ctx;
|
|
164
|
+
#endif
|
|
165
|
+
#ifdef ARCHIVE_HAS_SHA384
|
|
166
|
+
archive_sha384_ctx sha384ctx;
|
|
167
|
+
#endif
|
|
168
|
+
#ifdef ARCHIVE_HAS_SHA512
|
|
169
|
+
archive_sha512_ctx sha512ctx;
|
|
170
|
+
#endif
|
|
171
|
+
/* Keyword options */
|
|
172
|
+
int keys;
|
|
173
|
+
#define F_CKSUM 0x00000001 /* checksum */
|
|
174
|
+
#define F_DEV 0x00000002 /* device type */
|
|
175
|
+
#define F_DONE 0x00000004 /* directory done */
|
|
176
|
+
#define F_FLAGS 0x00000008 /* file flags */
|
|
177
|
+
#define F_GID 0x00000010 /* gid */
|
|
178
|
+
#define F_GNAME 0x00000020 /* group name */
|
|
179
|
+
#define F_IGN 0x00000040 /* ignore */
|
|
180
|
+
#define F_MAGIC 0x00000080 /* name has magic chars */
|
|
181
|
+
#define F_MD5 0x00000100 /* MD5 digest */
|
|
182
|
+
#define F_MODE 0x00000200 /* mode */
|
|
183
|
+
#define F_NLINK 0x00000400 /* number of links */
|
|
184
|
+
#define F_NOCHANGE 0x00000800 /* If owner/mode "wrong", do
|
|
185
|
+
* not change */
|
|
186
|
+
#define F_OPT 0x00001000 /* existence optional */
|
|
187
|
+
#define F_RMD160 0x00002000 /* RIPEMD160 digest */
|
|
188
|
+
#define F_SHA1 0x00004000 /* SHA-1 digest */
|
|
189
|
+
#define F_SIZE 0x00008000 /* size */
|
|
190
|
+
#define F_SLINK 0x00010000 /* symbolic link */
|
|
191
|
+
#define F_TAGS 0x00020000 /* tags */
|
|
192
|
+
#define F_TIME 0x00040000 /* modification time */
|
|
193
|
+
#define F_TYPE 0x00080000 /* file type */
|
|
194
|
+
#define F_UID 0x00100000 /* uid */
|
|
195
|
+
#define F_UNAME 0x00200000 /* user name */
|
|
196
|
+
#define F_VISIT 0x00400000 /* file visited */
|
|
197
|
+
#define F_SHA256 0x00800000 /* SHA-256 digest */
|
|
198
|
+
#define F_SHA384 0x01000000 /* SHA-384 digest */
|
|
199
|
+
#define F_SHA512 0x02000000 /* SHA-512 digest */
|
|
200
|
+
#define F_INO 0x04000000 /* inode number */
|
|
201
|
+
#define F_RESDEV 0x08000000 /* device ID on which the
|
|
202
|
+
* entry resides */
|
|
203
|
+
|
|
204
|
+
/* Options */
|
|
205
|
+
int dironly; /* If it is set, ignore all files except
|
|
206
|
+
* directory files, like mtree(8) -d option. */
|
|
207
|
+
int indent; /* If it is set, indent output data. */
|
|
208
|
+
int output_global_set; /* If it is set, use /set keyword to set
|
|
209
|
+
* global values. When generating mtree
|
|
210
|
+
* classic format, it is set by default. */
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
#define DEFAULT_KEYS (F_DEV | F_FLAGS | F_GID | F_GNAME | F_SLINK | F_MODE\
|
|
214
|
+
| F_NLINK | F_SIZE | F_TIME | F_TYPE | F_UID\
|
|
215
|
+
| F_UNAME)
|
|
216
|
+
#define attr_counter_set_reset attr_counter_set_free
|
|
217
|
+
|
|
218
|
+
static void attr_counter_free(struct attr_counter **);
|
|
219
|
+
static int attr_counter_inc(struct attr_counter **, struct attr_counter *,
|
|
220
|
+
struct attr_counter *, struct mtree_entry *);
|
|
221
|
+
static struct attr_counter * attr_counter_new(struct mtree_entry *,
|
|
222
|
+
struct attr_counter *);
|
|
223
|
+
static int attr_counter_set_collect(struct mtree_writer *,
|
|
224
|
+
struct mtree_entry *);
|
|
225
|
+
static void attr_counter_set_free(struct mtree_writer *);
|
|
226
|
+
static int get_global_set_keys(struct mtree_writer *, struct mtree_entry *);
|
|
227
|
+
static int mtree_entry_add_child_tail(struct mtree_entry *,
|
|
228
|
+
struct mtree_entry *);
|
|
229
|
+
static int mtree_entry_create_virtual_dir(struct archive_write *, const char *,
|
|
230
|
+
struct mtree_entry **);
|
|
231
|
+
static int mtree_entry_cmp_node(const struct archive_rb_node *,
|
|
232
|
+
const struct archive_rb_node *);
|
|
233
|
+
static int mtree_entry_cmp_key(const struct archive_rb_node *, const void *);
|
|
234
|
+
static int mtree_entry_exchange_same_entry(struct archive_write *,
|
|
235
|
+
struct mtree_entry *, struct mtree_entry *);
|
|
236
|
+
static void mtree_entry_free(struct mtree_entry *);
|
|
237
|
+
static int mtree_entry_new(struct archive_write *, struct archive_entry *,
|
|
238
|
+
struct mtree_entry **);
|
|
239
|
+
static void mtree_entry_register_free(struct mtree_writer *);
|
|
240
|
+
static void mtree_entry_register_init(struct mtree_writer *);
|
|
241
|
+
static int mtree_entry_setup_filenames(struct archive_write *,
|
|
242
|
+
struct mtree_entry *, struct archive_entry *);
|
|
243
|
+
static int mtree_entry_tree_add(struct archive_write *, struct mtree_entry **);
|
|
244
|
+
static void sum_init(struct mtree_writer *);
|
|
245
|
+
static void sum_update(struct mtree_writer *, const void *, size_t);
|
|
246
|
+
static void sum_final(struct mtree_writer *, struct reg_info *);
|
|
247
|
+
static void sum_write(struct archive_string *, struct reg_info *);
|
|
248
|
+
static int write_mtree_entry(struct archive_write *, struct mtree_entry *);
|
|
249
|
+
static int write_dot_dot_entry(struct archive_write *, struct mtree_entry *);
|
|
250
|
+
|
|
251
|
+
#define COMPUTE_CRC(var, ch) (var) = (var) << 8 ^ crctab[(var) >> 24 ^ (ch)]
|
|
252
|
+
static const uint32_t crctab[] = {
|
|
253
|
+
0x0,
|
|
254
|
+
0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
|
|
255
|
+
0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6,
|
|
256
|
+
0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
|
|
257
|
+
0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac,
|
|
258
|
+
0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f,
|
|
259
|
+
0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a,
|
|
260
|
+
0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
|
|
261
|
+
0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58,
|
|
262
|
+
0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033,
|
|
263
|
+
0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe,
|
|
264
|
+
0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
|
|
265
|
+
0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4,
|
|
266
|
+
0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
|
|
267
|
+
0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5,
|
|
268
|
+
0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
|
|
269
|
+
0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07,
|
|
270
|
+
0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c,
|
|
271
|
+
0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1,
|
|
272
|
+
0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
|
|
273
|
+
0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b,
|
|
274
|
+
0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698,
|
|
275
|
+
0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d,
|
|
276
|
+
0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
|
|
277
|
+
0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f,
|
|
278
|
+
0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
|
|
279
|
+
0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80,
|
|
280
|
+
0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
|
|
281
|
+
0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a,
|
|
282
|
+
0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629,
|
|
283
|
+
0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c,
|
|
284
|
+
0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
|
|
285
|
+
0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e,
|
|
286
|
+
0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65,
|
|
287
|
+
0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8,
|
|
288
|
+
0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
|
|
289
|
+
0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2,
|
|
290
|
+
0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
|
|
291
|
+
0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74,
|
|
292
|
+
0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
|
|
293
|
+
0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21,
|
|
294
|
+
0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a,
|
|
295
|
+
0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087,
|
|
296
|
+
0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
|
|
297
|
+
0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d,
|
|
298
|
+
0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce,
|
|
299
|
+
0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb,
|
|
300
|
+
0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
|
|
301
|
+
0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09,
|
|
302
|
+
0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
|
|
303
|
+
0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf,
|
|
304
|
+
0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
static const unsigned char safe_char[256] = {
|
|
308
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 00 - 0F */
|
|
309
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 1F */
|
|
310
|
+
/* !"$%&'()*+,-./ EXCLUSION:0x20( ) 0x23(#) */
|
|
311
|
+
0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 - 2F */
|
|
312
|
+
/* 0123456789:;<>? EXCLUSION:0x3d(=) */
|
|
313
|
+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, /* 30 - 3F */
|
|
314
|
+
/* @ABCDEFGHIJKLMNO */
|
|
315
|
+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 - 4F */
|
|
316
|
+
/* PQRSTUVWXYZ[]^_ EXCLUSION:0x5c(\) */
|
|
317
|
+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, /* 50 - 5F */
|
|
318
|
+
/* `abcdefghijklmno */
|
|
319
|
+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60 - 6F */
|
|
320
|
+
/* pqrstuvwxyz{|}~ */
|
|
321
|
+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* 70 - 7F */
|
|
322
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 8F */
|
|
323
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 - 9F */
|
|
324
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A0 - AF */
|
|
325
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0 - BF */
|
|
326
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* C0 - CF */
|
|
327
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* D0 - DF */
|
|
328
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* E0 - EF */
|
|
329
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F0 - FF */
|
|
330
|
+
};
|
|
331
|
+
|
|
332
|
+
static void
|
|
333
|
+
mtree_quote(struct archive_string *s, const char *str)
|
|
334
|
+
{
|
|
335
|
+
const char *start;
|
|
336
|
+
char buf[4];
|
|
337
|
+
unsigned char c;
|
|
338
|
+
|
|
339
|
+
for (start = str; *str != '\0'; ++str) {
|
|
340
|
+
if (safe_char[*(const unsigned char *)str])
|
|
341
|
+
continue;
|
|
342
|
+
if (start != str)
|
|
343
|
+
archive_strncat(s, start, str - start);
|
|
344
|
+
c = (unsigned char)*str;
|
|
345
|
+
buf[0] = '\\';
|
|
346
|
+
buf[1] = (c / 64) + '0';
|
|
347
|
+
buf[2] = (c / 8 % 8) + '0';
|
|
348
|
+
buf[3] = (c % 8) + '0';
|
|
349
|
+
archive_strncat(s, buf, 4);
|
|
350
|
+
start = str + 1;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
if (start != str)
|
|
354
|
+
archive_strncat(s, start, str - start);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/*
|
|
358
|
+
* Indent a line as the mtree utility does so it is readable for people.
|
|
359
|
+
*/
|
|
360
|
+
static void
|
|
361
|
+
mtree_indent(struct mtree_writer *mtree)
|
|
362
|
+
{
|
|
363
|
+
int i, fn, nd, pd;
|
|
364
|
+
const char *r, *s, *x;
|
|
365
|
+
|
|
366
|
+
if (mtree->classic) {
|
|
367
|
+
if (mtree->indent) {
|
|
368
|
+
nd = 0;
|
|
369
|
+
pd = mtree->depth * 4;
|
|
370
|
+
} else {
|
|
371
|
+
nd = mtree->depth?4:0;
|
|
372
|
+
pd = 0;
|
|
373
|
+
}
|
|
374
|
+
} else
|
|
375
|
+
nd = pd = 0;
|
|
376
|
+
fn = 1;
|
|
377
|
+
s = r = mtree->ebuf.s;
|
|
378
|
+
x = NULL;
|
|
379
|
+
while (*r == ' ')
|
|
380
|
+
r++;
|
|
381
|
+
while ((r = strchr(r, ' ')) != NULL) {
|
|
382
|
+
if (fn) {
|
|
383
|
+
fn = 0;
|
|
384
|
+
for (i = 0; i < nd + pd; i++)
|
|
385
|
+
archive_strappend_char(&mtree->buf, ' ');
|
|
386
|
+
archive_strncat(&mtree->buf, s, r - s);
|
|
387
|
+
if (nd + (r -s) > INDENTNAMELEN) {
|
|
388
|
+
archive_strncat(&mtree->buf, " \\\n", 3);
|
|
389
|
+
for (i = 0; i < (INDENTNAMELEN + 1 + pd); i++)
|
|
390
|
+
archive_strappend_char(&mtree->buf, ' ');
|
|
391
|
+
} else {
|
|
392
|
+
for (i = (int)(r -s + nd);
|
|
393
|
+
i < (INDENTNAMELEN + 1); i++)
|
|
394
|
+
archive_strappend_char(&mtree->buf, ' ');
|
|
395
|
+
}
|
|
396
|
+
s = ++r;
|
|
397
|
+
x = NULL;
|
|
398
|
+
continue;
|
|
399
|
+
}
|
|
400
|
+
if (pd + (r - s) <= MAXLINELEN - 3 - INDENTNAMELEN)
|
|
401
|
+
x = r++;
|
|
402
|
+
else {
|
|
403
|
+
if (x == NULL)
|
|
404
|
+
x = r;
|
|
405
|
+
archive_strncat(&mtree->buf, s, x - s);
|
|
406
|
+
archive_strncat(&mtree->buf, " \\\n", 3);
|
|
407
|
+
for (i = 0; i < (INDENTNAMELEN + 1 + pd); i++)
|
|
408
|
+
archive_strappend_char(&mtree->buf, ' ');
|
|
409
|
+
s = r = ++x;
|
|
410
|
+
x = NULL;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
if (fn) {
|
|
414
|
+
for (i = 0; i < nd + pd; i++)
|
|
415
|
+
archive_strappend_char(&mtree->buf, ' ');
|
|
416
|
+
archive_strcat(&mtree->buf, s);
|
|
417
|
+
s += strlen(s);
|
|
418
|
+
}
|
|
419
|
+
if (x != NULL && pd + strlen(s) > MAXLINELEN - 3 - INDENTNAMELEN) {
|
|
420
|
+
/* Last keyword is longer. */
|
|
421
|
+
archive_strncat(&mtree->buf, s, x - s);
|
|
422
|
+
archive_strncat(&mtree->buf, " \\\n", 3);
|
|
423
|
+
for (i = 0; i < (INDENTNAMELEN + 1 + pd); i++)
|
|
424
|
+
archive_strappend_char(&mtree->buf, ' ');
|
|
425
|
+
s = ++x;
|
|
426
|
+
}
|
|
427
|
+
archive_strcat(&mtree->buf, s);
|
|
428
|
+
archive_string_empty(&mtree->ebuf);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/*
|
|
432
|
+
* Write /set keyword.
|
|
433
|
+
* Set the most used value of uid, gid, mode and fflags, which are
|
|
434
|
+
* collected by the attr_counter_set_collect() function.
|
|
435
|
+
*/
|
|
436
|
+
static void
|
|
437
|
+
write_global(struct mtree_writer *mtree)
|
|
438
|
+
{
|
|
439
|
+
struct archive_string setstr;
|
|
440
|
+
struct archive_string unsetstr;
|
|
441
|
+
struct att_counter_set *acs;
|
|
442
|
+
int keys, oldkeys, effkeys;
|
|
443
|
+
|
|
444
|
+
archive_string_init(&setstr);
|
|
445
|
+
archive_string_init(&unsetstr);
|
|
446
|
+
keys = mtree->keys & SET_KEYS;
|
|
447
|
+
oldkeys = mtree->set.keys;
|
|
448
|
+
effkeys = keys;
|
|
449
|
+
acs = &mtree->acs;
|
|
450
|
+
if (mtree->set.processing) {
|
|
451
|
+
/*
|
|
452
|
+
* Check if the global data needs updating.
|
|
453
|
+
*/
|
|
454
|
+
effkeys &= ~F_TYPE;
|
|
455
|
+
if (acs->uid_list == NULL)
|
|
456
|
+
effkeys &= ~(F_UNAME | F_UID);
|
|
457
|
+
else if (oldkeys & (F_UNAME | F_UID)) {
|
|
458
|
+
if (acs->uid_list->count < 2 ||
|
|
459
|
+
mtree->set.uid == acs->uid_list->m_entry->uid)
|
|
460
|
+
effkeys &= ~(F_UNAME | F_UID);
|
|
461
|
+
}
|
|
462
|
+
if (acs->gid_list == NULL)
|
|
463
|
+
effkeys &= ~(F_GNAME | F_GID);
|
|
464
|
+
else if (oldkeys & (F_GNAME | F_GID)) {
|
|
465
|
+
if (acs->gid_list->count < 2 ||
|
|
466
|
+
mtree->set.gid == acs->gid_list->m_entry->gid)
|
|
467
|
+
effkeys &= ~(F_GNAME | F_GID);
|
|
468
|
+
}
|
|
469
|
+
if (acs->mode_list == NULL)
|
|
470
|
+
effkeys &= ~F_MODE;
|
|
471
|
+
else if (oldkeys & F_MODE) {
|
|
472
|
+
if (acs->mode_list->count < 2 ||
|
|
473
|
+
mtree->set.mode == acs->mode_list->m_entry->mode)
|
|
474
|
+
effkeys &= ~F_MODE;
|
|
475
|
+
}
|
|
476
|
+
if (acs->flags_list == NULL)
|
|
477
|
+
effkeys &= ~F_FLAGS;
|
|
478
|
+
else if ((oldkeys & F_FLAGS) != 0) {
|
|
479
|
+
if (acs->flags_list->count < 2 ||
|
|
480
|
+
(acs->flags_list->m_entry->fflags_set ==
|
|
481
|
+
mtree->set.fflags_set &&
|
|
482
|
+
acs->flags_list->m_entry->fflags_clear ==
|
|
483
|
+
mtree->set.fflags_clear))
|
|
484
|
+
effkeys &= ~F_FLAGS;
|
|
485
|
+
}
|
|
486
|
+
} else {
|
|
487
|
+
if (acs->uid_list == NULL)
|
|
488
|
+
keys &= ~(F_UNAME | F_UID);
|
|
489
|
+
if (acs->gid_list == NULL)
|
|
490
|
+
keys &= ~(F_GNAME | F_GID);
|
|
491
|
+
if (acs->mode_list == NULL)
|
|
492
|
+
keys &= ~F_MODE;
|
|
493
|
+
if (acs->flags_list == NULL)
|
|
494
|
+
keys &= ~F_FLAGS;
|
|
495
|
+
}
|
|
496
|
+
if ((keys & effkeys & F_TYPE) != 0) {
|
|
497
|
+
if (mtree->dironly) {
|
|
498
|
+
archive_strcat(&setstr, " type=dir");
|
|
499
|
+
mtree->set.type = AE_IFDIR;
|
|
500
|
+
} else {
|
|
501
|
+
archive_strcat(&setstr, " type=file");
|
|
502
|
+
mtree->set.type = AE_IFREG;
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
if ((keys & effkeys & F_UNAME) != 0) {
|
|
506
|
+
if (archive_strlen(&(acs->uid_list->m_entry->uname)) > 0) {
|
|
507
|
+
archive_strcat(&setstr, " uname=");
|
|
508
|
+
mtree_quote(&setstr, acs->uid_list->m_entry->uname.s);
|
|
509
|
+
} else {
|
|
510
|
+
keys &= ~F_UNAME;
|
|
511
|
+
if ((oldkeys & F_UNAME) != 0)
|
|
512
|
+
archive_strcat(&unsetstr, " uname");
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
if ((keys & effkeys & F_UID) != 0) {
|
|
516
|
+
mtree->set.uid = acs->uid_list->m_entry->uid;
|
|
517
|
+
archive_string_sprintf(&setstr, " uid=%jd",
|
|
518
|
+
(intmax_t)mtree->set.uid);
|
|
519
|
+
}
|
|
520
|
+
if ((keys & effkeys & F_GNAME) != 0) {
|
|
521
|
+
if (archive_strlen(&(acs->gid_list->m_entry->gname)) > 0) {
|
|
522
|
+
archive_strcat(&setstr, " gname=");
|
|
523
|
+
mtree_quote(&setstr, acs->gid_list->m_entry->gname.s);
|
|
524
|
+
} else {
|
|
525
|
+
keys &= ~F_GNAME;
|
|
526
|
+
if ((oldkeys & F_GNAME) != 0)
|
|
527
|
+
archive_strcat(&unsetstr, " gname");
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
if ((keys & effkeys & F_GID) != 0) {
|
|
531
|
+
mtree->set.gid = acs->gid_list->m_entry->gid;
|
|
532
|
+
archive_string_sprintf(&setstr, " gid=%jd",
|
|
533
|
+
(intmax_t)mtree->set.gid);
|
|
534
|
+
}
|
|
535
|
+
if ((keys & effkeys & F_MODE) != 0) {
|
|
536
|
+
mtree->set.mode = acs->mode_list->m_entry->mode;
|
|
537
|
+
archive_string_sprintf(&setstr, " mode=%o",
|
|
538
|
+
(unsigned int)mtree->set.mode);
|
|
539
|
+
}
|
|
540
|
+
if ((keys & effkeys & F_FLAGS) != 0) {
|
|
541
|
+
if (archive_strlen(
|
|
542
|
+
&(acs->flags_list->m_entry->fflags_text)) > 0) {
|
|
543
|
+
archive_strcat(&setstr, " flags=");
|
|
544
|
+
mtree_quote(&setstr,
|
|
545
|
+
acs->flags_list->m_entry->fflags_text.s);
|
|
546
|
+
mtree->set.fflags_set =
|
|
547
|
+
acs->flags_list->m_entry->fflags_set;
|
|
548
|
+
mtree->set.fflags_clear =
|
|
549
|
+
acs->flags_list->m_entry->fflags_clear;
|
|
550
|
+
} else {
|
|
551
|
+
keys &= ~F_FLAGS;
|
|
552
|
+
if ((oldkeys & F_FLAGS) != 0)
|
|
553
|
+
archive_strcat(&unsetstr, " flags");
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
if (unsetstr.length > 0)
|
|
557
|
+
archive_string_sprintf(&mtree->buf, "/unset%s\n", unsetstr.s);
|
|
558
|
+
archive_string_free(&unsetstr);
|
|
559
|
+
if (setstr.length > 0)
|
|
560
|
+
archive_string_sprintf(&mtree->buf, "/set%s\n", setstr.s);
|
|
561
|
+
archive_string_free(&setstr);
|
|
562
|
+
mtree->set.keys = keys;
|
|
563
|
+
mtree->set.processing = 1;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
static struct attr_counter *
|
|
567
|
+
attr_counter_new(struct mtree_entry *me, struct attr_counter *prev)
|
|
568
|
+
{
|
|
569
|
+
struct attr_counter *ac;
|
|
570
|
+
|
|
571
|
+
ac = malloc(sizeof(*ac));
|
|
572
|
+
if (ac != NULL) {
|
|
573
|
+
ac->prev = prev;
|
|
574
|
+
ac->next = NULL;
|
|
575
|
+
ac->count = 1;
|
|
576
|
+
ac->m_entry = me;
|
|
577
|
+
}
|
|
578
|
+
return (ac);
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
static void
|
|
582
|
+
attr_counter_free(struct attr_counter **top)
|
|
583
|
+
{
|
|
584
|
+
struct attr_counter *ac, *tac;
|
|
585
|
+
|
|
586
|
+
if (*top == NULL)
|
|
587
|
+
return;
|
|
588
|
+
ac = *top;
|
|
589
|
+
while (ac != NULL) {
|
|
590
|
+
tac = ac->next;
|
|
591
|
+
free(ac);
|
|
592
|
+
ac = tac;
|
|
593
|
+
}
|
|
594
|
+
*top = NULL;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
static int
|
|
598
|
+
attr_counter_inc(struct attr_counter **top, struct attr_counter *ac,
|
|
599
|
+
struct attr_counter *last, struct mtree_entry *me)
|
|
600
|
+
{
|
|
601
|
+
struct attr_counter *pac;
|
|
602
|
+
|
|
603
|
+
if (ac != NULL) {
|
|
604
|
+
ac->count++;
|
|
605
|
+
if (*top == ac || ac->prev->count >= ac->count)
|
|
606
|
+
return (0);
|
|
607
|
+
for (pac = ac->prev; pac; pac = pac->prev) {
|
|
608
|
+
if (pac->count >= ac->count)
|
|
609
|
+
break;
|
|
610
|
+
}
|
|
611
|
+
ac->prev->next = ac->next;
|
|
612
|
+
if (ac->next != NULL)
|
|
613
|
+
ac->next->prev = ac->prev;
|
|
614
|
+
if (pac != NULL) {
|
|
615
|
+
ac->prev = pac;
|
|
616
|
+
ac->next = pac->next;
|
|
617
|
+
pac->next = ac;
|
|
618
|
+
if (ac->next != NULL)
|
|
619
|
+
ac->next->prev = ac;
|
|
620
|
+
} else {
|
|
621
|
+
ac->prev = NULL;
|
|
622
|
+
ac->next = *top;
|
|
623
|
+
*top = ac;
|
|
624
|
+
ac->next->prev = ac;
|
|
625
|
+
}
|
|
626
|
+
} else if (last != NULL) {
|
|
627
|
+
ac = attr_counter_new(me, last);
|
|
628
|
+
if (ac == NULL)
|
|
629
|
+
return (-1);
|
|
630
|
+
last->next = ac;
|
|
631
|
+
}
|
|
632
|
+
return (0);
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
/*
|
|
636
|
+
* Tabulate uid, gid, mode and fflags of a entry in order to be used for /set.
|
|
637
|
+
*/
|
|
638
|
+
static int
|
|
639
|
+
attr_counter_set_collect(struct mtree_writer *mtree, struct mtree_entry *me)
|
|
640
|
+
{
|
|
641
|
+
struct attr_counter *ac, *last;
|
|
642
|
+
struct att_counter_set *acs = &mtree->acs;
|
|
643
|
+
int keys = mtree->keys;
|
|
644
|
+
|
|
645
|
+
if (keys & (F_UNAME | F_UID)) {
|
|
646
|
+
if (acs->uid_list == NULL) {
|
|
647
|
+
acs->uid_list = attr_counter_new(me, NULL);
|
|
648
|
+
if (acs->uid_list == NULL)
|
|
649
|
+
return (-1);
|
|
650
|
+
} else {
|
|
651
|
+
last = NULL;
|
|
652
|
+
for (ac = acs->uid_list; ac; ac = ac->next) {
|
|
653
|
+
if (ac->m_entry->uid == me->uid)
|
|
654
|
+
break;
|
|
655
|
+
last = ac;
|
|
656
|
+
}
|
|
657
|
+
if (attr_counter_inc(&acs->uid_list, ac, last, me) < 0)
|
|
658
|
+
return (-1);
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
if (keys & (F_GNAME | F_GID)) {
|
|
662
|
+
if (acs->gid_list == NULL) {
|
|
663
|
+
acs->gid_list = attr_counter_new(me, NULL);
|
|
664
|
+
if (acs->gid_list == NULL)
|
|
665
|
+
return (-1);
|
|
666
|
+
} else {
|
|
667
|
+
last = NULL;
|
|
668
|
+
for (ac = acs->gid_list; ac; ac = ac->next) {
|
|
669
|
+
if (ac->m_entry->gid == me->gid)
|
|
670
|
+
break;
|
|
671
|
+
last = ac;
|
|
672
|
+
}
|
|
673
|
+
if (attr_counter_inc(&acs->gid_list, ac, last, me) < 0)
|
|
674
|
+
return (-1);
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
if (keys & F_MODE) {
|
|
678
|
+
if (acs->mode_list == NULL) {
|
|
679
|
+
acs->mode_list = attr_counter_new(me, NULL);
|
|
680
|
+
if (acs->mode_list == NULL)
|
|
681
|
+
return (-1);
|
|
682
|
+
} else {
|
|
683
|
+
last = NULL;
|
|
684
|
+
for (ac = acs->mode_list; ac; ac = ac->next) {
|
|
685
|
+
if (ac->m_entry->mode == me->mode)
|
|
686
|
+
break;
|
|
687
|
+
last = ac;
|
|
688
|
+
}
|
|
689
|
+
if (attr_counter_inc(&acs->mode_list, ac, last, me) < 0)
|
|
690
|
+
return (-1);
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
if (keys & F_FLAGS) {
|
|
694
|
+
if (acs->flags_list == NULL) {
|
|
695
|
+
acs->flags_list = attr_counter_new(me, NULL);
|
|
696
|
+
if (acs->flags_list == NULL)
|
|
697
|
+
return (-1);
|
|
698
|
+
} else {
|
|
699
|
+
last = NULL;
|
|
700
|
+
for (ac = acs->flags_list; ac; ac = ac->next) {
|
|
701
|
+
if (ac->m_entry->fflags_set == me->fflags_set &&
|
|
702
|
+
ac->m_entry->fflags_clear ==
|
|
703
|
+
me->fflags_clear)
|
|
704
|
+
break;
|
|
705
|
+
last = ac;
|
|
706
|
+
}
|
|
707
|
+
if (attr_counter_inc(&acs->flags_list, ac, last, me) < 0)
|
|
708
|
+
return (-1);
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
return (0);
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
static void
|
|
716
|
+
attr_counter_set_free(struct mtree_writer *mtree)
|
|
717
|
+
{
|
|
718
|
+
struct att_counter_set *acs = &mtree->acs;
|
|
719
|
+
|
|
720
|
+
attr_counter_free(&acs->uid_list);
|
|
721
|
+
attr_counter_free(&acs->gid_list);
|
|
722
|
+
attr_counter_free(&acs->mode_list);
|
|
723
|
+
attr_counter_free(&acs->flags_list);
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
static int
|
|
727
|
+
get_global_set_keys(struct mtree_writer *mtree, struct mtree_entry *me)
|
|
728
|
+
{
|
|
729
|
+
int keys;
|
|
730
|
+
|
|
731
|
+
keys = mtree->keys;
|
|
732
|
+
|
|
733
|
+
/*
|
|
734
|
+
* If a keyword has been set by /set, we do not need to
|
|
735
|
+
* output it.
|
|
736
|
+
*/
|
|
737
|
+
if (mtree->set.keys == 0)
|
|
738
|
+
return (keys);/* /set is not used. */
|
|
739
|
+
|
|
740
|
+
if ((mtree->set.keys & (F_GNAME | F_GID)) != 0 &&
|
|
741
|
+
mtree->set.gid == me->gid)
|
|
742
|
+
keys &= ~(F_GNAME | F_GID);
|
|
743
|
+
if ((mtree->set.keys & (F_UNAME | F_UID)) != 0 &&
|
|
744
|
+
mtree->set.uid == me->uid)
|
|
745
|
+
keys &= ~(F_UNAME | F_UID);
|
|
746
|
+
if (mtree->set.keys & F_FLAGS) {
|
|
747
|
+
if (mtree->set.fflags_set == me->fflags_set &&
|
|
748
|
+
mtree->set.fflags_clear == me->fflags_clear)
|
|
749
|
+
keys &= ~F_FLAGS;
|
|
750
|
+
}
|
|
751
|
+
if ((mtree->set.keys & F_MODE) != 0 && mtree->set.mode == me->mode)
|
|
752
|
+
keys &= ~F_MODE;
|
|
753
|
+
|
|
754
|
+
switch (me->filetype) {
|
|
755
|
+
case AE_IFLNK: case AE_IFSOCK: case AE_IFCHR:
|
|
756
|
+
case AE_IFBLK: case AE_IFIFO:
|
|
757
|
+
break;
|
|
758
|
+
case AE_IFDIR:
|
|
759
|
+
if ((mtree->set.keys & F_TYPE) != 0 &&
|
|
760
|
+
mtree->set.type == AE_IFDIR)
|
|
761
|
+
keys &= ~F_TYPE;
|
|
762
|
+
break;
|
|
763
|
+
case AE_IFREG:
|
|
764
|
+
default: /* Handle unknown file types as regular files. */
|
|
765
|
+
if ((mtree->set.keys & F_TYPE) != 0 &&
|
|
766
|
+
mtree->set.type == AE_IFREG)
|
|
767
|
+
keys &= ~F_TYPE;
|
|
768
|
+
break;
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
return (keys);
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
static int
|
|
775
|
+
mtree_entry_new(struct archive_write *a, struct archive_entry *entry,
|
|
776
|
+
struct mtree_entry **m_entry)
|
|
777
|
+
{
|
|
778
|
+
struct mtree_entry *me;
|
|
779
|
+
const char *s;
|
|
780
|
+
int r;
|
|
781
|
+
static const struct archive_rb_tree_ops rb_ops = {
|
|
782
|
+
mtree_entry_cmp_node, mtree_entry_cmp_key
|
|
783
|
+
};
|
|
784
|
+
|
|
785
|
+
me = calloc(1, sizeof(*me));
|
|
786
|
+
if (me == NULL) {
|
|
787
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
788
|
+
"Can't allocate memory for a mtree entry");
|
|
789
|
+
*m_entry = NULL;
|
|
790
|
+
return (ARCHIVE_FATAL);
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
r = mtree_entry_setup_filenames(a, me, entry);
|
|
794
|
+
if (r < ARCHIVE_WARN) {
|
|
795
|
+
mtree_entry_free(me);
|
|
796
|
+
*m_entry = NULL;
|
|
797
|
+
return (r);
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
if ((s = archive_entry_symlink(entry)) != NULL)
|
|
801
|
+
archive_strcpy(&me->symlink, s);
|
|
802
|
+
me->nlink = archive_entry_nlink(entry);
|
|
803
|
+
me->filetype = archive_entry_filetype(entry);
|
|
804
|
+
me->mode = archive_entry_mode(entry) & 07777;
|
|
805
|
+
me->uid = archive_entry_uid(entry);
|
|
806
|
+
me->gid = archive_entry_gid(entry);
|
|
807
|
+
if ((s = archive_entry_uname(entry)) != NULL)
|
|
808
|
+
archive_strcpy(&me->uname, s);
|
|
809
|
+
if ((s = archive_entry_gname(entry)) != NULL)
|
|
810
|
+
archive_strcpy(&me->gname, s);
|
|
811
|
+
if ((s = archive_entry_fflags_text(entry)) != NULL)
|
|
812
|
+
archive_strcpy(&me->fflags_text, s);
|
|
813
|
+
archive_entry_fflags(entry, &me->fflags_set, &me->fflags_clear);
|
|
814
|
+
me->mtime = archive_entry_mtime(entry);
|
|
815
|
+
me->mtime_nsec = archive_entry_mtime_nsec(entry);
|
|
816
|
+
me->rdevmajor = archive_entry_rdevmajor(entry);
|
|
817
|
+
me->rdevminor = archive_entry_rdevminor(entry);
|
|
818
|
+
me->devmajor = archive_entry_devmajor(entry);
|
|
819
|
+
me->devminor = archive_entry_devminor(entry);
|
|
820
|
+
me->ino = archive_entry_ino(entry);
|
|
821
|
+
me->size = archive_entry_size(entry);
|
|
822
|
+
if (me->filetype == AE_IFDIR) {
|
|
823
|
+
me->dir_info = calloc(1, sizeof(*me->dir_info));
|
|
824
|
+
if (me->dir_info == NULL) {
|
|
825
|
+
mtree_entry_free(me);
|
|
826
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
827
|
+
"Can't allocate memory for a mtree entry");
|
|
828
|
+
*m_entry = NULL;
|
|
829
|
+
return (ARCHIVE_FATAL);
|
|
830
|
+
}
|
|
831
|
+
__archive_rb_tree_init(&me->dir_info->rbtree, &rb_ops);
|
|
832
|
+
me->dir_info->children.first = NULL;
|
|
833
|
+
me->dir_info->children.last = &(me->dir_info->children.first);
|
|
834
|
+
me->dir_info->chnext = NULL;
|
|
835
|
+
} else if (me->filetype == AE_IFREG) {
|
|
836
|
+
me->reg_info = calloc(1, sizeof(*me->reg_info));
|
|
837
|
+
if (me->reg_info == NULL) {
|
|
838
|
+
mtree_entry_free(me);
|
|
839
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
840
|
+
"Can't allocate memory for a mtree entry");
|
|
841
|
+
*m_entry = NULL;
|
|
842
|
+
return (ARCHIVE_FATAL);
|
|
843
|
+
}
|
|
844
|
+
me->reg_info->compute_sum = 0;
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
*m_entry = me;
|
|
848
|
+
return (ARCHIVE_OK);
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
static void
|
|
852
|
+
mtree_entry_free(struct mtree_entry *me)
|
|
853
|
+
{
|
|
854
|
+
archive_string_free(&me->parentdir);
|
|
855
|
+
archive_string_free(&me->basename);
|
|
856
|
+
archive_string_free(&me->pathname);
|
|
857
|
+
archive_string_free(&me->symlink);
|
|
858
|
+
archive_string_free(&me->uname);
|
|
859
|
+
archive_string_free(&me->gname);
|
|
860
|
+
archive_string_free(&me->fflags_text);
|
|
861
|
+
free(me->dir_info);
|
|
862
|
+
free(me->reg_info);
|
|
863
|
+
free(me);
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
static int
|
|
867
|
+
archive_write_mtree_header(struct archive_write *a,
|
|
868
|
+
struct archive_entry *entry)
|
|
869
|
+
{
|
|
870
|
+
struct mtree_writer *mtree= a->format_data;
|
|
871
|
+
struct mtree_entry *mtree_entry;
|
|
872
|
+
int r, r2;
|
|
873
|
+
|
|
874
|
+
if (mtree->first) {
|
|
875
|
+
mtree->first = 0;
|
|
876
|
+
archive_strcat(&mtree->buf, "#mtree\n");
|
|
877
|
+
if ((mtree->keys & SET_KEYS) == 0)
|
|
878
|
+
mtree->output_global_set = 0;/* Disabled. */
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
mtree->entry_bytes_remaining = archive_entry_size(entry);
|
|
882
|
+
|
|
883
|
+
/* While directory only mode, we do not handle non directory files. */
|
|
884
|
+
if (mtree->dironly && archive_entry_filetype(entry) != AE_IFDIR)
|
|
885
|
+
return (ARCHIVE_OK);
|
|
886
|
+
|
|
887
|
+
r2 = mtree_entry_new(a, entry, &mtree_entry);
|
|
888
|
+
if (r2 < ARCHIVE_WARN)
|
|
889
|
+
return (r2);
|
|
890
|
+
r = mtree_entry_tree_add(a, &mtree_entry);
|
|
891
|
+
if (r < ARCHIVE_WARN) {
|
|
892
|
+
mtree_entry_free(mtree_entry);
|
|
893
|
+
return (r);
|
|
894
|
+
}
|
|
895
|
+
mtree->mtree_entry = mtree_entry;
|
|
896
|
+
|
|
897
|
+
/* If the current file is a regular file, we have to
|
|
898
|
+
* compute the sum of its content.
|
|
899
|
+
* Initialize a bunch of checksum context. */
|
|
900
|
+
if (mtree_entry->reg_info)
|
|
901
|
+
sum_init(mtree);
|
|
902
|
+
|
|
903
|
+
return (r2);
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
static int
|
|
907
|
+
write_mtree_entry(struct archive_write *a, struct mtree_entry *me)
|
|
908
|
+
{
|
|
909
|
+
struct mtree_writer *mtree = a->format_data;
|
|
910
|
+
struct archive_string *str;
|
|
911
|
+
int keys, ret;
|
|
912
|
+
|
|
913
|
+
if (me->dir_info) {
|
|
914
|
+
if (mtree->classic) {
|
|
915
|
+
/*
|
|
916
|
+
* Output a comment line to describe the full
|
|
917
|
+
* pathname of the entry as mtree utility does
|
|
918
|
+
* while generating classic format.
|
|
919
|
+
*/
|
|
920
|
+
if (!mtree->dironly)
|
|
921
|
+
archive_strappend_char(&mtree->buf, '\n');
|
|
922
|
+
if (me->parentdir.s)
|
|
923
|
+
archive_string_sprintf(&mtree->buf,
|
|
924
|
+
"# %s/%s\n",
|
|
925
|
+
me->parentdir.s, me->basename.s);
|
|
926
|
+
else
|
|
927
|
+
archive_string_sprintf(&mtree->buf,
|
|
928
|
+
"# %s\n",
|
|
929
|
+
me->basename.s);
|
|
930
|
+
}
|
|
931
|
+
if (mtree->output_global_set)
|
|
932
|
+
write_global(mtree);
|
|
933
|
+
}
|
|
934
|
+
archive_string_empty(&mtree->ebuf);
|
|
935
|
+
str = (mtree->indent || mtree->classic)? &mtree->ebuf : &mtree->buf;
|
|
936
|
+
|
|
937
|
+
if (!mtree->classic && me->parentdir.s) {
|
|
938
|
+
/*
|
|
939
|
+
* If generating format is not classic one(v1), output
|
|
940
|
+
* a full pathname.
|
|
941
|
+
*/
|
|
942
|
+
mtree_quote(str, me->parentdir.s);
|
|
943
|
+
archive_strappend_char(str, '/');
|
|
944
|
+
}
|
|
945
|
+
mtree_quote(str, me->basename.s);
|
|
946
|
+
|
|
947
|
+
keys = get_global_set_keys(mtree, me);
|
|
948
|
+
if ((keys & F_NLINK) != 0 &&
|
|
949
|
+
me->nlink != 1 && me->filetype != AE_IFDIR)
|
|
950
|
+
archive_string_sprintf(str, " nlink=%u", me->nlink);
|
|
951
|
+
|
|
952
|
+
if ((keys & F_GNAME) != 0 && archive_strlen(&me->gname) > 0) {
|
|
953
|
+
archive_strcat(str, " gname=");
|
|
954
|
+
mtree_quote(str, me->gname.s);
|
|
955
|
+
}
|
|
956
|
+
if ((keys & F_UNAME) != 0 && archive_strlen(&me->uname) > 0) {
|
|
957
|
+
archive_strcat(str, " uname=");
|
|
958
|
+
mtree_quote(str, me->uname.s);
|
|
959
|
+
}
|
|
960
|
+
if ((keys & F_FLAGS) != 0) {
|
|
961
|
+
if (archive_strlen(&me->fflags_text) > 0) {
|
|
962
|
+
archive_strcat(str, " flags=");
|
|
963
|
+
mtree_quote(str, me->fflags_text.s);
|
|
964
|
+
} else if (mtree->set.processing &&
|
|
965
|
+
(mtree->set.keys & F_FLAGS) != 0)
|
|
966
|
+
/* Overwrite the global parameter. */
|
|
967
|
+
archive_strcat(str, " flags=none");
|
|
968
|
+
}
|
|
969
|
+
if ((keys & F_TIME) != 0)
|
|
970
|
+
archive_string_sprintf(str, " time=%jd.%jd",
|
|
971
|
+
(intmax_t)me->mtime, (intmax_t)me->mtime_nsec);
|
|
972
|
+
if ((keys & F_MODE) != 0)
|
|
973
|
+
archive_string_sprintf(str, " mode=%o", (unsigned int)me->mode);
|
|
974
|
+
if ((keys & F_GID) != 0)
|
|
975
|
+
archive_string_sprintf(str, " gid=%jd", (intmax_t)me->gid);
|
|
976
|
+
if ((keys & F_UID) != 0)
|
|
977
|
+
archive_string_sprintf(str, " uid=%jd", (intmax_t)me->uid);
|
|
978
|
+
|
|
979
|
+
if ((keys & F_INO) != 0)
|
|
980
|
+
archive_string_sprintf(str, " inode=%jd", (intmax_t)me->ino);
|
|
981
|
+
if ((keys & F_RESDEV) != 0) {
|
|
982
|
+
archive_string_sprintf(str,
|
|
983
|
+
" resdevice=native,%ju,%ju",
|
|
984
|
+
(uintmax_t)me->devmajor,
|
|
985
|
+
(uintmax_t)me->devminor);
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
switch (me->filetype) {
|
|
989
|
+
case AE_IFLNK:
|
|
990
|
+
if ((keys & F_TYPE) != 0)
|
|
991
|
+
archive_strcat(str, " type=link");
|
|
992
|
+
if ((keys & F_SLINK) != 0) {
|
|
993
|
+
archive_strcat(str, " link=");
|
|
994
|
+
mtree_quote(str, me->symlink.s);
|
|
995
|
+
}
|
|
996
|
+
break;
|
|
997
|
+
case AE_IFSOCK:
|
|
998
|
+
if ((keys & F_TYPE) != 0)
|
|
999
|
+
archive_strcat(str, " type=socket");
|
|
1000
|
+
break;
|
|
1001
|
+
case AE_IFCHR:
|
|
1002
|
+
if ((keys & F_TYPE) != 0)
|
|
1003
|
+
archive_strcat(str, " type=char");
|
|
1004
|
+
if ((keys & F_DEV) != 0) {
|
|
1005
|
+
archive_string_sprintf(str,
|
|
1006
|
+
" device=native,%ju,%ju",
|
|
1007
|
+
(uintmax_t)me->rdevmajor,
|
|
1008
|
+
(uintmax_t)me->rdevminor);
|
|
1009
|
+
}
|
|
1010
|
+
break;
|
|
1011
|
+
case AE_IFBLK:
|
|
1012
|
+
if ((keys & F_TYPE) != 0)
|
|
1013
|
+
archive_strcat(str, " type=block");
|
|
1014
|
+
if ((keys & F_DEV) != 0) {
|
|
1015
|
+
archive_string_sprintf(str,
|
|
1016
|
+
" device=native,%ju,%ju",
|
|
1017
|
+
(uintmax_t)me->rdevmajor,
|
|
1018
|
+
(uintmax_t)me->rdevminor);
|
|
1019
|
+
}
|
|
1020
|
+
break;
|
|
1021
|
+
case AE_IFDIR:
|
|
1022
|
+
if ((keys & F_TYPE) != 0)
|
|
1023
|
+
archive_strcat(str, " type=dir");
|
|
1024
|
+
break;
|
|
1025
|
+
case AE_IFIFO:
|
|
1026
|
+
if ((keys & F_TYPE) != 0)
|
|
1027
|
+
archive_strcat(str, " type=fifo");
|
|
1028
|
+
break;
|
|
1029
|
+
case AE_IFREG:
|
|
1030
|
+
default: /* Handle unknown file types as regular files. */
|
|
1031
|
+
if ((keys & F_TYPE) != 0)
|
|
1032
|
+
archive_strcat(str, " type=file");
|
|
1033
|
+
if ((keys & F_SIZE) != 0)
|
|
1034
|
+
archive_string_sprintf(str, " size=%jd",
|
|
1035
|
+
(intmax_t)me->size);
|
|
1036
|
+
break;
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
/* Write a bunch of sum. */
|
|
1040
|
+
if (me->reg_info)
|
|
1041
|
+
sum_write(str, me->reg_info);
|
|
1042
|
+
|
|
1043
|
+
archive_strappend_char(str, '\n');
|
|
1044
|
+
if (mtree->indent || mtree->classic)
|
|
1045
|
+
mtree_indent(mtree);
|
|
1046
|
+
|
|
1047
|
+
if (mtree->buf.length > 32768) {
|
|
1048
|
+
ret = __archive_write_output(
|
|
1049
|
+
a, mtree->buf.s, mtree->buf.length);
|
|
1050
|
+
archive_string_empty(&mtree->buf);
|
|
1051
|
+
} else
|
|
1052
|
+
ret = ARCHIVE_OK;
|
|
1053
|
+
return (ret);
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
static int
|
|
1057
|
+
write_dot_dot_entry(struct archive_write *a, struct mtree_entry *n)
|
|
1058
|
+
{
|
|
1059
|
+
struct mtree_writer *mtree = a->format_data;
|
|
1060
|
+
int ret;
|
|
1061
|
+
|
|
1062
|
+
if (n->parentdir.s) {
|
|
1063
|
+
if (mtree->indent) {
|
|
1064
|
+
int i, pd = mtree->depth * 4;
|
|
1065
|
+
for (i = 0; i < pd; i++)
|
|
1066
|
+
archive_strappend_char(&mtree->buf, ' ');
|
|
1067
|
+
}
|
|
1068
|
+
archive_string_sprintf(&mtree->buf, "# %s/%s\n",
|
|
1069
|
+
n->parentdir.s, n->basename.s);
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
if (mtree->indent) {
|
|
1073
|
+
archive_string_empty(&mtree->ebuf);
|
|
1074
|
+
archive_strncat(&mtree->ebuf, "..\n\n", (mtree->dironly)?3:4);
|
|
1075
|
+
mtree_indent(mtree);
|
|
1076
|
+
} else
|
|
1077
|
+
archive_strncat(&mtree->buf, "..\n\n", (mtree->dironly)?3:4);
|
|
1078
|
+
|
|
1079
|
+
if (mtree->buf.length > 32768) {
|
|
1080
|
+
ret = __archive_write_output(
|
|
1081
|
+
a, mtree->buf.s, mtree->buf.length);
|
|
1082
|
+
archive_string_empty(&mtree->buf);
|
|
1083
|
+
} else
|
|
1084
|
+
ret = ARCHIVE_OK;
|
|
1085
|
+
return (ret);
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
/*
|
|
1089
|
+
* Write mtree entries saved at attr_counter_set_collect() function.
|
|
1090
|
+
*/
|
|
1091
|
+
static int
|
|
1092
|
+
write_mtree_entry_tree(struct archive_write *a)
|
|
1093
|
+
{
|
|
1094
|
+
struct mtree_writer *mtree = a->format_data;
|
|
1095
|
+
struct mtree_entry *np = mtree->root;
|
|
1096
|
+
struct archive_rb_node *n;
|
|
1097
|
+
int ret;
|
|
1098
|
+
|
|
1099
|
+
do {
|
|
1100
|
+
if (mtree->output_global_set) {
|
|
1101
|
+
/*
|
|
1102
|
+
* Collect attribute information to know which value
|
|
1103
|
+
* is frequently used among the children.
|
|
1104
|
+
*/
|
|
1105
|
+
attr_counter_set_reset(mtree);
|
|
1106
|
+
ARCHIVE_RB_TREE_FOREACH(n, &(np->dir_info->rbtree)) {
|
|
1107
|
+
struct mtree_entry *e = (struct mtree_entry *)n;
|
|
1108
|
+
if (attr_counter_set_collect(mtree, e) < 0) {
|
|
1109
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
1110
|
+
"Can't allocate memory");
|
|
1111
|
+
return (ARCHIVE_FATAL);
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
if (!np->dir_info->virtual || mtree->classic) {
|
|
1116
|
+
ret = write_mtree_entry(a, np);
|
|
1117
|
+
if (ret != ARCHIVE_OK)
|
|
1118
|
+
return (ARCHIVE_FATAL);
|
|
1119
|
+
} else {
|
|
1120
|
+
/* Whenever output_global_set is enabled
|
|
1121
|
+
* output global value(/set keywords)
|
|
1122
|
+
* even if the directory entry is not allowed
|
|
1123
|
+
* to be written because the global values
|
|
1124
|
+
* can be used for the children. */
|
|
1125
|
+
if (mtree->output_global_set)
|
|
1126
|
+
write_global(mtree);
|
|
1127
|
+
}
|
|
1128
|
+
/*
|
|
1129
|
+
* Output the attribute of all files except directory files.
|
|
1130
|
+
*/
|
|
1131
|
+
mtree->depth++;
|
|
1132
|
+
ARCHIVE_RB_TREE_FOREACH(n, &(np->dir_info->rbtree)) {
|
|
1133
|
+
struct mtree_entry *e = (struct mtree_entry *)n;
|
|
1134
|
+
|
|
1135
|
+
if (e->dir_info)
|
|
1136
|
+
mtree_entry_add_child_tail(np, e);
|
|
1137
|
+
else {
|
|
1138
|
+
ret = write_mtree_entry(a, e);
|
|
1139
|
+
if (ret != ARCHIVE_OK)
|
|
1140
|
+
return (ARCHIVE_FATAL);
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
mtree->depth--;
|
|
1144
|
+
|
|
1145
|
+
if (np->dir_info->children.first != NULL) {
|
|
1146
|
+
/*
|
|
1147
|
+
* Descend the tree.
|
|
1148
|
+
*/
|
|
1149
|
+
np = np->dir_info->children.first;
|
|
1150
|
+
if (mtree->indent)
|
|
1151
|
+
mtree->depth++;
|
|
1152
|
+
continue;
|
|
1153
|
+
} else if (mtree->classic) {
|
|
1154
|
+
/*
|
|
1155
|
+
* While printing mtree classic, if there are not
|
|
1156
|
+
* any directory files(except "." and "..") in the
|
|
1157
|
+
* directory, output two dots ".." as returning
|
|
1158
|
+
* the parent directory.
|
|
1159
|
+
*/
|
|
1160
|
+
ret = write_dot_dot_entry(a, np);
|
|
1161
|
+
if (ret != ARCHIVE_OK)
|
|
1162
|
+
return (ARCHIVE_FATAL);
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
while (np != np->parent) {
|
|
1166
|
+
if (np->dir_info->chnext == NULL) {
|
|
1167
|
+
/*
|
|
1168
|
+
* Ascend the tree; go back to the parent.
|
|
1169
|
+
*/
|
|
1170
|
+
if (mtree->indent)
|
|
1171
|
+
mtree->depth--;
|
|
1172
|
+
if (mtree->classic) {
|
|
1173
|
+
ret = write_dot_dot_entry(a,
|
|
1174
|
+
np->parent);
|
|
1175
|
+
if (ret != ARCHIVE_OK)
|
|
1176
|
+
return (ARCHIVE_FATAL);
|
|
1177
|
+
}
|
|
1178
|
+
np = np->parent;
|
|
1179
|
+
} else {
|
|
1180
|
+
/*
|
|
1181
|
+
* Switch to next mtree entry in the directory.
|
|
1182
|
+
*/
|
|
1183
|
+
np = np->dir_info->chnext;
|
|
1184
|
+
break;
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1187
|
+
} while (np != np->parent);
|
|
1188
|
+
|
|
1189
|
+
return (ARCHIVE_OK);
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
static int
|
|
1193
|
+
archive_write_mtree_finish_entry(struct archive_write *a)
|
|
1194
|
+
{
|
|
1195
|
+
struct mtree_writer *mtree = a->format_data;
|
|
1196
|
+
struct mtree_entry *me;
|
|
1197
|
+
|
|
1198
|
+
if ((me = mtree->mtree_entry) == NULL)
|
|
1199
|
+
return (ARCHIVE_OK);
|
|
1200
|
+
mtree->mtree_entry = NULL;
|
|
1201
|
+
|
|
1202
|
+
if (me->reg_info)
|
|
1203
|
+
sum_final(mtree, me->reg_info);
|
|
1204
|
+
|
|
1205
|
+
return (ARCHIVE_OK);
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
static int
|
|
1209
|
+
archive_write_mtree_close(struct archive_write *a)
|
|
1210
|
+
{
|
|
1211
|
+
struct mtree_writer *mtree= a->format_data;
|
|
1212
|
+
int ret;
|
|
1213
|
+
|
|
1214
|
+
if (mtree->root != NULL) {
|
|
1215
|
+
ret = write_mtree_entry_tree(a);
|
|
1216
|
+
if (ret != ARCHIVE_OK)
|
|
1217
|
+
return (ARCHIVE_FATAL);
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1220
|
+
archive_write_set_bytes_in_last_block(&a->archive, 1);
|
|
1221
|
+
|
|
1222
|
+
return __archive_write_output(a, mtree->buf.s, mtree->buf.length);
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
static ssize_t
|
|
1226
|
+
archive_write_mtree_data(struct archive_write *a, const void *buff, size_t n)
|
|
1227
|
+
{
|
|
1228
|
+
struct mtree_writer *mtree= a->format_data;
|
|
1229
|
+
|
|
1230
|
+
if (n > mtree->entry_bytes_remaining)
|
|
1231
|
+
n = (size_t)mtree->entry_bytes_remaining;
|
|
1232
|
+
mtree->entry_bytes_remaining -= n;
|
|
1233
|
+
|
|
1234
|
+
/* We don't need to compute a regular file sum */
|
|
1235
|
+
if (mtree->mtree_entry == NULL)
|
|
1236
|
+
return (n);
|
|
1237
|
+
|
|
1238
|
+
if (mtree->mtree_entry->filetype == AE_IFREG)
|
|
1239
|
+
sum_update(mtree, buff, n);
|
|
1240
|
+
|
|
1241
|
+
return (n);
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1244
|
+
static int
|
|
1245
|
+
archive_write_mtree_free(struct archive_write *a)
|
|
1246
|
+
{
|
|
1247
|
+
struct mtree_writer *mtree= a->format_data;
|
|
1248
|
+
|
|
1249
|
+
if (mtree == NULL)
|
|
1250
|
+
return (ARCHIVE_OK);
|
|
1251
|
+
|
|
1252
|
+
/* Make sure we do not leave any entries. */
|
|
1253
|
+
mtree_entry_register_free(mtree);
|
|
1254
|
+
archive_string_free(&mtree->cur_dirstr);
|
|
1255
|
+
archive_string_free(&mtree->ebuf);
|
|
1256
|
+
archive_string_free(&mtree->buf);
|
|
1257
|
+
attr_counter_set_free(mtree);
|
|
1258
|
+
free(mtree);
|
|
1259
|
+
a->format_data = NULL;
|
|
1260
|
+
return (ARCHIVE_OK);
|
|
1261
|
+
}
|
|
1262
|
+
|
|
1263
|
+
static int
|
|
1264
|
+
archive_write_mtree_options(struct archive_write *a, const char *key,
|
|
1265
|
+
const char *value)
|
|
1266
|
+
{
|
|
1267
|
+
struct mtree_writer *mtree= a->format_data;
|
|
1268
|
+
int keybit = 0;
|
|
1269
|
+
|
|
1270
|
+
switch (key[0]) {
|
|
1271
|
+
case 'a':
|
|
1272
|
+
if (strcmp(key, "all") == 0)
|
|
1273
|
+
keybit = ~0;
|
|
1274
|
+
break;
|
|
1275
|
+
case 'c':
|
|
1276
|
+
if (strcmp(key, "cksum") == 0)
|
|
1277
|
+
keybit = F_CKSUM;
|
|
1278
|
+
break;
|
|
1279
|
+
case 'd':
|
|
1280
|
+
if (strcmp(key, "device") == 0)
|
|
1281
|
+
keybit = F_DEV;
|
|
1282
|
+
else if (strcmp(key, "dironly") == 0) {
|
|
1283
|
+
mtree->dironly = (value != NULL)? 1: 0;
|
|
1284
|
+
return (ARCHIVE_OK);
|
|
1285
|
+
}
|
|
1286
|
+
break;
|
|
1287
|
+
case 'f':
|
|
1288
|
+
if (strcmp(key, "flags") == 0)
|
|
1289
|
+
keybit = F_FLAGS;
|
|
1290
|
+
break;
|
|
1291
|
+
case 'g':
|
|
1292
|
+
if (strcmp(key, "gid") == 0)
|
|
1293
|
+
keybit = F_GID;
|
|
1294
|
+
else if (strcmp(key, "gname") == 0)
|
|
1295
|
+
keybit = F_GNAME;
|
|
1296
|
+
break;
|
|
1297
|
+
case 'i':
|
|
1298
|
+
if (strcmp(key, "indent") == 0) {
|
|
1299
|
+
mtree->indent = (value != NULL)? 1: 0;
|
|
1300
|
+
return (ARCHIVE_OK);
|
|
1301
|
+
} else if (strcmp(key, "inode") == 0) {
|
|
1302
|
+
keybit = F_INO;
|
|
1303
|
+
}
|
|
1304
|
+
break;
|
|
1305
|
+
case 'l':
|
|
1306
|
+
if (strcmp(key, "link") == 0)
|
|
1307
|
+
keybit = F_SLINK;
|
|
1308
|
+
break;
|
|
1309
|
+
case 'm':
|
|
1310
|
+
if (strcmp(key, "md5") == 0 ||
|
|
1311
|
+
strcmp(key, "md5digest") == 0)
|
|
1312
|
+
keybit = F_MD5;
|
|
1313
|
+
if (strcmp(key, "mode") == 0)
|
|
1314
|
+
keybit = F_MODE;
|
|
1315
|
+
break;
|
|
1316
|
+
case 'n':
|
|
1317
|
+
if (strcmp(key, "nlink") == 0)
|
|
1318
|
+
keybit = F_NLINK;
|
|
1319
|
+
break;
|
|
1320
|
+
case 'r':
|
|
1321
|
+
if (strcmp(key, "resdevice") == 0) {
|
|
1322
|
+
keybit = F_RESDEV;
|
|
1323
|
+
} else if (strcmp(key, "ripemd160digest") == 0 ||
|
|
1324
|
+
strcmp(key, "rmd160") == 0 ||
|
|
1325
|
+
strcmp(key, "rmd160digest") == 0)
|
|
1326
|
+
keybit = F_RMD160;
|
|
1327
|
+
break;
|
|
1328
|
+
case 's':
|
|
1329
|
+
if (strcmp(key, "sha1") == 0 ||
|
|
1330
|
+
strcmp(key, "sha1digest") == 0)
|
|
1331
|
+
keybit = F_SHA1;
|
|
1332
|
+
if (strcmp(key, "sha256") == 0 ||
|
|
1333
|
+
strcmp(key, "sha256digest") == 0)
|
|
1334
|
+
keybit = F_SHA256;
|
|
1335
|
+
if (strcmp(key, "sha384") == 0 ||
|
|
1336
|
+
strcmp(key, "sha384digest") == 0)
|
|
1337
|
+
keybit = F_SHA384;
|
|
1338
|
+
if (strcmp(key, "sha512") == 0 ||
|
|
1339
|
+
strcmp(key, "sha512digest") == 0)
|
|
1340
|
+
keybit = F_SHA512;
|
|
1341
|
+
if (strcmp(key, "size") == 0)
|
|
1342
|
+
keybit = F_SIZE;
|
|
1343
|
+
break;
|
|
1344
|
+
case 't':
|
|
1345
|
+
if (strcmp(key, "time") == 0)
|
|
1346
|
+
keybit = F_TIME;
|
|
1347
|
+
else if (strcmp(key, "type") == 0)
|
|
1348
|
+
keybit = F_TYPE;
|
|
1349
|
+
break;
|
|
1350
|
+
case 'u':
|
|
1351
|
+
if (strcmp(key, "uid") == 0)
|
|
1352
|
+
keybit = F_UID;
|
|
1353
|
+
else if (strcmp(key, "uname") == 0)
|
|
1354
|
+
keybit = F_UNAME;
|
|
1355
|
+
else if (strcmp(key, "use-set") == 0) {
|
|
1356
|
+
mtree->output_global_set = (value != NULL)? 1: 0;
|
|
1357
|
+
return (ARCHIVE_OK);
|
|
1358
|
+
}
|
|
1359
|
+
break;
|
|
1360
|
+
}
|
|
1361
|
+
if (keybit != 0) {
|
|
1362
|
+
if (value != NULL)
|
|
1363
|
+
mtree->keys |= keybit;
|
|
1364
|
+
else
|
|
1365
|
+
mtree->keys &= ~keybit;
|
|
1366
|
+
return (ARCHIVE_OK);
|
|
1367
|
+
}
|
|
1368
|
+
|
|
1369
|
+
/* Note: The "warn" return is just to inform the options
|
|
1370
|
+
* supervisor that we didn't handle it. It will generate
|
|
1371
|
+
* a suitable error if no one used this option. */
|
|
1372
|
+
return (ARCHIVE_WARN);
|
|
1373
|
+
}
|
|
1374
|
+
|
|
1375
|
+
static int
|
|
1376
|
+
archive_write_set_format_mtree_default(struct archive *_a, const char *fn)
|
|
1377
|
+
{
|
|
1378
|
+
struct archive_write *a = (struct archive_write *)_a;
|
|
1379
|
+
struct mtree_writer *mtree;
|
|
1380
|
+
|
|
1381
|
+
archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_NEW, fn);
|
|
1382
|
+
|
|
1383
|
+
if (a->format_free != NULL)
|
|
1384
|
+
(a->format_free)(a);
|
|
1385
|
+
|
|
1386
|
+
if ((mtree = calloc(1, sizeof(*mtree))) == NULL) {
|
|
1387
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
1388
|
+
"Can't allocate mtree data");
|
|
1389
|
+
return (ARCHIVE_FATAL);
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
mtree->mtree_entry = NULL;
|
|
1393
|
+
mtree->first = 1;
|
|
1394
|
+
memset(&(mtree->set), 0, sizeof(mtree->set));
|
|
1395
|
+
mtree->keys = DEFAULT_KEYS;
|
|
1396
|
+
mtree->dironly = 0;
|
|
1397
|
+
mtree->indent = 0;
|
|
1398
|
+
archive_string_init(&mtree->ebuf);
|
|
1399
|
+
archive_string_init(&mtree->buf);
|
|
1400
|
+
mtree_entry_register_init(mtree);
|
|
1401
|
+
a->format_data = mtree;
|
|
1402
|
+
a->format_free = archive_write_mtree_free;
|
|
1403
|
+
a->format_name = "mtree";
|
|
1404
|
+
a->format_options = archive_write_mtree_options;
|
|
1405
|
+
a->format_write_header = archive_write_mtree_header;
|
|
1406
|
+
a->format_close = archive_write_mtree_close;
|
|
1407
|
+
a->format_write_data = archive_write_mtree_data;
|
|
1408
|
+
a->format_finish_entry = archive_write_mtree_finish_entry;
|
|
1409
|
+
a->archive.archive_format = ARCHIVE_FORMAT_MTREE;
|
|
1410
|
+
a->archive.archive_format_name = "mtree";
|
|
1411
|
+
|
|
1412
|
+
return (ARCHIVE_OK);
|
|
1413
|
+
}
|
|
1414
|
+
|
|
1415
|
+
int
|
|
1416
|
+
archive_write_set_format_mtree(struct archive *_a)
|
|
1417
|
+
{
|
|
1418
|
+
return archive_write_set_format_mtree_default(_a,
|
|
1419
|
+
"archive_write_set_format_mtree");
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1422
|
+
int
|
|
1423
|
+
archive_write_set_format_mtree_classic(struct archive *_a)
|
|
1424
|
+
{
|
|
1425
|
+
int r;
|
|
1426
|
+
|
|
1427
|
+
r = archive_write_set_format_mtree_default(_a,
|
|
1428
|
+
"archive_write_set_format_mtree_classic");
|
|
1429
|
+
if (r == ARCHIVE_OK) {
|
|
1430
|
+
struct archive_write *a = (struct archive_write *)_a;
|
|
1431
|
+
struct mtree_writer *mtree;
|
|
1432
|
+
|
|
1433
|
+
mtree = (struct mtree_writer *)a->format_data;
|
|
1434
|
+
|
|
1435
|
+
/* Set to output a mtree archive in classic format. */
|
|
1436
|
+
mtree->classic = 1;
|
|
1437
|
+
/* Basically, mtree classic format uses '/set' global
|
|
1438
|
+
* value. */
|
|
1439
|
+
mtree->output_global_set = 1;
|
|
1440
|
+
}
|
|
1441
|
+
return (r);
|
|
1442
|
+
}
|
|
1443
|
+
|
|
1444
|
+
static void
|
|
1445
|
+
sum_init(struct mtree_writer *mtree)
|
|
1446
|
+
{
|
|
1447
|
+
|
|
1448
|
+
mtree->compute_sum = 0;
|
|
1449
|
+
|
|
1450
|
+
if (mtree->keys & F_CKSUM) {
|
|
1451
|
+
mtree->compute_sum |= F_CKSUM;
|
|
1452
|
+
mtree->crc = 0;
|
|
1453
|
+
mtree->crc_len = 0;
|
|
1454
|
+
}
|
|
1455
|
+
#ifdef ARCHIVE_HAS_MD5
|
|
1456
|
+
if (mtree->keys & F_MD5) {
|
|
1457
|
+
if (archive_md5_init(&mtree->md5ctx) == ARCHIVE_OK)
|
|
1458
|
+
mtree->compute_sum |= F_MD5;
|
|
1459
|
+
else
|
|
1460
|
+
mtree->keys &= ~F_MD5;/* Not supported. */
|
|
1461
|
+
}
|
|
1462
|
+
#endif
|
|
1463
|
+
#ifdef ARCHIVE_HAS_RMD160
|
|
1464
|
+
if (mtree->keys & F_RMD160) {
|
|
1465
|
+
if (archive_rmd160_init(&mtree->rmd160ctx) == ARCHIVE_OK)
|
|
1466
|
+
mtree->compute_sum |= F_RMD160;
|
|
1467
|
+
else
|
|
1468
|
+
mtree->keys &= ~F_RMD160;/* Not supported. */
|
|
1469
|
+
}
|
|
1470
|
+
#endif
|
|
1471
|
+
#ifdef ARCHIVE_HAS_SHA1
|
|
1472
|
+
if (mtree->keys & F_SHA1) {
|
|
1473
|
+
if (archive_sha1_init(&mtree->sha1ctx) == ARCHIVE_OK)
|
|
1474
|
+
mtree->compute_sum |= F_SHA1;
|
|
1475
|
+
else
|
|
1476
|
+
mtree->keys &= ~F_SHA1;/* Not supported. */
|
|
1477
|
+
}
|
|
1478
|
+
#endif
|
|
1479
|
+
#ifdef ARCHIVE_HAS_SHA256
|
|
1480
|
+
if (mtree->keys & F_SHA256) {
|
|
1481
|
+
if (archive_sha256_init(&mtree->sha256ctx) == ARCHIVE_OK)
|
|
1482
|
+
mtree->compute_sum |= F_SHA256;
|
|
1483
|
+
else
|
|
1484
|
+
mtree->keys &= ~F_SHA256;/* Not supported. */
|
|
1485
|
+
}
|
|
1486
|
+
#endif
|
|
1487
|
+
#ifdef ARCHIVE_HAS_SHA384
|
|
1488
|
+
if (mtree->keys & F_SHA384) {
|
|
1489
|
+
if (archive_sha384_init(&mtree->sha384ctx) == ARCHIVE_OK)
|
|
1490
|
+
mtree->compute_sum |= F_SHA384;
|
|
1491
|
+
else
|
|
1492
|
+
mtree->keys &= ~F_SHA384;/* Not supported. */
|
|
1493
|
+
}
|
|
1494
|
+
#endif
|
|
1495
|
+
#ifdef ARCHIVE_HAS_SHA512
|
|
1496
|
+
if (mtree->keys & F_SHA512) {
|
|
1497
|
+
if (archive_sha512_init(&mtree->sha512ctx) == ARCHIVE_OK)
|
|
1498
|
+
mtree->compute_sum |= F_SHA512;
|
|
1499
|
+
else
|
|
1500
|
+
mtree->keys &= ~F_SHA512;/* Not supported. */
|
|
1501
|
+
}
|
|
1502
|
+
#endif
|
|
1503
|
+
}
|
|
1504
|
+
|
|
1505
|
+
static void
|
|
1506
|
+
sum_update(struct mtree_writer *mtree, const void *buff, size_t n)
|
|
1507
|
+
{
|
|
1508
|
+
if (mtree->compute_sum & F_CKSUM) {
|
|
1509
|
+
/*
|
|
1510
|
+
* Compute a POSIX 1003.2 checksum
|
|
1511
|
+
*/
|
|
1512
|
+
const unsigned char *p;
|
|
1513
|
+
size_t nn;
|
|
1514
|
+
|
|
1515
|
+
for (nn = n, p = buff; nn--; ++p)
|
|
1516
|
+
COMPUTE_CRC(mtree->crc, *p);
|
|
1517
|
+
mtree->crc_len += n;
|
|
1518
|
+
}
|
|
1519
|
+
#ifdef ARCHIVE_HAS_MD5
|
|
1520
|
+
if (mtree->compute_sum & F_MD5)
|
|
1521
|
+
archive_md5_update(&mtree->md5ctx, buff, n);
|
|
1522
|
+
#endif
|
|
1523
|
+
#ifdef ARCHIVE_HAS_RMD160
|
|
1524
|
+
if (mtree->compute_sum & F_RMD160)
|
|
1525
|
+
archive_rmd160_update(&mtree->rmd160ctx, buff, n);
|
|
1526
|
+
#endif
|
|
1527
|
+
#ifdef ARCHIVE_HAS_SHA1
|
|
1528
|
+
if (mtree->compute_sum & F_SHA1)
|
|
1529
|
+
archive_sha1_update(&mtree->sha1ctx, buff, n);
|
|
1530
|
+
#endif
|
|
1531
|
+
#ifdef ARCHIVE_HAS_SHA256
|
|
1532
|
+
if (mtree->compute_sum & F_SHA256)
|
|
1533
|
+
archive_sha256_update(&mtree->sha256ctx, buff, n);
|
|
1534
|
+
#endif
|
|
1535
|
+
#ifdef ARCHIVE_HAS_SHA384
|
|
1536
|
+
if (mtree->compute_sum & F_SHA384)
|
|
1537
|
+
archive_sha384_update(&mtree->sha384ctx, buff, n);
|
|
1538
|
+
#endif
|
|
1539
|
+
#ifdef ARCHIVE_HAS_SHA512
|
|
1540
|
+
if (mtree->compute_sum & F_SHA512)
|
|
1541
|
+
archive_sha512_update(&mtree->sha512ctx, buff, n);
|
|
1542
|
+
#endif
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1545
|
+
static void
|
|
1546
|
+
sum_final(struct mtree_writer *mtree, struct reg_info *reg)
|
|
1547
|
+
{
|
|
1548
|
+
|
|
1549
|
+
if (mtree->compute_sum & F_CKSUM) {
|
|
1550
|
+
uint64_t len;
|
|
1551
|
+
/* Include the length of the file. */
|
|
1552
|
+
for (len = mtree->crc_len; len != 0; len >>= 8)
|
|
1553
|
+
COMPUTE_CRC(mtree->crc, len & 0xff);
|
|
1554
|
+
reg->crc = ~mtree->crc;
|
|
1555
|
+
}
|
|
1556
|
+
#ifdef ARCHIVE_HAS_MD5
|
|
1557
|
+
if (mtree->compute_sum & F_MD5)
|
|
1558
|
+
archive_md5_final(&mtree->md5ctx, reg->digest.md5);
|
|
1559
|
+
#endif
|
|
1560
|
+
#ifdef ARCHIVE_HAS_RMD160
|
|
1561
|
+
if (mtree->compute_sum & F_RMD160)
|
|
1562
|
+
archive_rmd160_final(&mtree->rmd160ctx, reg->digest.rmd160);
|
|
1563
|
+
#endif
|
|
1564
|
+
#ifdef ARCHIVE_HAS_SHA1
|
|
1565
|
+
if (mtree->compute_sum & F_SHA1)
|
|
1566
|
+
archive_sha1_final(&mtree->sha1ctx, reg->digest.sha1);
|
|
1567
|
+
#endif
|
|
1568
|
+
#ifdef ARCHIVE_HAS_SHA256
|
|
1569
|
+
if (mtree->compute_sum & F_SHA256)
|
|
1570
|
+
archive_sha256_final(&mtree->sha256ctx, reg->digest.sha256);
|
|
1571
|
+
#endif
|
|
1572
|
+
#ifdef ARCHIVE_HAS_SHA384
|
|
1573
|
+
if (mtree->compute_sum & F_SHA384)
|
|
1574
|
+
archive_sha384_final(&mtree->sha384ctx, reg->digest.sha384);
|
|
1575
|
+
#endif
|
|
1576
|
+
#ifdef ARCHIVE_HAS_SHA512
|
|
1577
|
+
if (mtree->compute_sum & F_SHA512)
|
|
1578
|
+
archive_sha512_final(&mtree->sha512ctx, reg->digest.sha512);
|
|
1579
|
+
#endif
|
|
1580
|
+
/* Save what types of sum are computed. */
|
|
1581
|
+
reg->compute_sum = mtree->compute_sum;
|
|
1582
|
+
}
|
|
1583
|
+
|
|
1584
|
+
#if defined(ARCHIVE_HAS_MD5) || defined(ARCHIVE_HAS_RMD160) || \
|
|
1585
|
+
defined(ARCHIVE_HAS_SHA1) || defined(ARCHIVE_HAS_SHA256) || \
|
|
1586
|
+
defined(ARCHIVE_HAS_SHA384) || defined(ARCHIVE_HAS_SHA512)
|
|
1587
|
+
static void
|
|
1588
|
+
strappend_bin(struct archive_string *s, const unsigned char *bin, int n)
|
|
1589
|
+
{
|
|
1590
|
+
static const char hex[] = "0123456789abcdef";
|
|
1591
|
+
int i;
|
|
1592
|
+
|
|
1593
|
+
for (i = 0; i < n; i++) {
|
|
1594
|
+
archive_strappend_char(s, hex[bin[i] >> 4]);
|
|
1595
|
+
archive_strappend_char(s, hex[bin[i] & 0x0f]);
|
|
1596
|
+
}
|
|
1597
|
+
}
|
|
1598
|
+
#endif
|
|
1599
|
+
|
|
1600
|
+
static void
|
|
1601
|
+
sum_write(struct archive_string *str, struct reg_info *reg)
|
|
1602
|
+
{
|
|
1603
|
+
|
|
1604
|
+
if (reg->compute_sum & F_CKSUM) {
|
|
1605
|
+
archive_string_sprintf(str, " cksum=%ju",
|
|
1606
|
+
(uintmax_t)reg->crc);
|
|
1607
|
+
}
|
|
1608
|
+
|
|
1609
|
+
#define append_digest(_s, _r, _t) \
|
|
1610
|
+
strappend_bin(_s, _r->digest._t, sizeof(_r->digest._t))
|
|
1611
|
+
|
|
1612
|
+
#ifdef ARCHIVE_HAS_MD5
|
|
1613
|
+
if (reg->compute_sum & F_MD5) {
|
|
1614
|
+
archive_strcat(str, " md5digest=");
|
|
1615
|
+
append_digest(str, reg, md5);
|
|
1616
|
+
}
|
|
1617
|
+
#endif
|
|
1618
|
+
#ifdef ARCHIVE_HAS_RMD160
|
|
1619
|
+
if (reg->compute_sum & F_RMD160) {
|
|
1620
|
+
archive_strcat(str, " rmd160digest=");
|
|
1621
|
+
append_digest(str, reg, rmd160);
|
|
1622
|
+
}
|
|
1623
|
+
#endif
|
|
1624
|
+
#ifdef ARCHIVE_HAS_SHA1
|
|
1625
|
+
if (reg->compute_sum & F_SHA1) {
|
|
1626
|
+
archive_strcat(str, " sha1digest=");
|
|
1627
|
+
append_digest(str, reg, sha1);
|
|
1628
|
+
}
|
|
1629
|
+
#endif
|
|
1630
|
+
#ifdef ARCHIVE_HAS_SHA256
|
|
1631
|
+
if (reg->compute_sum & F_SHA256) {
|
|
1632
|
+
archive_strcat(str, " sha256digest=");
|
|
1633
|
+
append_digest(str, reg, sha256);
|
|
1634
|
+
}
|
|
1635
|
+
#endif
|
|
1636
|
+
#ifdef ARCHIVE_HAS_SHA384
|
|
1637
|
+
if (reg->compute_sum & F_SHA384) {
|
|
1638
|
+
archive_strcat(str, " sha384digest=");
|
|
1639
|
+
append_digest(str, reg, sha384);
|
|
1640
|
+
}
|
|
1641
|
+
#endif
|
|
1642
|
+
#ifdef ARCHIVE_HAS_SHA512
|
|
1643
|
+
if (reg->compute_sum & F_SHA512) {
|
|
1644
|
+
archive_strcat(str, " sha512digest=");
|
|
1645
|
+
append_digest(str, reg, sha512);
|
|
1646
|
+
}
|
|
1647
|
+
#endif
|
|
1648
|
+
#undef append_digest
|
|
1649
|
+
}
|
|
1650
|
+
|
|
1651
|
+
static int
|
|
1652
|
+
mtree_entry_cmp_node(const struct archive_rb_node *n1,
|
|
1653
|
+
const struct archive_rb_node *n2)
|
|
1654
|
+
{
|
|
1655
|
+
const struct mtree_entry *e1 = (const struct mtree_entry *)n1;
|
|
1656
|
+
const struct mtree_entry *e2 = (const struct mtree_entry *)n2;
|
|
1657
|
+
|
|
1658
|
+
return (strcmp(e2->basename.s, e1->basename.s));
|
|
1659
|
+
}
|
|
1660
|
+
|
|
1661
|
+
static int
|
|
1662
|
+
mtree_entry_cmp_key(const struct archive_rb_node *n, const void *key)
|
|
1663
|
+
{
|
|
1664
|
+
const struct mtree_entry *e = (const struct mtree_entry *)n;
|
|
1665
|
+
|
|
1666
|
+
return (strcmp((const char *)key, e->basename.s));
|
|
1667
|
+
}
|
|
1668
|
+
|
|
1669
|
+
#if defined(_WIN32) || defined(__CYGWIN__)
|
|
1670
|
+
static int
|
|
1671
|
+
cleanup_backslash_1(char *p)
|
|
1672
|
+
{
|
|
1673
|
+
int mb, dos;
|
|
1674
|
+
|
|
1675
|
+
mb = dos = 0;
|
|
1676
|
+
while (*p) {
|
|
1677
|
+
if (*(unsigned char *)p > 127)
|
|
1678
|
+
mb = 1;
|
|
1679
|
+
if (*p == '\\') {
|
|
1680
|
+
/* If we have not met any multi-byte characters,
|
|
1681
|
+
* we can replace '\' with '/'. */
|
|
1682
|
+
if (!mb)
|
|
1683
|
+
*p = '/';
|
|
1684
|
+
dos = 1;
|
|
1685
|
+
}
|
|
1686
|
+
p++;
|
|
1687
|
+
}
|
|
1688
|
+
if (!mb || !dos)
|
|
1689
|
+
return (0);
|
|
1690
|
+
return (-1);
|
|
1691
|
+
}
|
|
1692
|
+
|
|
1693
|
+
static void
|
|
1694
|
+
cleanup_backslash_2(wchar_t *p)
|
|
1695
|
+
{
|
|
1696
|
+
|
|
1697
|
+
/* Convert a path-separator from '\' to '/' */
|
|
1698
|
+
while (*p != L'\0') {
|
|
1699
|
+
if (*p == L'\\')
|
|
1700
|
+
*p = L'/';
|
|
1701
|
+
p++;
|
|
1702
|
+
}
|
|
1703
|
+
}
|
|
1704
|
+
#endif
|
|
1705
|
+
|
|
1706
|
+
/*
|
|
1707
|
+
* Generate a parent directory name and a base name from a pathname.
|
|
1708
|
+
*/
|
|
1709
|
+
static int
|
|
1710
|
+
mtree_entry_setup_filenames(struct archive_write *a, struct mtree_entry *file,
|
|
1711
|
+
struct archive_entry *entry)
|
|
1712
|
+
{
|
|
1713
|
+
const char *pathname;
|
|
1714
|
+
char *p, *dirname, *slash;
|
|
1715
|
+
size_t len;
|
|
1716
|
+
int ret = ARCHIVE_OK;
|
|
1717
|
+
|
|
1718
|
+
archive_strcpy(&file->pathname, archive_entry_pathname(entry));
|
|
1719
|
+
#if defined(_WIN32) || defined(__CYGWIN__)
|
|
1720
|
+
/*
|
|
1721
|
+
* Convert a path-separator from '\' to '/'
|
|
1722
|
+
*/
|
|
1723
|
+
if (cleanup_backslash_1(file->pathname.s) != 0) {
|
|
1724
|
+
const wchar_t *wp = archive_entry_pathname_w(entry);
|
|
1725
|
+
struct archive_wstring ws;
|
|
1726
|
+
|
|
1727
|
+
if (wp != NULL) {
|
|
1728
|
+
int r;
|
|
1729
|
+
archive_string_init(&ws);
|
|
1730
|
+
archive_wstrcpy(&ws, wp);
|
|
1731
|
+
cleanup_backslash_2(ws.s);
|
|
1732
|
+
archive_string_empty(&(file->pathname));
|
|
1733
|
+
r = archive_string_append_from_wcs(&(file->pathname),
|
|
1734
|
+
ws.s, ws.length);
|
|
1735
|
+
archive_wstring_free(&ws);
|
|
1736
|
+
if (r < 0 && errno == ENOMEM) {
|
|
1737
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
1738
|
+
"Can't allocate memory");
|
|
1739
|
+
return (ARCHIVE_FATAL);
|
|
1740
|
+
}
|
|
1741
|
+
}
|
|
1742
|
+
}
|
|
1743
|
+
#else
|
|
1744
|
+
(void)a; /* UNUSED */
|
|
1745
|
+
#endif
|
|
1746
|
+
pathname = file->pathname.s;
|
|
1747
|
+
if (strcmp(pathname, ".") == 0) {
|
|
1748
|
+
archive_strcpy(&file->basename, ".");
|
|
1749
|
+
return (ARCHIVE_OK);
|
|
1750
|
+
}
|
|
1751
|
+
|
|
1752
|
+
archive_strcpy(&(file->parentdir), pathname);
|
|
1753
|
+
|
|
1754
|
+
len = file->parentdir.length;
|
|
1755
|
+
p = dirname = file->parentdir.s;
|
|
1756
|
+
|
|
1757
|
+
/*
|
|
1758
|
+
* Remove leading '/' and '../' elements
|
|
1759
|
+
*/
|
|
1760
|
+
while (*p) {
|
|
1761
|
+
if (p[0] == '/') {
|
|
1762
|
+
p++;
|
|
1763
|
+
len--;
|
|
1764
|
+
} else if (p[0] != '.')
|
|
1765
|
+
break;
|
|
1766
|
+
else if (p[1] == '.' && p[2] == '/') {
|
|
1767
|
+
p += 3;
|
|
1768
|
+
len -= 3;
|
|
1769
|
+
} else
|
|
1770
|
+
break;
|
|
1771
|
+
}
|
|
1772
|
+
if (p != dirname) {
|
|
1773
|
+
memmove(dirname, p, len+1);
|
|
1774
|
+
p = dirname;
|
|
1775
|
+
}
|
|
1776
|
+
/*
|
|
1777
|
+
* Remove "/","/." and "/.." elements from tail.
|
|
1778
|
+
*/
|
|
1779
|
+
while (len > 0) {
|
|
1780
|
+
size_t ll = len;
|
|
1781
|
+
|
|
1782
|
+
if (len > 0 && p[len-1] == '/') {
|
|
1783
|
+
p[len-1] = '\0';
|
|
1784
|
+
len--;
|
|
1785
|
+
}
|
|
1786
|
+
if (len > 1 && p[len-2] == '/' && p[len-1] == '.') {
|
|
1787
|
+
p[len-2] = '\0';
|
|
1788
|
+
len -= 2;
|
|
1789
|
+
}
|
|
1790
|
+
if (len > 2 && p[len-3] == '/' && p[len-2] == '.' &&
|
|
1791
|
+
p[len-1] == '.') {
|
|
1792
|
+
p[len-3] = '\0';
|
|
1793
|
+
len -= 3;
|
|
1794
|
+
}
|
|
1795
|
+
if (ll == len)
|
|
1796
|
+
break;
|
|
1797
|
+
}
|
|
1798
|
+
while (*p) {
|
|
1799
|
+
if (p[0] == '/') {
|
|
1800
|
+
if (p[1] == '/')
|
|
1801
|
+
/* Convert '//' --> '/' */
|
|
1802
|
+
memmove(p, p+1, strlen(p+1) + 1);
|
|
1803
|
+
else if (p[1] == '.' && p[2] == '/')
|
|
1804
|
+
/* Convert '/./' --> '/' */
|
|
1805
|
+
memmove(p, p+2, strlen(p+2) + 1);
|
|
1806
|
+
else if (p[1] == '.' && p[2] == '.' && p[3] == '/') {
|
|
1807
|
+
/* Convert 'dir/dir1/../dir2/'
|
|
1808
|
+
* --> 'dir/dir2/'
|
|
1809
|
+
*/
|
|
1810
|
+
char *rp = p -1;
|
|
1811
|
+
while (rp >= dirname) {
|
|
1812
|
+
if (*rp == '/')
|
|
1813
|
+
break;
|
|
1814
|
+
--rp;
|
|
1815
|
+
}
|
|
1816
|
+
if (rp > dirname) {
|
|
1817
|
+
strcpy(rp, p+3);
|
|
1818
|
+
p = rp;
|
|
1819
|
+
} else {
|
|
1820
|
+
strcpy(dirname, p+4);
|
|
1821
|
+
p = dirname;
|
|
1822
|
+
}
|
|
1823
|
+
} else
|
|
1824
|
+
p++;
|
|
1825
|
+
} else
|
|
1826
|
+
p++;
|
|
1827
|
+
}
|
|
1828
|
+
p = dirname;
|
|
1829
|
+
len = strlen(p);
|
|
1830
|
+
|
|
1831
|
+
/*
|
|
1832
|
+
* Add "./" prefix.
|
|
1833
|
+
* NOTE: If the pathname does not have a path separator, we have
|
|
1834
|
+
* to add "./" to the head of the pathname because mtree reader
|
|
1835
|
+
* will suppose that it is v1(a.k.a classic) mtree format and
|
|
1836
|
+
* change the directory unexpectedly and so it will make a wrong
|
|
1837
|
+
* path.
|
|
1838
|
+
*/
|
|
1839
|
+
if (strcmp(p, ".") != 0 && strncmp(p, "./", 2) != 0) {
|
|
1840
|
+
struct archive_string as;
|
|
1841
|
+
archive_string_init(&as);
|
|
1842
|
+
archive_strcpy(&as, "./");
|
|
1843
|
+
archive_strncat(&as, p, len);
|
|
1844
|
+
archive_string_empty(&file->parentdir);
|
|
1845
|
+
archive_string_concat(&file->parentdir, &as);
|
|
1846
|
+
archive_string_free(&as);
|
|
1847
|
+
p = file->parentdir.s;
|
|
1848
|
+
len = archive_strlen(&file->parentdir);
|
|
1849
|
+
}
|
|
1850
|
+
|
|
1851
|
+
/*
|
|
1852
|
+
* Find out the position which points the last position of
|
|
1853
|
+
* path separator('/').
|
|
1854
|
+
*/
|
|
1855
|
+
slash = NULL;
|
|
1856
|
+
for (; *p != '\0'; p++) {
|
|
1857
|
+
if (*p == '/')
|
|
1858
|
+
slash = p;
|
|
1859
|
+
}
|
|
1860
|
+
if (slash == NULL) {
|
|
1861
|
+
/* The pathname doesn't have a parent directory. */
|
|
1862
|
+
file->parentdir.length = len;
|
|
1863
|
+
archive_string_copy(&(file->basename), &(file->parentdir));
|
|
1864
|
+
archive_string_empty(&(file->parentdir));
|
|
1865
|
+
*file->parentdir.s = '\0';
|
|
1866
|
+
return (ret);
|
|
1867
|
+
}
|
|
1868
|
+
|
|
1869
|
+
/* Make a basename from file->parentdir.s and slash */
|
|
1870
|
+
*slash = '\0';
|
|
1871
|
+
file->parentdir.length = slash - file->parentdir.s;
|
|
1872
|
+
archive_strcpy(&(file->basename), slash + 1);
|
|
1873
|
+
return (ret);
|
|
1874
|
+
}
|
|
1875
|
+
|
|
1876
|
+
static int
|
|
1877
|
+
mtree_entry_create_virtual_dir(struct archive_write *a, const char *pathname,
|
|
1878
|
+
struct mtree_entry **m_entry)
|
|
1879
|
+
{
|
|
1880
|
+
struct archive_entry *entry;
|
|
1881
|
+
struct mtree_entry *file;
|
|
1882
|
+
int r;
|
|
1883
|
+
|
|
1884
|
+
entry = archive_entry_new();
|
|
1885
|
+
if (entry == NULL) {
|
|
1886
|
+
*m_entry = NULL;
|
|
1887
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
1888
|
+
"Can't allocate memory");
|
|
1889
|
+
return (ARCHIVE_FATAL);
|
|
1890
|
+
}
|
|
1891
|
+
archive_entry_copy_pathname(entry, pathname);
|
|
1892
|
+
archive_entry_set_mode(entry, AE_IFDIR | 0755);
|
|
1893
|
+
archive_entry_set_mtime(entry, time(NULL), 0);
|
|
1894
|
+
|
|
1895
|
+
r = mtree_entry_new(a, entry, &file);
|
|
1896
|
+
archive_entry_free(entry);
|
|
1897
|
+
if (r < ARCHIVE_WARN) {
|
|
1898
|
+
*m_entry = NULL;
|
|
1899
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
1900
|
+
"Can't allocate memory");
|
|
1901
|
+
return (ARCHIVE_FATAL);
|
|
1902
|
+
}
|
|
1903
|
+
|
|
1904
|
+
file->dir_info->virtual = 1;
|
|
1905
|
+
|
|
1906
|
+
*m_entry = file;
|
|
1907
|
+
return (ARCHIVE_OK);
|
|
1908
|
+
}
|
|
1909
|
+
|
|
1910
|
+
static void
|
|
1911
|
+
mtree_entry_register_add(struct mtree_writer *mtree, struct mtree_entry *file)
|
|
1912
|
+
{
|
|
1913
|
+
file->next = NULL;
|
|
1914
|
+
*mtree->file_list.last = file;
|
|
1915
|
+
mtree->file_list.last = &(file->next);
|
|
1916
|
+
}
|
|
1917
|
+
|
|
1918
|
+
static void
|
|
1919
|
+
mtree_entry_register_init(struct mtree_writer *mtree)
|
|
1920
|
+
{
|
|
1921
|
+
mtree->file_list.first = NULL;
|
|
1922
|
+
mtree->file_list.last = &(mtree->file_list.first);
|
|
1923
|
+
}
|
|
1924
|
+
|
|
1925
|
+
static void
|
|
1926
|
+
mtree_entry_register_free(struct mtree_writer *mtree)
|
|
1927
|
+
{
|
|
1928
|
+
struct mtree_entry *file, *file_next;
|
|
1929
|
+
|
|
1930
|
+
file = mtree->file_list.first;
|
|
1931
|
+
while (file != NULL) {
|
|
1932
|
+
file_next = file->next;
|
|
1933
|
+
mtree_entry_free(file);
|
|
1934
|
+
file = file_next;
|
|
1935
|
+
}
|
|
1936
|
+
}
|
|
1937
|
+
|
|
1938
|
+
static int
|
|
1939
|
+
mtree_entry_add_child_tail(struct mtree_entry *parent,
|
|
1940
|
+
struct mtree_entry *child)
|
|
1941
|
+
{
|
|
1942
|
+
child->dir_info->chnext = NULL;
|
|
1943
|
+
*parent->dir_info->children.last = child;
|
|
1944
|
+
parent->dir_info->children.last = &(child->dir_info->chnext);
|
|
1945
|
+
return (1);
|
|
1946
|
+
}
|
|
1947
|
+
|
|
1948
|
+
/*
|
|
1949
|
+
* Find a entry from a parent entry with the name.
|
|
1950
|
+
*/
|
|
1951
|
+
static struct mtree_entry *
|
|
1952
|
+
mtree_entry_find_child(struct mtree_entry *parent, const char *child_name)
|
|
1953
|
+
{
|
|
1954
|
+
struct mtree_entry *np;
|
|
1955
|
+
|
|
1956
|
+
if (parent == NULL)
|
|
1957
|
+
return (NULL);
|
|
1958
|
+
np = (struct mtree_entry *)__archive_rb_tree_find_node(
|
|
1959
|
+
&(parent->dir_info->rbtree), child_name);
|
|
1960
|
+
return (np);
|
|
1961
|
+
}
|
|
1962
|
+
|
|
1963
|
+
static int
|
|
1964
|
+
get_path_component(char *name, size_t n, const char *fn)
|
|
1965
|
+
{
|
|
1966
|
+
char *p;
|
|
1967
|
+
size_t l;
|
|
1968
|
+
|
|
1969
|
+
p = strchr(fn, '/');
|
|
1970
|
+
if (p == NULL) {
|
|
1971
|
+
if ((l = strlen(fn)) == 0)
|
|
1972
|
+
return (0);
|
|
1973
|
+
} else
|
|
1974
|
+
l = p - fn;
|
|
1975
|
+
if (l > n -1)
|
|
1976
|
+
return (-1);
|
|
1977
|
+
memcpy(name, fn, l);
|
|
1978
|
+
name[l] = '\0';
|
|
1979
|
+
|
|
1980
|
+
return ((int)l);
|
|
1981
|
+
}
|
|
1982
|
+
|
|
1983
|
+
/*
|
|
1984
|
+
* Add a new entry into the tree.
|
|
1985
|
+
*/
|
|
1986
|
+
static int
|
|
1987
|
+
mtree_entry_tree_add(struct archive_write *a, struct mtree_entry **filep)
|
|
1988
|
+
{
|
|
1989
|
+
#if defined(_WIN32) && !defined(__CYGWIN__)
|
|
1990
|
+
char name[_MAX_FNAME];/* Included null terminator size. */
|
|
1991
|
+
#elif defined(NAME_MAX) && NAME_MAX >= 255
|
|
1992
|
+
char name[NAME_MAX+1];
|
|
1993
|
+
#else
|
|
1994
|
+
char name[256];
|
|
1995
|
+
#endif
|
|
1996
|
+
struct mtree_writer *mtree = (struct mtree_writer *)a->format_data;
|
|
1997
|
+
struct mtree_entry *dent, *file, *np;
|
|
1998
|
+
const char *fn, *p;
|
|
1999
|
+
int l, r;
|
|
2000
|
+
|
|
2001
|
+
file = *filep;
|
|
2002
|
+
if (file->parentdir.length == 0 && file->basename.length == 1 &&
|
|
2003
|
+
file->basename.s[0] == '.') {
|
|
2004
|
+
file->parent = file;
|
|
2005
|
+
if (mtree->root != NULL) {
|
|
2006
|
+
np = mtree->root;
|
|
2007
|
+
goto same_entry;
|
|
2008
|
+
}
|
|
2009
|
+
mtree->root = file;
|
|
2010
|
+
mtree_entry_register_add(mtree, file);
|
|
2011
|
+
return (ARCHIVE_OK);
|
|
2012
|
+
}
|
|
2013
|
+
|
|
2014
|
+
if (file->parentdir.length == 0) {
|
|
2015
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
2016
|
+
"Internal programming error "
|
|
2017
|
+
"in generating canonical name for %s",
|
|
2018
|
+
file->pathname.s);
|
|
2019
|
+
return (ARCHIVE_FAILED);
|
|
2020
|
+
}
|
|
2021
|
+
|
|
2022
|
+
fn = p = file->parentdir.s;
|
|
2023
|
+
|
|
2024
|
+
/*
|
|
2025
|
+
* If the path of the parent directory of `file' entry is
|
|
2026
|
+
* the same as the path of `cur_dirent', add `file' entry to
|
|
2027
|
+
* `cur_dirent'.
|
|
2028
|
+
*/
|
|
2029
|
+
if (archive_strlen(&(mtree->cur_dirstr))
|
|
2030
|
+
== archive_strlen(&(file->parentdir)) &&
|
|
2031
|
+
strcmp(mtree->cur_dirstr.s, fn) == 0) {
|
|
2032
|
+
if (!__archive_rb_tree_insert_node(
|
|
2033
|
+
&(mtree->cur_dirent->dir_info->rbtree),
|
|
2034
|
+
(struct archive_rb_node *)file)) {
|
|
2035
|
+
/* There is the same name in the tree. */
|
|
2036
|
+
np = (struct mtree_entry *)__archive_rb_tree_find_node(
|
|
2037
|
+
&(mtree->cur_dirent->dir_info->rbtree),
|
|
2038
|
+
file->basename.s);
|
|
2039
|
+
goto same_entry;
|
|
2040
|
+
}
|
|
2041
|
+
file->parent = mtree->cur_dirent;
|
|
2042
|
+
mtree_entry_register_add(mtree, file);
|
|
2043
|
+
return (ARCHIVE_OK);
|
|
2044
|
+
}
|
|
2045
|
+
|
|
2046
|
+
dent = mtree->root;
|
|
2047
|
+
for (;;) {
|
|
2048
|
+
l = get_path_component(name, sizeof(name), fn);
|
|
2049
|
+
if (l == 0) {
|
|
2050
|
+
np = NULL;
|
|
2051
|
+
break;
|
|
2052
|
+
}
|
|
2053
|
+
if (l < 0) {
|
|
2054
|
+
archive_set_error(&a->archive,
|
|
2055
|
+
ARCHIVE_ERRNO_MISC,
|
|
2056
|
+
"A name buffer is too small");
|
|
2057
|
+
return (ARCHIVE_FATAL);
|
|
2058
|
+
}
|
|
2059
|
+
if (l == 1 && name[0] == '.' && dent != NULL &&
|
|
2060
|
+
dent == mtree->root) {
|
|
2061
|
+
fn += l;
|
|
2062
|
+
if (fn[0] == '/')
|
|
2063
|
+
fn++;
|
|
2064
|
+
continue;
|
|
2065
|
+
}
|
|
2066
|
+
|
|
2067
|
+
np = mtree_entry_find_child(dent, name);
|
|
2068
|
+
if (np == NULL || fn[0] == '\0')
|
|
2069
|
+
break;
|
|
2070
|
+
|
|
2071
|
+
/* Find next sub directory. */
|
|
2072
|
+
if (!np->dir_info) {
|
|
2073
|
+
/* NOT Directory! */
|
|
2074
|
+
archive_set_error(&a->archive,
|
|
2075
|
+
ARCHIVE_ERRNO_MISC,
|
|
2076
|
+
"`%s' is not directory, we cannot insert `%s' ",
|
|
2077
|
+
np->pathname.s, file->pathname.s);
|
|
2078
|
+
return (ARCHIVE_FAILED);
|
|
2079
|
+
}
|
|
2080
|
+
fn += l;
|
|
2081
|
+
if (fn[0] == '/')
|
|
2082
|
+
fn++;
|
|
2083
|
+
dent = np;
|
|
2084
|
+
}
|
|
2085
|
+
if (np == NULL) {
|
|
2086
|
+
/*
|
|
2087
|
+
* Create virtual parent directories.
|
|
2088
|
+
*/
|
|
2089
|
+
while (fn[0] != '\0') {
|
|
2090
|
+
struct mtree_entry *vp;
|
|
2091
|
+
struct archive_string as;
|
|
2092
|
+
|
|
2093
|
+
archive_string_init(&as);
|
|
2094
|
+
archive_strncat(&as, p, fn - p + l);
|
|
2095
|
+
if (as.s[as.length-1] == '/') {
|
|
2096
|
+
as.s[as.length-1] = '\0';
|
|
2097
|
+
as.length--;
|
|
2098
|
+
}
|
|
2099
|
+
r = mtree_entry_create_virtual_dir(a, as.s, &vp);
|
|
2100
|
+
archive_string_free(&as);
|
|
2101
|
+
if (r < ARCHIVE_WARN)
|
|
2102
|
+
return (r);
|
|
2103
|
+
|
|
2104
|
+
if (strcmp(vp->pathname.s, ".") == 0) {
|
|
2105
|
+
vp->parent = vp;
|
|
2106
|
+
mtree->root = vp;
|
|
2107
|
+
} else {
|
|
2108
|
+
__archive_rb_tree_insert_node(
|
|
2109
|
+
&(dent->dir_info->rbtree),
|
|
2110
|
+
(struct archive_rb_node *)vp);
|
|
2111
|
+
vp->parent = dent;
|
|
2112
|
+
}
|
|
2113
|
+
mtree_entry_register_add(mtree, vp);
|
|
2114
|
+
np = vp;
|
|
2115
|
+
|
|
2116
|
+
fn += l;
|
|
2117
|
+
if (fn[0] == '/')
|
|
2118
|
+
fn++;
|
|
2119
|
+
l = get_path_component(name, sizeof(name), fn);
|
|
2120
|
+
if (l < 0) {
|
|
2121
|
+
archive_string_free(&as);
|
|
2122
|
+
archive_set_error(&a->archive,
|
|
2123
|
+
ARCHIVE_ERRNO_MISC,
|
|
2124
|
+
"A name buffer is too small");
|
|
2125
|
+
return (ARCHIVE_FATAL);
|
|
2126
|
+
}
|
|
2127
|
+
dent = np;
|
|
2128
|
+
}
|
|
2129
|
+
|
|
2130
|
+
/* Found out the parent directory where `file' can be
|
|
2131
|
+
* inserted. */
|
|
2132
|
+
mtree->cur_dirent = dent;
|
|
2133
|
+
archive_string_empty(&(mtree->cur_dirstr));
|
|
2134
|
+
archive_string_ensure(&(mtree->cur_dirstr),
|
|
2135
|
+
archive_strlen(&(dent->parentdir)) +
|
|
2136
|
+
archive_strlen(&(dent->basename)) + 2);
|
|
2137
|
+
if (archive_strlen(&(dent->parentdir)) +
|
|
2138
|
+
archive_strlen(&(dent->basename)) == 0)
|
|
2139
|
+
mtree->cur_dirstr.s[0] = 0;
|
|
2140
|
+
else {
|
|
2141
|
+
if (archive_strlen(&(dent->parentdir)) > 0) {
|
|
2142
|
+
archive_string_copy(&(mtree->cur_dirstr),
|
|
2143
|
+
&(dent->parentdir));
|
|
2144
|
+
archive_strappend_char(
|
|
2145
|
+
&(mtree->cur_dirstr), '/');
|
|
2146
|
+
}
|
|
2147
|
+
archive_string_concat(&(mtree->cur_dirstr),
|
|
2148
|
+
&(dent->basename));
|
|
2149
|
+
}
|
|
2150
|
+
|
|
2151
|
+
if (!__archive_rb_tree_insert_node(
|
|
2152
|
+
&(dent->dir_info->rbtree),
|
|
2153
|
+
(struct archive_rb_node *)file)) {
|
|
2154
|
+
np = (struct mtree_entry *)__archive_rb_tree_find_node(
|
|
2155
|
+
&(dent->dir_info->rbtree), file->basename.s);
|
|
2156
|
+
goto same_entry;
|
|
2157
|
+
}
|
|
2158
|
+
file->parent = dent;
|
|
2159
|
+
mtree_entry_register_add(mtree, file);
|
|
2160
|
+
return (ARCHIVE_OK);
|
|
2161
|
+
}
|
|
2162
|
+
|
|
2163
|
+
same_entry:
|
|
2164
|
+
/*
|
|
2165
|
+
* We have already has the entry the filename of which is
|
|
2166
|
+
* the same.
|
|
2167
|
+
*/
|
|
2168
|
+
r = mtree_entry_exchange_same_entry(a, np, file);
|
|
2169
|
+
if (r < ARCHIVE_WARN)
|
|
2170
|
+
return (r);
|
|
2171
|
+
if (np->dir_info)
|
|
2172
|
+
np->dir_info->virtual = 0;
|
|
2173
|
+
*filep = np;
|
|
2174
|
+
mtree_entry_free(file);
|
|
2175
|
+
return (ARCHIVE_WARN);
|
|
2176
|
+
}
|
|
2177
|
+
|
|
2178
|
+
static int
|
|
2179
|
+
mtree_entry_exchange_same_entry(struct archive_write *a, struct mtree_entry *np,
|
|
2180
|
+
struct mtree_entry *file)
|
|
2181
|
+
{
|
|
2182
|
+
|
|
2183
|
+
if ((np->mode & AE_IFMT) != (file->mode & AE_IFMT)) {
|
|
2184
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
2185
|
+
"Found duplicate entries `%s' and its file type is "
|
|
2186
|
+
"different",
|
|
2187
|
+
np->pathname.s);
|
|
2188
|
+
return (ARCHIVE_FAILED);
|
|
2189
|
+
}
|
|
2190
|
+
|
|
2191
|
+
/* Update the existent mtree entry's attributes by the new one's. */
|
|
2192
|
+
archive_string_empty(&np->symlink);
|
|
2193
|
+
archive_string_concat(&np->symlink, &file->symlink);
|
|
2194
|
+
archive_string_empty(&np->uname);
|
|
2195
|
+
archive_string_concat(&np->uname, &file->uname);
|
|
2196
|
+
archive_string_empty(&np->gname);
|
|
2197
|
+
archive_string_concat(&np->gname, &file->gname);
|
|
2198
|
+
archive_string_empty(&np->fflags_text);
|
|
2199
|
+
archive_string_concat(&np->fflags_text, &file->fflags_text);
|
|
2200
|
+
np->nlink = file->nlink;
|
|
2201
|
+
np->filetype = file->filetype;
|
|
2202
|
+
np->mode = file->mode;
|
|
2203
|
+
np->size = file->size;
|
|
2204
|
+
np->uid = file->uid;
|
|
2205
|
+
np->gid = file->gid;
|
|
2206
|
+
np->fflags_set = file->fflags_set;
|
|
2207
|
+
np->fflags_clear = file->fflags_clear;
|
|
2208
|
+
np->mtime = file->mtime;
|
|
2209
|
+
np->mtime_nsec = file->mtime_nsec;
|
|
2210
|
+
np->rdevmajor = file->rdevmajor;
|
|
2211
|
+
np->rdevminor = file->rdevminor;
|
|
2212
|
+
np->devmajor = file->devmajor;
|
|
2213
|
+
np->devminor = file->devminor;
|
|
2214
|
+
np->ino = file->ino;
|
|
2215
|
+
|
|
2216
|
+
return (ARCHIVE_WARN);
|
|
2217
|
+
}
|