aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Matuska <mm@FreeBSD.org>2012-02-08 12:53:14 +0000
committerMartin Matuska <mm@FreeBSD.org>2012-02-08 12:53:14 +0000
commit17993d47e9beebea021707962fcdf2387b27cae9 (patch)
tree28a8e9d81eb7ed48e286dfc384e2e0ffccc238b5
parentd8b2811c01ad218932b237af23558ab000e58265 (diff)
downloadsrc-17993d47e9beebea021707962fcdf2387b27cae9.tar.gz
src-17993d47e9beebea021707962fcdf2387b27cae9.zip
Update vendor libarchive dist to new "release" branch (post 3.0.3)
Git branch: release Git commit: 9af87742342aa4f37a22ec12c4cc1c82e00ffa2f Obtained from: https://github.com/libarchive/libarchive.git
Notes
Notes: svn path=/vendor/libarchive/dist/; revision=231200
-rw-r--r--CMakeLists.txt650
-rw-r--r--COPYING4
-rw-r--r--INSTALL9
-rw-r--r--Makefile.am282
-rw-r--r--NEWS97
-rw-r--r--README37
-rwxr-xr-xbuild/autoconf/config.rpath696
-rw-r--r--build/autoconf/iconv.m4268
-rw-r--r--build/autoconf/lib-ld.m4109
-rw-r--r--build/autoconf/lib-link.m4777
-rw-r--r--build/autoconf/lib-prefix.m4224
-rwxr-xr-xbuild/autogen.sh10
-rw-r--r--build/clean.sh54
-rw-r--r--build/cmake/AddTest28.cmake107
-rw-r--r--build/cmake/FindLZMA.cmake6
-rw-r--r--build/cmake/config.h.in574
-rwxr-xr-xbuild/makerelease.sh57
-rw-r--r--build/pkgconfig/libarchive.pc.in3
-rwxr-xr-xbuild/utils/gen_archive_string_composition_h.sh418
-rw-r--r--build/version2
-rw-r--r--configure.ac322
-rw-r--r--contrib/README29
-rw-r--r--contrib/libarchive.1aix53.spec4
-rw-r--r--contrib/libarchive.spec4
-rw-r--r--contrib/psota-benchmark/results.txt16
-rw-r--r--contrib/psota-benchmark/tcp.sh22
-rw-r--r--contrib/shar/shar.c2
-rw-r--r--contrib/untar.c6
-rw-r--r--cpio/bsdcpio.165
-rw-r--r--cpio/cmdline.c21
-rw-r--r--cpio/cpio.c96
-rw-r--r--cpio/cpio.h8
-rw-r--r--cpio/test/CMakeLists.txt6
-rw-r--r--cpio/test/main.c760
-rw-r--r--cpio/test/test.h98
-rw-r--r--cpio/test/test_0.c14
-rw-r--r--cpio/test/test_basic.c49
-rw-r--r--cpio/test/test_format_newc.c45
-rw-r--r--cpio/test/test_option_0.c92
-rw-r--r--cpio/test/test_option_c.c20
-rw-r--r--cpio/test/test_option_t.c31
-rw-r--r--cpio/test/test_option_u.c6
-rw-r--r--cpio/test/test_owner_parse.c11
-rw-r--r--doc/html/.ignore_me2
-rw-r--r--doc/man/.ignore_me2
-rw-r--r--doc/mdoc2wiki.awk8
-rw-r--r--doc/pdf/.ignore_me2
-rw-r--r--doc/text/.ignore_me2
-rw-r--r--doc/wiki/.ignore_me2
-rw-r--r--examples/minitar/Makefile20
-rw-r--r--examples/minitar/minitar.c85
-rw-r--r--examples/minitar/tree.c423
-rw-r--r--examples/minitar/tree.h78
-rw-r--r--examples/tarfilter.c6
-rw-r--r--examples/untar.c6
-rw-r--r--libarchive/CMakeLists.txt69
-rw-r--r--libarchive/archive.h517
-rw-r--r--libarchive/archive_acl.c1264
-rw-r--r--libarchive/archive_acl_private.h87
-rw-r--r--libarchive/archive_check_magic.c80
-rw-r--r--libarchive/archive_crc32.h12
-rw-r--r--libarchive/archive_crypto.c1427
-rw-r--r--libarchive/archive_crypto_private.h376
-rw-r--r--libarchive/archive_entry.3337
-rw-r--r--libarchive/archive_entry.c1335
-rw-r--r--libarchive/archive_entry.h238
-rw-r--r--libarchive/archive_entry_acl.3233
-rw-r--r--libarchive/archive_entry_copy_bhfi.c3
-rw-r--r--libarchive/archive_entry_copy_stat.c8
-rw-r--r--libarchive/archive_entry_link_resolver.c161
-rw-r--r--libarchive/archive_entry_linkify.3224
-rw-r--r--libarchive/archive_entry_locale.h88
-rw-r--r--libarchive/archive_entry_paths.3151
-rw-r--r--libarchive/archive_entry_perms.3207
-rw-r--r--libarchive/archive_entry_private.h86
-rw-r--r--libarchive/archive_entry_sparse.c156
-rw-r--r--libarchive/archive_entry_stat.3272
-rw-r--r--libarchive/archive_entry_stat.c4
-rw-r--r--libarchive/archive_entry_time.3127
-rw-r--r--libarchive/archive_hash.h309
-rw-r--r--libarchive/archive_options.c164
-rw-r--r--libarchive/archive_options_private.h47
-rw-r--r--libarchive/archive_ppmd7.c1164
-rw-r--r--libarchive/archive_ppmd7_private.h119
-rw-r--r--libarchive/archive_ppmd_private.h158
-rw-r--r--libarchive/archive_private.h48
-rw-r--r--libarchive/archive_rb.c701
-rw-r--r--libarchive/archive_rb.h100
-rw-r--r--libarchive/archive_read.3696
-rw-r--r--libarchive/archive_read.c923
-rw-r--r--libarchive/archive_read_data.3128
-rw-r--r--libarchive/archive_read_data_into_fd.c82
-rw-r--r--libarchive/archive_read_disk.331
-rw-r--r--libarchive/archive_read_disk.c198
-rw-r--r--libarchive/archive_read_disk_entry_from_file.c561
-rw-r--r--libarchive/archive_read_disk_posix.c2311
-rw-r--r--libarchive/archive_read_disk_private.h13
-rw-r--r--libarchive/archive_read_disk_set_standard_lookup.c28
-rw-r--r--libarchive/archive_read_disk_windows.c1983
-rw-r--r--libarchive/archive_read_extract.3135
-rw-r--r--libarchive/archive_read_extract.c11
-rw-r--r--libarchive/archive_read_filter.3127
-rw-r--r--libarchive/archive_read_format.3175
-rw-r--r--libarchive/archive_read_free.391
-rw-r--r--libarchive/archive_read_header.389
-rw-r--r--libarchive/archive_read_new.357
-rw-r--r--libarchive/archive_read_open.3231
-rw-r--r--libarchive/archive_read_open_fd.c87
-rw-r--r--libarchive/archive_read_open_file.c44
-rw-r--r--libarchive/archive_read_open_filename.c431
-rw-r--r--libarchive/archive_read_open_memory.c76
-rw-r--r--libarchive/archive_read_private.h55
-rw-r--r--libarchive/archive_read_set_options.3207
-rw-r--r--libarchive/archive_read_set_options.c148
-rw-r--r--libarchive/archive_read_support_filter_all.c (renamed from libarchive/archive_read_support_compression_all.c)33
-rw-r--r--libarchive/archive_read_support_filter_bzip2.c (renamed from libarchive/archive_read_support_compression_bzip2.c)31
-rw-r--r--libarchive/archive_read_support_filter_compress.c (renamed from libarchive/archive_read_support_compression_compress.c)42
-rw-r--r--libarchive/archive_read_support_filter_gzip.c (renamed from libarchive/archive_read_support_compression_gzip.c)37
-rw-r--r--libarchive/archive_read_support_filter_none.c (renamed from libarchive/archive_read_support_compression_none.c)18
-rw-r--r--libarchive/archive_read_support_filter_program.c (renamed from libarchive/archive_read_support_compression_program.c)33
-rw-r--r--libarchive/archive_read_support_filter_rpm.c (renamed from libarchive/archive_read_support_compression_rpm.c)33
-rw-r--r--libarchive/archive_read_support_filter_uu.c (renamed from libarchive/archive_read_support_compression_uu.c)87
-rw-r--r--libarchive/archive_read_support_filter_xz.c (renamed from libarchive/archive_read_support_compression_xz.c)457
-rw-r--r--libarchive/archive_read_support_format_7zip.c3706
-rw-r--r--libarchive/archive_read_support_format_all.c38
-rw-r--r--libarchive/archive_read_support_format_ar.c143
-rw-r--r--libarchive/archive_read_support_format_by_code.c74
-rw-r--r--libarchive/archive_read_support_format_cab.c3315
-rw-r--r--libarchive/archive_read_support_format_cpio.c598
-rw-r--r--libarchive/archive_read_support_format_empty.c20
-rw-r--r--libarchive/archive_read_support_format_iso9660.c446
-rw-r--r--libarchive/archive_read_support_format_lha.c2745
-rw-r--r--libarchive/archive_read_support_format_mtree.c631
-rw-r--r--libarchive/archive_read_support_format_rar.c2574
-rw-r--r--libarchive/archive_read_support_format_raw.c58
-rw-r--r--libarchive/archive_read_support_format_tar.c1176
-rw-r--r--libarchive/archive_read_support_format_xar.c417
-rw-r--r--libarchive/archive_read_support_format_zip.c1240
-rw-r--r--libarchive/archive_string.c4304
-rw-r--r--libarchive/archive_string.h178
-rw-r--r--libarchive/archive_string_composition.h1351
-rw-r--r--libarchive/archive_string_sprintf.c50
-rw-r--r--libarchive/archive_util.374
-rw-r--r--libarchive/archive_util.c499
-rw-r--r--libarchive/archive_virtual.c59
-rw-r--r--libarchive/archive_windows.c606
-rw-r--r--libarchive/archive_windows.h111
-rw-r--r--libarchive/archive_write.3546
-rw-r--r--libarchive/archive_write.c581
-rw-r--r--libarchive/archive_write_add_filter_bzip2.c335
-rw-r--r--libarchive/archive_write_add_filter_compress.c (renamed from libarchive/archive_write_set_compression_compress.c)197
-rw-r--r--libarchive/archive_write_add_filter_gzip.c356
-rw-r--r--libarchive/archive_write_add_filter_none.c43
-rw-r--r--libarchive/archive_write_add_filter_program.c327
-rw-r--r--libarchive/archive_write_add_filter_xz.c502
-rw-r--r--libarchive/archive_write_blocksize.3112
-rw-r--r--libarchive/archive_write_data.360
-rw-r--r--libarchive/archive_write_disk.346
-rw-r--r--libarchive/archive_write_disk_posix.c (renamed from libarchive/archive_write_disk.c)906
-rw-r--r--libarchive/archive_write_disk_set_standard_lookup.c12
-rw-r--r--libarchive/archive_write_disk_windows.c2514
-rw-r--r--libarchive/archive_write_filter.398
-rw-r--r--libarchive/archive_write_finish_entry.374
-rw-r--r--libarchive/archive_write_format.398
-rw-r--r--libarchive/archive_write_free.381
-rw-r--r--libarchive/archive_write_header.371
-rw-r--r--libarchive/archive_write_new.356
-rw-r--r--libarchive/archive_write_open.3233
-rw-r--r--libarchive/archive_write_open_filename.c106
-rw-r--r--libarchive/archive_write_open_memory.c12
-rw-r--r--libarchive/archive_write_private.h64
-rw-r--r--libarchive/archive_write_set_compression_bzip2.c408
-rw-r--r--libarchive/archive_write_set_compression_gzip.c477
-rw-r--r--libarchive/archive_write_set_compression_none.c257
-rw-r--r--libarchive/archive_write_set_compression_program.c347
-rw-r--r--libarchive/archive_write_set_compression_xz.c439
-rw-r--r--libarchive/archive_write_set_format.c6
-rw-r--r--libarchive/archive_write_set_format_7zip.c2305
-rw-r--r--libarchive/archive_write_set_format_ar.c58
-rw-r--r--libarchive/archive_write_set_format_by_name.c10
-rw-r--r--libarchive/archive_write_set_format_cpio.c272
-rw-r--r--libarchive/archive_write_set_format_cpio_newc.c291
-rw-r--r--libarchive/archive_write_set_format_gnutar.c684
-rw-r--r--libarchive/archive_write_set_format_iso9660.c8114
-rw-r--r--libarchive/archive_write_set_format_mtree.c1116
-rw-r--r--libarchive/archive_write_set_format_pax.c1108
-rw-r--r--libarchive/archive_write_set_format_shar.c91
-rw-r--r--libarchive/archive_write_set_format_ustar.c253
-rw-r--r--libarchive/archive_write_set_format_xar.c3175
-rw-r--r--libarchive/archive_write_set_format_zip.c322
-rw-r--r--libarchive/archive_write_set_options.3437
-rw-r--r--libarchive/archive_write_set_options.c124
-rw-r--r--libarchive/config_freebsd.h6
-rw-r--r--libarchive/filter_fork_windows.c50
-rw-r--r--libarchive/libarchive-formats.56
-rw-r--r--libarchive/libarchive.3139
-rw-r--r--libarchive/libarchive_changes.3341
-rw-r--r--libarchive/libarchive_internals.36
-rw-r--r--libarchive/tar.5198
-rw-r--r--libarchive/test/CMakeLists.txt75
-rw-r--r--libarchive/test/main.c752
-rw-r--r--libarchive/test/read_open_memory.c98
-rw-r--r--libarchive/test/test.h96
-rw-r--r--libarchive/test/test_acl_freebsd.c4
-rw-r--r--libarchive/test/test_acl_nfs4.c291
-rw-r--r--libarchive/test/test_acl_pax.c263
-rw-r--r--libarchive/test/test_acl_pax.tar.uu117
-rw-r--r--libarchive/test/test_acl_posix1e.c (renamed from libarchive/test/test_acl_basic.c)62
-rw-r--r--libarchive/test/test_archive_api_feature.c28
-rw-r--r--libarchive/test/test_archive_clear_error.c42
-rw-r--r--libarchive/test/test_archive_crypto.c145
-rw-r--r--libarchive/test/test_archive_read_close_twice.c43
-rw-r--r--libarchive/test/test_archive_read_close_twice_open_fd.c47
-rw-r--r--libarchive/test/test_archive_read_close_twice_open_filename.c47
-rw-r--r--libarchive/test/test_archive_read_next_header_empty.c111
-rw-r--r--libarchive/test/test_archive_read_next_header_raw.c65
-rw-r--r--libarchive/test/test_archive_read_open2.c109
-rw-r--r--libarchive/test/test_archive_read_set_filter_option.c55
-rw-r--r--libarchive/test/test_archive_read_set_format_option.c67
-rw-r--r--libarchive/test/test_archive_read_set_option.c69
-rw-r--r--libarchive/test/test_archive_read_set_options.c79
-rw-r--r--libarchive/test/test_archive_read_support.c98
-rw-r--r--libarchive/test/test_archive_set_error.c51
-rw-r--r--libarchive/test/test_archive_string.c344
-rw-r--r--libarchive/test/test_archive_string_conversion.c629
-rw-r--r--libarchive/test/test_archive_string_conversion.txt.Z.uu2605
-rw-r--r--libarchive/test/test_archive_write_set_filter_option.c55
-rw-r--r--libarchive/test/test_archive_write_set_format_option.c67
-rw-r--r--libarchive/test/test_archive_write_set_option.c69
-rw-r--r--libarchive/test/test_archive_write_set_options.c79
-rw-r--r--libarchive/test/test_bad_fd.c10
-rw-r--r--libarchive/test/test_compat_bzip2.c10
-rw-r--r--libarchive/test/test_compat_cpio.c4
-rw-r--r--libarchive/test/test_compat_gtar.c12
-rw-r--r--libarchive/test/test_compat_gzip.c8
-rw-r--r--libarchive/test/test_compat_lzip.c141
-rw-r--r--libarchive/test/test_compat_lzip_1.tlz.uu10
-rw-r--r--libarchive/test/test_compat_lzip_2.tlz.uu9
-rw-r--r--libarchive/test/test_compat_lzma.c8
-rw-r--r--libarchive/test/test_compat_mac-1.tar.Z.uu38
-rw-r--r--libarchive/test/test_compat_mac-2.tar.Z.uu19
-rw-r--r--libarchive/test/test_compat_mac.c207
-rw-r--r--libarchive/test/test_compat_pax_libarchive_2x.c146
-rw-r--r--libarchive/test/test_compat_pax_libarchive_2x.tar.Z.uu15
-rw-r--r--libarchive/test/test_compat_solaris_pax_sparse.c188
-rw-r--r--libarchive/test/test_compat_solaris_pax_sparse_1.pax.Z.uu53
-rw-r--r--libarchive/test/test_compat_solaris_pax_sparse_2.pax.Z.uu53
-rw-r--r--libarchive/test/test_compat_solaris_tar_acl.c4
-rw-r--r--libarchive/test/test_compat_tar_hardlink.c8
-rw-r--r--libarchive/test/test_compat_xz.c8
-rw-r--r--libarchive/test/test_compat_zip.c363
-rw-r--r--libarchive/test/test_compat_zip_2.zip.uu2
-rw-r--r--libarchive/test/test_compat_zip_3.zip.uu18
-rw-r--r--libarchive/test/test_compat_zip_4.zip.uu25
-rw-r--r--libarchive/test/test_compat_zip_5.zip.uu242
-rw-r--r--libarchive/test/test_compat_zip_6.zip.uu10
-rw-r--r--libarchive/test/test_compat_zip_7.xps.uu357
-rw-r--r--libarchive/test/test_empty_write.c12
-rw-r--r--libarchive/test/test_entry.c157
-rw-r--r--libarchive/test/test_extattr_freebsd.c5
-rw-r--r--libarchive/test/test_filter_count.c72
-rw-r--r--libarchive/test/test_fuzz.c67
-rw-r--r--libarchive/test/test_fuzz.cab.uu49
-rw-r--r--libarchive/test/test_fuzz.lzh.uu152
-rw-r--r--libarchive/test/test_gnutar_filename_encoding.c414
-rw-r--r--libarchive/test/test_open_failure.c38
-rw-r--r--libarchive/test/test_open_fd.c10
-rw-r--r--libarchive/test/test_open_file.c6
-rw-r--r--libarchive/test/test_open_filename.c103
-rw-r--r--libarchive/test/test_pax_filename_encoding.c296
-rw-r--r--libarchive/test/test_read_compress_program.c12
-rw-r--r--libarchive/test/test_read_data_large.c32
-rw-r--r--libarchive/test/test_read_disk.c6
-rw-r--r--libarchive/test/test_read_disk_directory_traversals.c1060
-rw-r--r--libarchive/test/test_read_disk_entry_from_file.c8
-rw-r--r--libarchive/test/test_read_extract.c10
-rw-r--r--libarchive/test/test_read_file_nonexistent.c2
-rw-r--r--libarchive/test/test_read_format_7zip.c703
-rw-r--r--libarchive/test/test_read_format_7zip_bcj2_bzip2.7z.uu319
-rw-r--r--libarchive/test/test_read_format_7zip_bcj2_copy_1.7z.uu614
-rw-r--r--libarchive/test/test_read_format_7zip_bcj2_copy_2.7z.uu615
-rw-r--r--libarchive/test/test_read_format_7zip_bcj2_copy_lzma.7z.uu568
-rw-r--r--libarchive/test/test_read_format_7zip_bcj2_deflate.7z.uu313
-rw-r--r--libarchive/test/test_read_format_7zip_bcj2_lzma1_1.7z.uu287
-rw-r--r--libarchive/test/test_read_format_7zip_bcj2_lzma1_2.7z.uu240
-rw-r--r--libarchive/test/test_read_format_7zip_bcj2_lzma2_1.7z.uu287
-rw-r--r--libarchive/test/test_read_format_7zip_bcj2_lzma2_2.7z.uu240
-rw-r--r--libarchive/test/test_read_format_7zip_bcj_bzip2.7z.uu281
-rw-r--r--libarchive/test/test_read_format_7zip_bcj_copy.7z.uu613
-rw-r--r--libarchive/test/test_read_format_7zip_bcj_deflate.7z.uu275
-rw-r--r--libarchive/test/test_read_format_7zip_bcj_lzma1.7z.uu245
-rw-r--r--libarchive/test/test_read_format_7zip_bcj_lzma2.7z.uu245
-rw-r--r--libarchive/test/test_read_format_7zip_bzip2.7z.uu37
-rw-r--r--libarchive/test/test_read_format_7zip_copy.7z.uu7
-rw-r--r--libarchive/test/test_read_format_7zip_copy_2.7z.uu11
-rw-r--r--libarchive/test/test_read_format_7zip_deflate.7z.uu36
-rw-r--r--libarchive/test/test_read_format_7zip_delta_lzma1.7z.uu280
-rw-r--r--libarchive/test/test_read_format_7zip_delta_lzma2.7z.uu280
-rw-r--r--libarchive/test/test_read_format_7zip_empty_archive.7z.uu4
-rw-r--r--libarchive/test/test_read_format_7zip_empty_file.7z.uu5
-rw-r--r--libarchive/test/test_read_format_7zip_lzma1.7z.uu37
-rw-r--r--libarchive/test/test_read_format_7zip_lzma1_2.7z.uu8
-rw-r--r--libarchive/test/test_read_format_7zip_lzma1_lzma2.7z.uu10
-rw-r--r--libarchive/test/test_read_format_7zip_lzma2.7z.uu37
-rw-r--r--libarchive/test/test_read_format_7zip_ppmd.7z.uu235
-rw-r--r--libarchive/test/test_read_format_7zip_symbolic_name.7z.uu8
-rw-r--r--libarchive/test/test_read_format_ar.c13
-rw-r--r--libarchive/test/test_read_format_cab.c281
-rw-r--r--libarchive/test/test_read_format_cab_1.cab.uu9
-rw-r--r--libarchive/test/test_read_format_cab_2.cab.uu9
-rw-r--r--libarchive/test/test_read_format_cab_3.cab.uu10
-rw-r--r--libarchive/test/test_read_format_cab_filename.c164
-rw-r--r--libarchive/test/test_read_format_cab_filename_cp932.cab.uu7
-rw-r--r--libarchive/test/test_read_format_cpio_afio.c115
-rw-r--r--libarchive/test/test_read_format_cpio_bin.c21
-rw-r--r--libarchive/test/test_read_format_cpio_bin_Z.c9
-rw-r--r--libarchive/test/test_read_format_cpio_bin_be.c4
-rw-r--r--libarchive/test/test_read_format_cpio_bin_bz2.c6
-rw-r--r--libarchive/test/test_read_format_cpio_bin_gz.c10
-rw-r--r--libarchive/test/test_read_format_cpio_bin_lzip.c61
-rw-r--r--libarchive/test/test_read_format_cpio_bin_lzma.c8
-rw-r--r--libarchive/test/test_read_format_cpio_bin_xz.c8
-rw-r--r--libarchive/test/test_read_format_cpio_filename.c874
-rw-r--r--libarchive/test/test_read_format_cpio_filename_cp866.cpio.uu15
-rw-r--r--libarchive/test/test_read_format_cpio_filename_eucjp.cpio.uu15
-rw-r--r--libarchive/test/test_read_format_cpio_filename_koi8r.cpio.uu15
-rw-r--r--libarchive/test/test_read_format_cpio_filename_utf8_jp.cpio.uu15
-rw-r--r--libarchive/test/test_read_format_cpio_filename_utf8_ru.cpio.uu15
-rw-r--r--libarchive/test/test_read_format_cpio_odc.c10
-rw-r--r--libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.c8
-rw-r--r--libarchive/test/test_read_format_cpio_svr4_gzip.c8
-rw-r--r--libarchive/test/test_read_format_cpio_svr4_gzip_rpm.c8
-rw-r--r--libarchive/test/test_read_format_cpio_svr4c_Z.c8
-rw-r--r--libarchive/test/test_read_format_empty.c10
-rw-r--r--libarchive/test/test_read_format_gtar_filename.c512
-rw-r--r--libarchive/test/test_read_format_gtar_filename_cp866.tar.Z.uu10
-rw-r--r--libarchive/test/test_read_format_gtar_filename_eucjp.tar.Z.uu10
-rw-r--r--libarchive/test/test_read_format_gtar_filename_koi8r.tar.Z.uu10
-rw-r--r--libarchive/test/test_read_format_gtar_gz.c9
-rw-r--r--libarchive/test/test_read_format_gtar_lzma.c12
-rw-r--r--libarchive/test/test_read_format_gtar_sparse.c26
-rw-r--r--libarchive/test/test_read_format_iso_Z.c16
-rw-r--r--libarchive/test/test_read_format_iso_joliet_by_nero.iso.Z.uu64
-rw-r--r--libarchive/test/test_read_format_iso_multi_extent.c8
-rw-r--r--libarchive/test/test_read_format_iso_xorriso.c213
-rw-r--r--libarchive/test/test_read_format_iso_xorriso.iso.Z.uu61
-rw-r--r--libarchive/test/test_read_format_isojoliet_bz2.c12
-rw-r--r--libarchive/test/test_read_format_isojoliet_long.c10
-rw-r--r--libarchive/test/test_read_format_isojoliet_rr.c10
-rw-r--r--libarchive/test/test_read_format_isojoliet_versioned.c83
-rw-r--r--libarchive/test/test_read_format_isorr_bz2.c8
-rw-r--r--libarchive/test/test_read_format_isorr_ce.c8
-rw-r--r--libarchive/test/test_read_format_isorr_new_bz2.c8
-rw-r--r--libarchive/test/test_read_format_isorr_rr_moved.c8
-rw-r--r--libarchive/test/test_read_format_isozisofs_bz2.c8
-rw-r--r--libarchive/test/test_read_format_lha.c278
-rw-r--r--libarchive/test/test_read_format_lha_filename.c218
-rw-r--r--libarchive/test/test_read_format_lha_filename_cp932.lzh.uu7
-rw-r--r--libarchive/test/test_read_format_lha_header0.lzh.uu11
-rw-r--r--libarchive/test/test_read_format_lha_header1.lzh.uu13
-rw-r--r--libarchive/test/test_read_format_lha_header2.lzh.uu13
-rw-r--r--libarchive/test/test_read_format_lha_header3.lzh.uu16
-rw-r--r--libarchive/test/test_read_format_lha_lh0.lzh.uu13
-rw-r--r--libarchive/test/test_read_format_lha_lh6.lzh.uu13
-rw-r--r--libarchive/test/test_read_format_lha_lh7.lzh.uu13
-rw-r--r--libarchive/test/test_read_format_lha_withjunk.lzh.uu13
-rw-r--r--libarchive/test/test_read_format_mtree.c175
-rw-r--r--libarchive/test/test_read_format_mtree.mtree.uu11
-rw-r--r--libarchive/test/test_read_format_mtree_nomagic.mtree.uu11
-rw-r--r--libarchive/test/test_read_format_pax_bz2.c5
-rw-r--r--libarchive/test/test_read_format_rar.c867
-rw-r--r--libarchive/test/test_read_format_rar.rar.uu11
-rw-r--r--libarchive/test/test_read_format_rar_binary_data.rar.uu24041
-rw-r--r--libarchive/test/test_read_format_rar_compress_best.rar.uu274
-rw-r--r--libarchive/test/test_read_format_rar_compress_normal.rar.uu328
-rw-r--r--libarchive/test/test_read_format_rar_multi_lzss_blocks.rar.uu444
-rw-r--r--libarchive/test/test_read_format_rar_noeof.rar.uu5
-rw-r--r--libarchive/test/test_read_format_rar_ppmd_lzss_conversion.rar.uu3930
-rw-r--r--libarchive/test/test_read_format_rar_sfx.exe.uu2215
-rw-r--r--libarchive/test/test_read_format_rar_subblock.rar.uu7
-rw-r--r--libarchive/test/test_read_format_rar_unicode.rar.uu17
-rw-r--r--libarchive/test/test_read_format_rar_windows.rar.uu22
-rw-r--r--libarchive/test/test_read_format_raw.c12
-rw-r--r--libarchive/test/test_read_format_tar.c20
-rw-r--r--libarchive/test/test_read_format_tar_empty_filename.c8
-rw-r--r--libarchive/test/test_read_format_tar_filename.c363
-rw-r--r--libarchive/test/test_read_format_tar_filename_koi8r.tar.Z.uu14
-rw-r--r--libarchive/test/test_read_format_tbz.c7
-rw-r--r--libarchive/test/test_read_format_tgz.c9
-rw-r--r--libarchive/test/test_read_format_tlz.c9
-rw-r--r--libarchive/test/test_read_format_txz.c9
-rw-r--r--libarchive/test/test_read_format_tz.c9
-rw-r--r--libarchive/test/test_read_format_ustar_filename.c512
-rw-r--r--libarchive/test/test_read_format_ustar_filename_cp866.tar.Z.uu8
-rw-r--r--libarchive/test/test_read_format_ustar_filename_eucjp.tar.Z.uu9
-rw-r--r--libarchive/test/test_read_format_ustar_filename_koi8r.tar.Z.uu8
-rw-r--r--libarchive/test/test_read_format_xar.c19
-rw-r--r--libarchive/test/test_read_format_zip.c283
-rw-r--r--libarchive/test/test_read_format_zip.zip.uu3
-rw-r--r--libarchive/test/test_read_format_zip_filename.c1162
-rw-r--r--libarchive/test/test_read_format_zip_filename_cp866.zip.uu10
-rw-r--r--libarchive/test/test_read_format_zip_filename_cp932.zip.uu9
-rw-r--r--libarchive/test/test_read_format_zip_filename_koi8r.zip.uu10
-rw-r--r--libarchive/test/test_read_format_zip_filename_utf8_jp.zip.uu15
-rw-r--r--libarchive/test/test_read_format_zip_filename_utf8_ru.zip.uu11
-rw-r--r--libarchive/test/test_read_format_zip_filename_utf8_ru2.zip.uu11
-rw-r--r--libarchive/test/test_read_format_zip_length_at_end.zip.uu8
-rw-r--r--libarchive/test/test_read_format_zip_symlink.zip.uu10
-rw-r--r--libarchive/test/test_read_format_zip_ux.zip.uu7
-rw-r--r--libarchive/test/test_read_large.c17
-rw-r--r--libarchive/test/test_read_pax_truncated.c166
-rw-r--r--libarchive/test/test_read_position.c82
-rw-r--r--libarchive/test/test_read_truncated.c72
-rw-r--r--libarchive/test/test_read_truncated_filter.c132
-rw-r--r--libarchive/test/test_read_uu.c69
-rw-r--r--libarchive/test/test_sparse_basic.c462
-rw-r--r--libarchive/test/test_tar_filenames.c30
-rw-r--r--libarchive/test/test_tar_large.c37
-rw-r--r--libarchive/test/test_ustar_filename_encoding.c414
-rw-r--r--libarchive/test/test_ustar_filenames.c18
-rw-r--r--libarchive/test/test_write_compress.c37
-rw-r--r--libarchive/test/test_write_compress_bzip2.c92
-rw-r--r--libarchive/test/test_write_compress_gzip.c90
-rw-r--r--libarchive/test/test_write_compress_lzip.c247
-rw-r--r--libarchive/test/test_write_compress_lzma.c85
-rw-r--r--libarchive/test/test_write_compress_program.c20
-rw-r--r--libarchive/test/test_write_compress_xz.c84
-rw-r--r--libarchive/test/test_write_disk.c107
-rw-r--r--libarchive/test/test_write_disk_failures.c13
-rw-r--r--libarchive/test/test_write_disk_hardlink.c12
-rw-r--r--libarchive/test/test_write_disk_lookup.c150
-rw-r--r--libarchive/test/test_write_disk_perms.c10
-rw-r--r--libarchive/test/test_write_disk_secure.c8
-rw-r--r--libarchive/test/test_write_disk_sparse.c4
-rw-r--r--libarchive/test/test_write_disk_symlink.c2
-rw-r--r--libarchive/test/test_write_disk_times.c2
-rw-r--r--libarchive/test/test_write_format_7zip.c816
-rw-r--r--libarchive/test/test_write_format_ar.c51
-rw-r--r--libarchive/test/test_write_format_cpio.c122
-rw-r--r--libarchive/test/test_write_format_cpio_empty.c8
-rw-r--r--libarchive/test/test_write_format_cpio_newc.c7
-rw-r--r--libarchive/test/test_write_format_cpio_odc.c6
-rw-r--r--libarchive/test/test_write_format_gnutar.c236
-rw-r--r--libarchive/test/test_write_format_iso9660.c937
-rw-r--r--libarchive/test/test_write_format_iso9660_boot.c276
-rw-r--r--libarchive/test/test_write_format_iso9660_empty.c202
-rw-r--r--libarchive/test/test_write_format_iso9660_filename.c468
-rw-r--r--libarchive/test/test_write_format_iso9660_zisofs.c819
-rw-r--r--libarchive/test/test_write_format_mtree.c32
-rw-r--r--libarchive/test/test_write_format_mtree_fflags.c134
-rw-r--r--libarchive/test/test_write_format_pax.c59
-rw-r--r--libarchive/test/test_write_format_shar_empty.c8
-rw-r--r--libarchive/test/test_write_format_tar.c87
-rw-r--r--libarchive/test/test_write_format_tar_empty.c26
-rw-r--r--libarchive/test/test_write_format_tar_sparse.c305
-rw-r--r--libarchive/test/test_write_format_tar_ustar.c37
-rw-r--r--libarchive/test/test_write_format_xar.c312
-rw-r--r--libarchive/test/test_write_format_xar_empty.c120
-rw-r--r--libarchive/test/test_write_format_zip.c189
-rw-r--r--libarchive/test/test_write_format_zip_empty.c36
-rw-r--r--libarchive/test/test_write_format_zip_no_compression.c48
-rw-r--r--libarchive/test/test_write_open_memory.c42
-rw-r--r--libarchive/test/test_zip_filename_encoding.c543
-rw-r--r--libarchive_fe/line_reader.c60
-rw-r--r--libarchive_fe/matching.c57
-rw-r--r--libarchive_fe/pathmatch.c2
-rw-r--r--tar/CMakeLists.txt2
-rw-r--r--tar/bsdtar.151
-rw-r--r--tar/bsdtar.c130
-rw-r--r--tar/bsdtar.h17
-rw-r--r--tar/bsdtar_platform.h4
-rw-r--r--tar/bsdtar_windows.h18
-rw-r--r--tar/cmdline.c98
-rw-r--r--tar/getdate.c2
-rw-r--r--tar/read.c79
-rw-r--r--tar/subst.c53
-rw-r--r--tar/test/CMakeLists.txt23
-rw-r--r--tar/test/main.c664
-rw-r--r--tar/test/test.h99
-rw-r--r--tar/test/test_0.c14
-rw-r--r--tar/test/test_basic.c112
-rw-r--r--tar/test/test_option_C_upper.c149
-rw-r--r--tar/test/test_option_H_upper.c92
-rw-r--r--tar/test/test_option_L_upper.c92
-rw-r--r--tar/test/test_option_O_upper.c87
-rw-r--r--tar/test/test_option_T_upper.c62
-rw-r--r--tar/test/test_option_U_upper.c159
-rw-r--r--tar/test/test_option_X_upper.c145
-rw-r--r--tar/test/test_option_b.c74
-rw-r--r--tar/test/test_option_exclude.c142
-rw-r--r--tar/test/test_option_gid_gname.c88
-rw-r--r--tar/test/test_option_k.c107
-rw-r--r--tar/test/test_option_keep_newer_files.c56
-rw-r--r--tar/test/test_option_keep_newer_files.tar.Z.uu7
-rw-r--r--tar/test/test_option_n.c61
-rw-r--r--tar/test/test_option_newer_than.c75
-rw-r--r--tar/test/test_option_q.c26
-rw-r--r--tar/test/test_option_r.c95
-rw-r--r--tar/test/test_option_s.c184
-rw-r--r--tar/test/test_option_s.tar.Z.uu16
-rw-r--r--tar/test/test_option_uid_uname.c80
-rw-r--r--tar/test/test_patterns.c10
-rw-r--r--tar/test/test_print_longpath.c54
-rw-r--r--tar/test/test_print_longpath.tar.Z.uu24
-rw-r--r--tar/test/test_strip_components.c80
-rw-r--r--tar/test/test_symlink_dir.c34
-rw-r--r--tar/tree.c71
-rw-r--r--tar/util.c46
-rw-r--r--tar/write.c207
509 files changed, 133197 insertions, 14939 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2c1e86de1d73..60672ce64dce 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,11 +2,16 @@
#
PROJECT(libarchive C)
#
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6.3 FATAL_ERROR)
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/build/cmake")
if(NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${libarchive_BINARY_DIR}/bin)
endif()
+SET(CMAKE_BUILD_TYPE "Release")
+
+# On MacOS, prefer MacPorts libraries to system libraries.
+# I haven't come up with a compelling argument for this to be conditional.
+list(APPEND CMAKE_PREFIX_PATH /opt/local)
#
# Version - read from 'version' file.
@@ -21,41 +26,52 @@ STRING(REGEX REPLACE
STRING(REGEX REPLACE
"^[0-9][0-9][0-9][0-9][0-9][0-9][0-9]([a-z]?)$" "\\1" _quality ${_version})
SET(_version_number ${_major}${_minor}${_revision})
-STRING(REGEX REPLACE "[0]*([^0][0-9]*)$" "\\1" _minor ${_minor})
-STRING(REGEX REPLACE "[0]*([^0][0-9]*)$" "\\1" _revision ${_revision})
+STRING(REGEX REPLACE "[0]*([^0]*[0-9])$" "\\1" _trimmed_minor ${_minor})
+STRING(REGEX REPLACE "[0]*([^0]*[0-9])$" "\\1" _trimmed_revision ${_revision})
#
-SET(VERSION "${_major}.${_minor}.${_revision}${_quality}")
+SET(VERSION "${_major}.${_trimmed_minor}.${_trimmed_revision}${_quality}")
SET(BSDCPIO_VERSION_STRING "${VERSION}")
SET(BSDTAR_VERSION_STRING "${VERSION}")
SET(LIBARCHIVE_VERSION_NUMBER "${_version_number}")
SET(LIBARCHIVE_VERSION_STRING "${VERSION}")
-# Shared library number
-SET(SOVERSION 8)
+
+# INTERFACE_VERSION increments with every release
+# libarchive 2.7 == interface version 9 = 2 + 7
+# libarchive 2.8 == interface version 10 = 2 + 8
+# libarchive 2.9 == interface version 11 = 2 + 9
+# libarchive 3.0 == interface version 12
+# libarchive 3.x == interface version 12 + x
+math(EXPR INTERFACE_VERSION "12 + ${_minor}")
+
+# Set SOVERSION == Interface version
+# ?? Should there be more here ??
+SET(SOVERSION "${INTERFACE_VERSION}")
+
+# Especially for early development, we want to be a little
+# aggressive about diagnosing build problems; this can get
+# relaxed somewhat in final shipping versions.
+IF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
+ ADD_DEFINITIONS(-Wall)
+ SET(CMAKE_REQUIRED_FLAGS "-Wall")
+ENDIF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
# Enable CTest/CDash support
include(CTest)
-# Provide ADD_TEST_28 macro to approximate CMake 2.8 ADD_TEST(NAME).
-# TODO: Require CMake 2.8 and drop this workaround (perhaps late 2010).
-INCLUDE(AddTest28)
-
+OPTION(ENABLE_NETTLE "Enable use of Nettle" ON)
OPTION(ENABLE_OPENSSL "Enable use of OpenSSL" ON)
OPTION(ENABLE_TAR "Enable tar building" ON)
-OPTION(ENABLE_TAR_SHARED "Enable dynamic build of tar" OFF)
+OPTION(ENABLE_TAR_SHARED "Enable dynamic build of tar" FALSE)
OPTION(ENABLE_CPIO "Enable cpio building" ON)
-OPTION(ENABLE_CPIO_SHARED "Enable dynamic build of cpio" OFF)
+OPTION(ENABLE_CPIO_SHARED "Enable dynamic build of cpio" FALSE)
OPTION(ENABLE_XATTR "Enable extended attribute support" ON)
OPTION(ENABLE_ACL "Enable ACL support" ON)
+OPTION(ENABLE_ICONV "Enable iconv support" ON)
OPTION(ENABLE_TEST "Enable unit and regression tests" ON)
IF(ENABLE_TEST)
ENABLE_TESTING()
ENDIF(ENABLE_TEST)
-IF(WIN32 AND NOT CYGWIN)
- # Currently, dynamic build only.
- SET(ENABLE_TAR_SHARED ON)
- SET(ENABLE_CPIO_SHARED ON)
-ENDIF(WIN32 AND NOT CYGWIN)
IF(WIN32)
SET(_WIN32_WINNT 0x0500 CACHE INTERNAL "Setting _WIN32_WINNT to 0x0500 for Windows 2000 APIs")
@@ -63,6 +79,7 @@ IF(WIN32)
ENDIF(WIN32)
#
+INCLUDE(CheckCSourceCompiles)
INCLUDE(CheckCSourceRuns)
INCLUDE(CheckFileOffsetBits)
INCLUDE(CheckFuncs)
@@ -185,18 +202,11 @@ IF(LZMA_FOUND)
SET(HAVE_LZMA_H 1)
INCLUDE_DIRECTORIES(${LZMA_INCLUDE_DIR})
LIST(APPEND ADDITIONAL_LIBS ${LZMA_LIBRARIES})
- MARK_AS_ADVANCED(CLEAR LZMA_INCLUDE_DIR)
- MARK_AS_ADVANCED(CLEAR LZMA_LIBRARY)
ELSEIF(LZMADEC_FOUND)
SET(HAVE_LIBLZMADEC 1)
SET(HAVE_LZMADEC_H 1)
INCLUDE_DIRECTORIES(${LZMADEC_INCLUDE_DIR})
LIST(APPEND ADDITIONAL_LIBS ${LZMADEC_LIBRARIES})
- MARK_AS_ADVANCED(CLEAR LZMADEC_INCLUDE_DIR)
- MARK_AS_ADVANCED(CLEAR LZMADEC_LIBRARY)
-ELSE(LZMA_FOUND)
- MARK_AS_ADVANCED(CLEAR LZMA_INCLUDE_DIR)
- MARK_AS_ADVANCED(CLEAR LZMA_LIBRARY)
ENDIF(LZMA_FOUND)
#
@@ -218,17 +228,25 @@ LA_CHECK_INCLUDE_FILE("sys/types.h" HAVE_SYS_TYPES_H)
# Alphabetize the rest unless there's a compelling reason
LA_CHECK_INCLUDE_FILE("acl/libacl.h" HAVE_ACL_LIBACL_H)
LA_CHECK_INCLUDE_FILE("ctype.h" HAVE_CTYPE_H)
+LA_CHECK_INCLUDE_FILE("copyfile.h" HAVE_COPYFILE_H)
LA_CHECK_INCLUDE_FILE("direct.h" HAVE_DIRECT_H)
LA_CHECK_INCLUDE_FILE("dlfcn.h" HAVE_DLFCN_H)
LA_CHECK_INCLUDE_FILE("errno.h" HAVE_ERRNO_H)
LA_CHECK_INCLUDE_FILE("ext2fs/ext2_fs.h" HAVE_EXT2FS_EXT2_FS_H)
+
+CHECK_C_SOURCE_COMPILES("#include <sys/ioctl.h>
+#include <ext2fs/ext2_fs.h>
+int main(void) { return EXT2_IOC_GETFLAGS; }" HAVE_WORKING_EXT2_IOC_GETFLAGS)
+
LA_CHECK_INCLUDE_FILE("fcntl.h" HAVE_FCNTL_H)
LA_CHECK_INCLUDE_FILE("grp.h" HAVE_GRP_H)
LA_CHECK_INCLUDE_FILE("inttypes.h" HAVE_INTTYPES_H)
LA_CHECK_INCLUDE_FILE("io.h" HAVE_IO_H)
LA_CHECK_INCLUDE_FILE("langinfo.h" HAVE_LANGINFO_H)
LA_CHECK_INCLUDE_FILE("limits.h" HAVE_LIMITS_H)
+LA_CHECK_INCLUDE_FILE("linux/fiemap.h" HAVE_LINUX_FIEMAP_H)
LA_CHECK_INCLUDE_FILE("linux/fs.h" HAVE_LINUX_FS_H)
+LA_CHECK_INCLUDE_FILE("linux/magic.h" HAVE_LINUX_MAGIC_H)
LA_CHECK_INCLUDE_FILE("locale.h" HAVE_LOCALE_H)
LA_CHECK_INCLUDE_FILE("memory.h" HAVE_MEMORY_H)
LA_CHECK_INCLUDE_FILE("paths.h" HAVE_PATHS_H)
@@ -246,12 +264,17 @@ LA_CHECK_INCLUDE_FILE("sys/acl.h" HAVE_SYS_ACL_H)
LA_CHECK_INCLUDE_FILE("sys/cdefs.h" HAVE_SYS_CDEFS_H)
LA_CHECK_INCLUDE_FILE("sys/ioctl.h" HAVE_SYS_IOCTL_H)
LA_CHECK_INCLUDE_FILE("sys/mkdev.h" HAVE_SYS_MKDEV_H)
+LA_CHECK_INCLUDE_FILE("sys/mount.h" HAVE_SYS_MOUNT_H)
LA_CHECK_INCLUDE_FILE("sys/param.h" HAVE_SYS_PARAM_H)
LA_CHECK_INCLUDE_FILE("sys/poll.h" HAVE_SYS_POLL_H)
LA_CHECK_INCLUDE_FILE("sys/select.h" HAVE_SYS_SELECT_H)
LA_CHECK_INCLUDE_FILE("sys/stat.h" HAVE_SYS_STAT_H)
+LA_CHECK_INCLUDE_FILE("sys/statfs.h" HAVE_SYS_STATFS_H)
+LA_CHECK_INCLUDE_FILE("sys/statvfs.h" HAVE_SYS_STATVFS_H)
LA_CHECK_INCLUDE_FILE("sys/time.h" HAVE_SYS_TIME_H)
LA_CHECK_INCLUDE_FILE("sys/utime.h" HAVE_SYS_UTIME_H)
+LA_CHECK_INCLUDE_FILE("sys/utsname.h" HAVE_SYS_UTSNAME_H)
+LA_CHECK_INCLUDE_FILE("sys/vfs.h" HAVE_SYS_VFS_H)
LA_CHECK_INCLUDE_FILE("sys/wait.h" HAVE_SYS_WAIT_H)
LA_CHECK_INCLUDE_FILE("time.h" HAVE_TIME_H)
LA_CHECK_INCLUDE_FILE("unistd.h" HAVE_UNISTD_H)
@@ -259,17 +282,47 @@ LA_CHECK_INCLUDE_FILE("utime.h" HAVE_UTIME_H)
LA_CHECK_INCLUDE_FILE("wchar.h" HAVE_WCHAR_H)
LA_CHECK_INCLUDE_FILE("wctype.h" HAVE_WCTYPE_H)
LA_CHECK_INCLUDE_FILE("windows.h" HAVE_WINDOWS_H)
-
+# Following files need windwos.h, so we should test it after windows.h test.
+LA_CHECK_INCLUDE_FILE("wincrypt.h" HAVE_WINCRYPT_H)
+LA_CHECK_INCLUDE_FILE("winioctl.h" HAVE_WINIOCTL_H)
#
-# Some headers require extra includes when they're available.
+# Check whether use of __EXTENSIONS__ is safe.
+# We need some macro such as _GNU_SOURCE to use extension functions.
#
+SET(_INCLUDE_FILES)
+FOREACH (it ${_HEADER})
+ SET(_INCLUDE_FILES "${_INCLUDE_FILES}#include <${it}>\n")
+ENDFOREACH (it)
+
+CHECK_C_SOURCE_COMPILES(
+ "#define __EXTENSIONS__ 1
+ ${_INCLUDE_FILES}
+ int main() { return 0;}"
+ SAFE_TO_DEFINE_EXTENSIONS)
+
+#
+# Find Nettle
+#
+IF(ENABLE_NETTLE)
+ CHECK_LIBRARY_EXISTS(nettle "nettle_sha1_digest" "" NETTLE_FOUND)
+ IF(NETTLE_FOUND)
+ SET(CMAKE_REQUIRED_LIBRARIES "nettle")
+ FIND_LIBRARY(NETTLE_LIBRARY NAMES nettle)
+ LIST(APPEND ADDITIONAL_LIBS ${NETTLE_LIBRARY})
+ ELSE(NETTLE_FOUND)
+ SET(ENABLE_NETTLE OFF)
+ ENDIF(NETTLE_FOUND)
+ENDIF(ENABLE_NETTLE)
#
# Find OpenSSL
+# (Except on Mac, where OpenSSL is deprecated.)
#
-IF(ENABLE_OPENSSL)
+IF(ENABLE_OPENSSL AND NOT CMAKE_SYSTEM_NAME MATCHES "Darwin")
FIND_PACKAGE(OpenSSL)
+ELSE()
+ SET(OPENSSL_FOUND FALSE) # Override cached value
ENDIF()
# FreeBSD libmd
@@ -281,126 +334,134 @@ IF(LIBMD_FOUND)
ENDIF(LIBMD_FOUND)
#
-# How to prove that HASH functions, which have several names on various
-# platforms, can be mapped to archive_{hash name}_init,
-# archive_{hash name}_update and archive_{hash name}_final through
-# archive_hash.h
+# How to prove that CRYPTO functions, which have several names on various
+# platforms, just see if archive_crypto.c can compile and link against
+# required libraries.
#
-MACRO(CHECK_MD HASH IMPLEMENTATIONS)
+MACRO(CHECK_CRYPTO ALGORITHMS IMPLEMENTATION)
IF(HAVE_SYS_TYPES_H)
- SET(HASH_HEADER_CONFIG "#define HAVE_SYS_TYPES_H 1\n")
+ SET(CRYPTO_HEADER_CONFIG "#define HAVE_SYS_TYPES_H 1\n")
ELSE(HAVE_SYS_TYPES_H)
- SET(HASH_HEADER_CONFIG "")
+ SET(CRYPTO_HEADER_CONFIG "")
ENDIF(HAVE_SYS_TYPES_H)
- FOREACH(IMPLEMENTATION ${IMPLEMENTATIONS})
- IF(NOT DEFINED ARCHIVE_HASH_${HASH}_${IMPLEMENTATION})
- STRING(TOLOWER "${HASH}" lower_hash)
- STRING(TOUPPER "${HASH}" hash)
+ FOREACH(ALGORITHM ${ALGORITHMS})
+ STRING(TOLOWER "${ALGORITHM}" lower_algorithm)
+ STRING(TOUPPER "${ALGORITHM}" algorithm)
+ IF ("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND NOT OPENSSL_FOUND)
+ SET(ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION} FALSE)
+ ELSEIF("${IMPLEMENTATION}" MATCHES "^NETTLE$" AND NOT NETTLE_FOUND)
+ SET(ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION} FALSE)
+ ENDIF("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND NOT OPENSSL_FOUND)
- SET(HASH_REQUIRED_INCLUDES)
- SET(TRY_HASH_REQUIRED_INCLUDES
- "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_CURRENT_SOURCE_DIR}/libarchive")
- SET(HASH_REQUIRED_LIBS)
- SET(TRY_HASH_REQUIRED_LIBS)
+ IF(NOT DEFINED ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION})
+ # Probe the local implementation for whether this
+ # crypto implementation is available on this platform.
+ SET(TRY_CRYPTO_REQUIRED_INCLUDES
+ "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_CURRENT_SOURCE_DIR}/libarchive;${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp")
+ SET(TRY_CRYPTO_REQUIRED_LIBS)
IF ("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND OPENSSL_FOUND)
- SET(HASH_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
- SET(TRY_HASH_REQUIRED_INCLUDES
- "${TRY_HASH_REQUIRED_INCLUDES};${OPENSSL_INCLUDE_DIR}")
- SET(HASH_REQUIRED_LIBS ${OPENSSL_LIBRARIES})
- SET(TRY_HASH_REQUIRED_LIBS
+ SET(TRY_CRYPTO_REQUIRED_INCLUDES
+ "${TRY_CRYPTO_REQUIRED_INCLUDES};${OPENSSL_INCLUDE_DIR}")
+ SET(TRY_CRYPTO_REQUIRED_LIBS
"-DLINK_LIBRARIES:STRING=${OPENSSL_LIBRARIES}")
+ ELSEIF("${IMPLEMENTATION}" MATCHES "^NETTLE$" AND NETTLE_FOUND)
+ SET(TRY_CRYPTO_REQUIRED_LIBS
+ "-DLINK_LIBRARIES:STRING=${NETTLE_LIBRARY}")
ELSEIF("${IMPLEMENTATION}" MATCHES "^LIBMD$" AND LIBMD_FOUND)
- SET(TRY_HASH_REQUIRED_LIBS
+ SET(TRY_CRYPTO_REQUIRED_LIBS
"-DLINK_LIBRARIES:STRING=${LIBMD_LIBRARY}")
- ENDIF ("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND OPENSSL_FOUND)
+ ENDIF("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND OPENSSL_FOUND)
+
+ FILE(READ "${CMAKE_CURRENT_SOURCE_DIR}/libarchive/archive_crypto.c"
+ ARCHIVE_CRYPTO_C)
+
+ SET(SOURCE "
+#define ARCHIVE_${algorithm}_COMPILE_TEST
+#define ARCHIVE_CRYPTO_${algorithm}_${IMPLEMENTATION}
+#define PLATFORM_CONFIG_H \"check_crypto_md.h\"
- SET(SOURCE "#define ${hash}_COMPILE_TEST
-#define ARCHIVE_HASH_${hash}_${IMPLEMENTATION}
-#define __LIBARCHIVE_BUILD
-${HASH_HEADER_CONFIG}
-#include \"archive_hash.h\"
+${ARCHIVE_CRYPTO_C}
int
main(int argc, char **argv)
{
- archive_${lower_hash}_ctx ctx;
-
- archive_${lower_hash}_init(&ctx);
- archive_${lower_hash}_update(&ctx, *argv, argc);
- archive_${lower_hash}_final(&ctx, *argv);
- return 0;
+ archive_${lower_crypto}_ctx ctx;
+ archive_${lower_crypto}_init(&ctx);
+ archive_${lower_crypto}_update(&ctx, *argv, argc);
+ archive_${lower_crypto}_final(&ctx, NULL);
+ return 0;
}
")
- FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_hash_md.c" "${SOURCE}")
- MESSAGE(STATUS "Checking support for ARCHIVE_HASH_${HASH}_${IMPLEMENTATION}")
+ FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_crypto_md.h" "")
+ FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_crypto_md.c" "${SOURCE}")
+ MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION}")
- TRY_COMPILE(ARCHIVE_HASH_${HASH}_${IMPLEMENTATION}
+ TRY_COMPILE(ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION}
${CMAKE_BINARY_DIR}
- ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_hash_md.c
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_crypto_md.c
CMAKE_FLAGS
- "${TRY_HASH_REQUIRED_LIBS}"
- "${TRY_HASH_REQUIRED_INCLUDES}"
+ "${TRY_CRYPTO_REQUIRED_LIBS}"
+ "${TRY_CRYPTO_REQUIRED_INCLUDES}"
OUTPUT_VARIABLE OUTPUT)
- IF (ARCHIVE_HASH_${HASH}_${IMPLEMENTATION})
- MESSAGE(STATUS "Checking support for ARCHIVE_HASH_${HASH}_${IMPLEMENTATION} -- found")
- IF (HASH_REQUIRED_INCLUDES)
- INCLUDE_DIRECTORIES(${HASH_REQUIRED_INCLUDES})
- ENDIF (HASH_REQUIRED_INCLUDES)
- IF (HASH_REQUIRED_LIBS)
- LIST(APPEND ADDITIONAL_LIBS ${HASH_REQUIRED_LIBS})
- LIST(REMOVE_DUPLICATES ADDITIONAL_LIBS)
- ENDIF (HASH_REQUIRED_LIBS)
- BREAK()
- ENDIF (ARCHIVE_HASH_${HASH}_${IMPLEMENTATION})
-
- MESSAGE(STATUS "Checking support for ARCHIVE_HASH_${HASH}_${IMPLEMENTATION} -- not found")
- FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
- "Checking support for ARCHIVE_HASH_${HASH}_${IMPLEMENTATION} failed with the following output:\n"
+ # Inform user whether or not we found it; if not, log why we didn't.
+ IF (ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION})
+ MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION} -- found")
+ ELSE (ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION})
+ MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION} -- not found")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Checking support for ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION} failed with the following output:\n"
"${OUTPUT}\n"
"Source file was:\n${SOURCE}\n")
- ELSE(NOT DEFINED ARCHIVE_HASH_${HASH}_${IMPLEMENTATION})
- IF(ARCHIVE_HASH_${HASH}_${IMPLEMENTATION})
- BREAK()
- ENDIF(ARCHIVE_HASH_${HASH}_${IMPLEMENTATION})
- ENDIF(NOT DEFINED ARCHIVE_HASH_${HASH}_${IMPLEMENTATION})
- ENDFOREACH(IMPLEMENTATION)
-ENDMACRO(CHECK_MD HASH IMPLEMENTATIONS)
-
-#
-# HASH functions on Windows is defined at archive_windows.c, thus we do not
-# need the test what the functions can be mapped to archive_{hash name}_init,
-# archive_{hash name}_update and archive_{hash name}_final.
-# The functions on Windows use CALG_{hash name} macro to create a crypt object
-# and then we need to know what CALG_{hash name} macros is available to show
-# ARCHIVE_HASH_{hash name}_WIN macros because Windows 2000 and earlier version
+ ENDIF (ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION})
+ ENDIF(NOT DEFINED ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION})
+
+ # Add appropriate libs/includes depending on whether the implementation
+ # was found on this platform.
+ IF (ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION})
+ IF ("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND OPENSSL_FOUND)
+ INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR})
+ LIST(APPEND ADDITIONAL_LIBS ${OPENSSL_LIBRARIES})
+ LIST(REMOVE_DUPLICATES ADDITIONAL_LIBS)
+ ENDIF ("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND OPENSSL_FOUND)
+ ENDIF (ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION})
+ ENDFOREACH(ALGORITHM ${ALGORITHMS})
+ENDMACRO(CHECK_CRYPTO ALGORITHMS IMPLEMENTATION)
+
+#
+# CRYPTO functions on Windows is defined at archive_windows.c, thus we do not
+# need the test what the functions can be mapped to archive_{crypto name}_init,
+# archive_{crypto name}_update and archive_{crypto name}_final.
+# The functions on Windows use CALG_{crypto name} macro to create a crypt object
+# and then we need to know what CALG_{crypto name} macros is available to show
+# ARCHIVE_CRYPTO_{crypto name}_WIN macros because Windows 2000 and earlier version
# of Windows XP do not support SHA256, SHA384 and SHA512.
#
-MACRO(CHECK_HASH_WIN HASH_LIST)
+MACRO(CHECK_CRYPTO_WIN CRYPTO_LIST)
IF(WIN32 AND NOT CYGWIN)
- FOREACH(HASH ${HASH_LIST})
- IF(NOT DEFINED ARCHIVE_HASH_${HASH}_WIN)
- STRING(TOUPPER "${HASH}" hash)
+ FOREACH(CRYPTO ${CRYPTO_LIST})
+ IF(NOT DEFINED ARCHIVE_CRYPTO_${CRYPTO}_WIN)
+ STRING(TOUPPER "${CRYPTO}" crypto)
SET(ALGID "")
- IF ("${HASH}" MATCHES "^MD5$")
+ IF ("${CRYPTO}" MATCHES "^MD5$")
SET(ALGID "CALG_MD5")
- ENDIF ("${HASH}" MATCHES "^MD5$")
- IF ("${HASH}" MATCHES "^SHA1$")
+ ENDIF ("${CRYPTO}" MATCHES "^MD5$")
+ IF ("${CRYPTO}" MATCHES "^SHA1$")
SET(ALGID "CALG_SHA1")
- ENDIF ("${HASH}" MATCHES "^SHA1$")
- IF ("${HASH}" MATCHES "^SHA256$")
+ ENDIF ("${CRYPTO}" MATCHES "^SHA1$")
+ IF ("${CRYPTO}" MATCHES "^SHA256$")
SET(ALGID "CALG_SHA_256")
- ENDIF ("${HASH}" MATCHES "^SHA256$")
- IF ("${HASH}" MATCHES "^SHA384$")
+ ENDIF ("${CRYPTO}" MATCHES "^SHA256$")
+ IF ("${CRYPTO}" MATCHES "^SHA384$")
SET(ALGID "CALG_SHA_384")
- ENDIF ("${HASH}" MATCHES "^SHA384$")
- IF ("${HASH}" MATCHES "^SHA512$")
+ ENDIF ("${CRYPTO}" MATCHES "^SHA384$")
+ IF ("${CRYPTO}" MATCHES "^SHA512$")
SET(ALGID "CALG_SHA_512")
- ENDIF ("${HASH}" MATCHES "^SHA512$")
+ ENDIF ("${CRYPTO}" MATCHES "^SHA512$")
- SET(SOURCE "#define ${hash}_COMPILE_TEST
+ SET(SOURCE "#define ${crypto}_COMPILE_TEST
#define _WIN32_WINNT ${_WIN32_WINNT}
#define WINVER ${WINVER}
#include <windows.h>
@@ -412,45 +473,112 @@ main(int argc, char **argv)
return ${ALGID};
}
")
- SET(SOURCE_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_hash_win.c")
+ SET(SOURCE_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_crypto_win.c")
FILE(WRITE "${SOURCE_FILE}" "${SOURCE}")
- MESSAGE(STATUS "Checking support for ARCHIVE_HASH_${HASH}_WIN")
+ MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN")
- TRY_COMPILE(ARCHIVE_HASH_${HASH}_WIN
+ TRY_COMPILE(ARCHIVE_CRYPTO_${CRYPTO}_WIN
${CMAKE_BINARY_DIR}
${SOURCE_FILE}
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_CURRENT_SOURCE_DIR}/libarchive"
OUTPUT_VARIABLE OUTPUT)
- IF (ARCHIVE_HASH_${HASH}_WIN)
+ IF (ARCHIVE_CRYPTO_${CRYPTO}_WIN)
MESSAGE(STATUS
- "Checking support for ARCHIVE_HASH_${HASH}_WIN -- found")
- ELSE (ARCHIVE_HASH_${HASH}_WIN)
+ "Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN -- found")
+ ELSE (ARCHIVE_CRYPTO_${CRYPTO}_WIN)
MESSAGE(STATUS
- "Checking support for ARCHIVE_HASH_${HASH}_WIN -- not found")
+ "Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN -- not found")
FILE(APPEND
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
- "Checking support for ARCHIVE_HASH_${HASH}_WIN failed with the following output:\n"
+ "Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN failed with the following output:\n"
"${OUTPUT}\n"
"Source file was:\n${SOURCE}\n")
- ENDIF (ARCHIVE_HASH_${HASH}_WIN)
+ ENDIF (ARCHIVE_CRYPTO_${CRYPTO}_WIN)
- ENDIF(NOT DEFINED ARCHIVE_HASH_${HASH}_WIN)
- ENDFOREACH(HASH)
+ ENDIF(NOT DEFINED ARCHIVE_CRYPTO_${CRYPTO}_WIN)
+ ENDFOREACH(CRYPTO)
ENDIF(WIN32 AND NOT CYGWIN)
-ENDMACRO(CHECK_HASH_WIN HASH_LIST)
+ENDMACRO(CHECK_CRYPTO_WIN CRYPTO_LIST)
#
-# Check MD5/RMD160/SHA support
-#
-CHECK_MD(MD5 "LIBC;LIBMD;LIBSYSTEM;OPENSSL")
-CHECK_MD(RMD160 "LIBC;OPENSSL")
-CHECK_MD(SHA1 "LIBC;LIBMD;LIBSYSTEM;OPENSSL")
-CHECK_MD(SHA256 "LIBC;LIBC2;LIBC3;LIBMD;LIBSYSTEM;OPENSSL")
-CHECK_MD(SHA384 "LIBC;LIBC2;LIBC3;LIBSYSTEM;OPENSSL")
-CHECK_MD(SHA512 "LIBC;LIBC2;LIBC3;LIBMD;LIBSYSTEM;OPENSSL")
-CHECK_HASH_WIN("MD5;SHA1;SHA256;SHA384;SHA512")
+# Find iconv
+# POSIX defines the second arg as const char **
+# and requires it to be in libc. But we can accept
+# a non-const argument here and can support iconv()
+# being in libiconv.
+#
+MACRO(CHECK_ICONV LIB TRY_ICONV_CONST)
+ IF(NOT HAVE_ICONV)
+ CHECK_C_SOURCE_COMPILES(
+ "#include <stdlib.h>
+ #include <iconv.h>
+ int main() {
+ ${TRY_ICONV_CONST} char *ccp;
+ iconv_t cd = iconv_open(\"\", \"\");
+ iconv(cd, &ccp, (size_t *)0, (char **)0, (size_t *)0);
+ iconv_close(cd);
+ return 0;
+ }"
+ HAVE_ICONV_${LIB}_${TRY_ICONV_CONST})
+ IF(HAVE_ICONV_${LIB}_${TRY_ICONV_CONST})
+ SET(HAVE_ICONV true)
+ SET(ICONV_CONST ${TRY_ICONV_CONST})
+ ENDIF(HAVE_ICONV_${LIB}_${TRY_ICONV_CONST})
+ ENDIF(NOT HAVE_ICONV)
+ENDMACRO(CHECK_ICONV TRY_ICONV_CONST)
+
+IF(ENABLE_ICONV)
+ FIND_PATH(ICONV_INCLUDE_DIR iconv.h)
+ IF(ICONV_INCLUDE_DIR)
+ #SET(INCLUDES ${INCLUDES} "iconv.h")
+ SET(HAVE_ICONV_H 1)
+ INCLUDE_DIRECTORIES(${ICONV_INCLUDE_DIR})
+ SET(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR})
+ CHECK_ICONV("libc" "const")
+ CHECK_ICONV("libc" "")
+
+ # If iconv isn't in libc and we have a libiconv, try that.
+ FIND_LIBRARY(LIBICONV_PATH iconv)
+ IF(NOT HAVE_ICONV AND LIBICONV_PATH)
+ LIST(APPEND CMAKE_REQUIRED_LIBRARIES ${LIBICONV_PATH})
+ CHECK_ICONV("libiconv" "const")
+ CHECK_ICONV("libiconv" "")
+ IF (HAVE_ICONV)
+ LIST(APPEND ADDITIONAL_LIBS ${LIBICONV_PATH})
+ ENDIF(HAVE_ICONV)
+ ENDIF(NOT HAVE_ICONV AND LIBICONV_PATH)
+ ENDIF(ICONV_INCLUDE_DIR)
+ #
+ # Find locale_charset() for libiconv.
+ #
+ IF(LIBICONV_PATH)
+ CHECK_INCLUDE_FILES("localcharset.h" HAVE_LOCALCHARSET_H)
+ CHECK_FUNCTION_EXISTS_GLIBC(locale_charset HAVE_LOCALE_CHARSET)
+ IF(NOT HAVE_LOCALE_CHARSET)
+ FIND_LIBRARY(LIBCHARSET_PATH charset)
+ IF(LIBCHARSET_PATH)
+ SET(CMAKE_REQUIRED_LIBRARIES ${LIBCHARSET_PATH})
+ CHECK_FUNCTION_EXISTS_GLIBC(locale_charset HAVE_LOCALE_CHARSET)
+ IF(HAVE_LOCALE_CHARSET)
+ LIST(APPEND ADDITIONAL_LIBS ${LIBCHARSET_PATH})
+ ENDIF(HAVE_LOCALE_CHARSET)
+ ENDIF(LIBCHARSET_PATH)
+ ENDIF(NOT HAVE_LOCALE_CHARSET)
+ ENDIF(LIBICONV_PATH)
+ELSE(ENABLE_ICONV)
+ # Make sure ICONV variables are not in CACHE after ENABLE_ICONV disabled
+ # (once enabled).
+ UNSET(HAVE_LOCALE_CHARSET CACHE)
+ UNSET(HAVE_ICONV CACHE)
+ UNSET(HAVE_ICONV_libc_ CACHE)
+ UNSET(HAVE_ICONV_libc_const CACHE)
+ UNSET(HAVE_ICONV_libiconv_ CACHE)
+ UNSET(HAVE_ICONV_libiconv_const CACHE)
+ UNSET(ICONV_INCLUDE_DIR CACHE)
+ UNSET(LIBICONV_PATH CACHE)
+ENDIF(ENABLE_ICONV)
#
# Find Libxml2
@@ -461,12 +589,9 @@ IF(LIBXML2_FOUND)
LIST(APPEND ADDITIONAL_LIBS ${LIBXML2_LIBRARIES})
SET(HAVE_LIBXML2 1)
# libxml2's include files use iconv.h
- # We need a directory path of iconv.h so that it won't fail to check
- # "libxml/xmlreader.h".
- FIND_PATH(ICONV_INCLUDE_DIR iconv.h)
- INCLUDE_DIRECTORIES(${ICONV_INCLUDE_DIR})
SET(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR})
CHECK_INCLUDE_FILES("libxml/xmlreader.h" HAVE_LIBXML_XMLREADER_H)
+ CHECK_INCLUDE_FILES("libxml/xmlwriter.h" HAVE_LIBXML_XMLWRITER_H)
SET(CMAKE_REQUIRED_INCLUDES "")
ELSE(LIBXML2_FOUND)
#
@@ -484,39 +609,59 @@ ENDIF(LIBXML2_FOUND)
#
# Check functions
#
-CHECK_SYMBOL_EXISTS(CreateHardLinkA "windows.h" HAVE_CREATEHARDLINKA)
-CHECK_SYMBOL_EXISTS(CreateHardLinkW "windows.h" HAVE_CREATEHARDLINKW)
+IF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
+ #
+ # During checking functions, we should use -fno-builtin to avoid the
+ # failure of function detection which failure is an error "conflicting
+ # types for built-in function" caused by using -Werror option.
+ #
+ SET(SAVE_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
+ SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-builtin")
+ENDIF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
CHECK_SYMBOL_EXISTS(_CrtSetReportMode "crtdbg.h" HAVE__CrtSetReportMode)
CHECK_FUNCTION_EXISTS_GLIBC(chflags HAVE_CHFLAGS)
CHECK_FUNCTION_EXISTS_GLIBC(chown HAVE_CHOWN)
CHECK_FUNCTION_EXISTS_GLIBC(chroot HAVE_CHROOT)
+CHECK_FUNCTION_EXISTS_GLIBC(ctime_r HAVE_CTIME_R)
CHECK_FUNCTION_EXISTS_GLIBC(fchdir HAVE_FCHDIR)
CHECK_FUNCTION_EXISTS_GLIBC(fchflags HAVE_FCHFLAGS)
CHECK_FUNCTION_EXISTS_GLIBC(fchmod HAVE_FCHMOD)
CHECK_FUNCTION_EXISTS_GLIBC(fchown HAVE_FCHOWN)
CHECK_FUNCTION_EXISTS_GLIBC(fcntl HAVE_FCNTL)
+CHECK_FUNCTION_EXISTS_GLIBC(fdopendir HAVE_FDOPENDIR)
CHECK_FUNCTION_EXISTS_GLIBC(fork HAVE_FORK)
CHECK_FUNCTION_EXISTS_GLIBC(fstat HAVE_FSTAT)
+CHECK_FUNCTION_EXISTS_GLIBC(fstatat HAVE_FSTATAT)
+CHECK_FUNCTION_EXISTS_GLIBC(fstatfs HAVE_FSTATFS)
+CHECK_FUNCTION_EXISTS_GLIBC(fstatvfs HAVE_FSTATVFS)
CHECK_FUNCTION_EXISTS_GLIBC(ftruncate HAVE_FTRUNCATE)
CHECK_FUNCTION_EXISTS_GLIBC(futimens HAVE_FUTIMENS)
CHECK_FUNCTION_EXISTS_GLIBC(futimes HAVE_FUTIMES)
+CHECK_FUNCTION_EXISTS_GLIBC(futimesat HAVE_FUTIMESAT)
CHECK_FUNCTION_EXISTS_GLIBC(geteuid HAVE_GETEUID)
CHECK_FUNCTION_EXISTS_GLIBC(getgrgid_r HAVE_GETGRGID_R)
CHECK_FUNCTION_EXISTS_GLIBC(getgrnam_r HAVE_GETGRNAM_R)
CHECK_FUNCTION_EXISTS_GLIBC(getpwnam_r HAVE_GETPWNAM_R)
CHECK_FUNCTION_EXISTS_GLIBC(getpwuid_r HAVE_GETPWUID_R)
CHECK_FUNCTION_EXISTS_GLIBC(getpid HAVE_GETPID)
+CHECK_FUNCTION_EXISTS_GLIBC(getvfsbyname HAVE_GETVFSBYNAME)
+CHECK_FUNCTION_EXISTS_GLIBC(gmtime_r HAVE_GMTIME_R)
CHECK_FUNCTION_EXISTS_GLIBC(lchflags HAVE_LCHFLAGS)
CHECK_FUNCTION_EXISTS_GLIBC(lchmod HAVE_LCHMOD)
CHECK_FUNCTION_EXISTS_GLIBC(lchown HAVE_LCHOWN)
CHECK_FUNCTION_EXISTS_GLIBC(link HAVE_LINK)
+CHECK_FUNCTION_EXISTS_GLIBC(localtime_r HAVE_LOCALTIME_R)
CHECK_FUNCTION_EXISTS_GLIBC(lstat HAVE_LSTAT)
CHECK_FUNCTION_EXISTS_GLIBC(lutimes HAVE_LUTIMES)
+CHECK_FUNCTION_EXISTS_GLIBC(mbrtowc HAVE_MBRTOWC)
+CHECK_FUNCTION_EXISTS_GLIBC(mbsnrtowcs HAVE_MBSNRTOWCS)
CHECK_FUNCTION_EXISTS_GLIBC(memmove HAVE_MEMMOVE)
CHECK_FUNCTION_EXISTS_GLIBC(mkdir HAVE_MKDIR)
CHECK_FUNCTION_EXISTS_GLIBC(mkfifo HAVE_MKFIFO)
CHECK_FUNCTION_EXISTS_GLIBC(mknod HAVE_MKNOD)
+CHECK_FUNCTION_EXISTS_GLIBC(mkstemp HAVE_MKSTEMP)
CHECK_FUNCTION_EXISTS_GLIBC(nl_langinfo HAVE_NL_LANGINFO)
+CHECK_FUNCTION_EXISTS_GLIBC(openat HAVE_OPENAT)
CHECK_FUNCTION_EXISTS_GLIBC(pipe HAVE_PIPE)
CHECK_FUNCTION_EXISTS_GLIBC(poll HAVE_POLL)
CHECK_FUNCTION_EXISTS_GLIBC(readlink HAVE_READLINK)
@@ -524,6 +669,8 @@ CHECK_FUNCTION_EXISTS_GLIBC(select HAVE_SELECT)
CHECK_FUNCTION_EXISTS_GLIBC(setenv HAVE_SETENV)
CHECK_FUNCTION_EXISTS_GLIBC(setlocale HAVE_SETLOCALE)
CHECK_FUNCTION_EXISTS_GLIBC(sigaction HAVE_SIGACTION)
+CHECK_FUNCTION_EXISTS_GLIBC(statfs HAVE_STATFS)
+CHECK_FUNCTION_EXISTS_GLIBC(statvfs HAVE_STATVFS)
CHECK_FUNCTION_EXISTS_GLIBC(strchr HAVE_STRCHR)
CHECK_FUNCTION_EXISTS_GLIBC(strdup HAVE_STRDUP)
CHECK_FUNCTION_EXISTS_GLIBC(strerror HAVE_STRERROR)
@@ -541,19 +688,52 @@ CHECK_FUNCTION_EXISTS_GLIBC(wcrtomb HAVE_WCRTOMB)
CHECK_FUNCTION_EXISTS_GLIBC(wcscmp HAVE_WCSCMP)
CHECK_FUNCTION_EXISTS_GLIBC(wcscpy HAVE_WCSCPY)
CHECK_FUNCTION_EXISTS_GLIBC(wcslen HAVE_WCSLEN)
+CHECK_FUNCTION_EXISTS_GLIBC(wcsnrtombs HAVE_WCSNRTOMBS)
CHECK_FUNCTION_EXISTS_GLIBC(wctomb HAVE_WCTOMB)
-CHECK_SYMBOL_EXISTS(wmemcmp "wchar.h" HAVE_WMEMCMP)
-CHECK_SYMBOL_EXISTS(wmemcpy "wchar.h" HAVE_WMEMCPY)
+CHECK_FUNCTION_EXISTS_GLIBC(_ctime64_s HAVE__CTIME64_S)
+CHECK_FUNCTION_EXISTS_GLIBC(_fseeki64 HAVE__FSEEKI64)
+CHECK_FUNCTION_EXISTS_GLIBC(_get_timezone HAVE__GET_TIMEZONE)
+CHECK_FUNCTION_EXISTS_GLIBC(_localtime64_s HAVE__LOCALTIME64_S)
+CHECK_FUNCTION_EXISTS_GLIBC(_mkgmtime64 HAVE__MKGMTIME64)
SET(CMAKE_REQUIRED_LIBRARIES "")
-CHECK_SYMBOL_EXISTS(fseeko "stdio.h" HAVE_FSEEKO)
-CHECK_SYMBOL_EXISTS(strerror_r "string.h" HAVE_STRERROR_R)
-CHECK_SYMBOL_EXISTS(strftime "time.h" HAVE_STRFTIME)
-CHECK_SYMBOL_EXISTS(vprintf "stdio.h" HAVE_VPRINTF)
-CHECK_SYMBOL_EXISTS(cygwin_conv_path "sys/cygwin.h" HAVE_CYGWIN_CONV_PATH)
+CHECK_FUNCTION_EXISTS(cygwin_conv_path HAVE_CYGWIN_CONV_PATH)
+CHECK_FUNCTION_EXISTS(fseeko HAVE_FSEEKO)
+CHECK_FUNCTION_EXISTS(strerror_r HAVE_STRERROR_R)
+CHECK_FUNCTION_EXISTS(strftime HAVE_STRFTIME)
+CHECK_FUNCTION_EXISTS(vprintf HAVE_VPRINTF)
+CHECK_FUNCTION_EXISTS(wmemcmp HAVE_WMEMCMP)
+CHECK_FUNCTION_EXISTS(wmemcpy HAVE_WMEMCPY)
+
+# Restore CMAKE_REQUIRED_FLAGS
+IF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
+ SET(CMAKE_REQUIRED_FLAGS ${SAVE_CMAKE_REQUIRED_FLAGS})
+ENDIF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
-CHECK_SYMBOL_EXISTS(major "sys/mkdev.h" MAJOR_IN_MKDEV)
-CHECK_SYMBOL_EXISTS(major "sys/sysmacros.h" MAJOR_IN_SYSMACROS)
+# Make sure we have the POSIX version of readdir_r, not the
+# older 2-argument version.
+CHECK_C_SOURCE_COMPILES(
+ "#include <dirent.h>\nint main() {DIR *d = opendir(\".\"); struct dirent e,*r; return readdir_r(d,&e,&r);}"
+ HAVE_READDIR_R)
+
+
+# Only detect readlinkat() if we also have AT_FDCWD in unistd.h.
+# NOTE: linux requires fcntl.h for AT_FDCWD.
+CHECK_C_SOURCE_COMPILES(
+ "#include <fcntl.h>\n#include <unistd.h>\nint main() {char buf[10]; return readlinkat(AT_FDCWD, \"\", buf, 0);}"
+ HAVE_READLINKAT)
+
+
+# To verify major(), we need to both include the header
+# of interest and verify that the result can be linked.
+# CHECK_FUNCTION_EXISTS doesn't accept a header argument,
+# CHECK_SYMBOL_EXISTS doesn't test linkage.
+CHECK_C_SOURCE_COMPILES(
+ "#include <sys/mkdev.h>\nint main() { return major(256); }"
+ MAJOR_IN_MKDEV)
+CHECK_C_SOURCE_COMPILES(
+ "#include <sys/sysmacros.h>\nint main() { return major(256); }"
+ MAJOR_IN_SYSMACROS)
IF(HAVE_STRERROR_R)
SET(HAVE_DECL_STRERROR_R 1)
@@ -572,8 +752,6 @@ ENDIF(HAVE_INTTYPES_H)
CHECK_SYMBOL_EXISTS(EFTYPE "errno.h" HAVE_EFTYPE)
CHECK_SYMBOL_EXISTS(EILSEQ "errno.h" HAVE_EILSEQ)
CHECK_SYMBOL_EXISTS(D_MD_ORDER "langinfo.h" HAVE_D_MD_ORDER)
-CHECK_SYMBOL_EXISTS(optarg "unistd.h" HAVE_DECL_OPTARG)
-CHECK_SYMBOL_EXISTS(optind "unistd.h" HAVE_DECL_OPTIND)
CHECK_SYMBOL_EXISTS(INT64_MAX "${headers}" HAVE_DECL_INT64_MAX)
CHECK_SYMBOL_EXISTS(INT64_MIN "${headers}" HAVE_DECL_INT64_MIN)
CHECK_SYMBOL_EXISTS(UINT32_MAX "${headers}" HAVE_DECL_UINT32_MAX)
@@ -584,6 +762,16 @@ CHECK_SYMBOL_EXISTS(SSIZE_MAX "limits.h" HAVE_DECL_SSIZE_MAX)
#
# Check struct members
#
+# Check for tm_gmtoff in struct tm
+CHECK_STRUCT_MEMBER("struct tm" tm_gmtoff
+ "time.h" HAVE_STRUCT_TM_TM_GMTOFF)
+CHECK_STRUCT_MEMBER("struct tm" __tm_gmtoff
+ "time.h" HAVE_STRUCT_TM___TM_GMTOFF)
+
+# Check for f_namemax in struct statfs
+CHECK_STRUCT_MEMBER("struct statfs" f_namemax
+ "sys/param.h;sys/mount.h" HAVE_STRUCT_STATFS_F_NAMEMAX)
+
# Check for birthtime in struct stat
CHECK_STRUCT_MEMBER("struct stat" st_birthtime
"sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_BIRTHTIME)
@@ -615,13 +803,30 @@ CHECK_STRUCT_MEMBER("struct tm" tm_sec
#
# Check for integer types
#
-# XXX There must be a way to make this simpler <sigh> XXXX
#
-CHECK_TYPE_SIZE("long long int" LONG_LONG_INT)
-CHECK_TYPE_SIZE("unsigned long long" UNSIGNED_LONG_LONG)
-CHECK_TYPE_SIZE("unsigned long long int" UNSIGNED_LONG_LONG_INT)
+CHECK_TYPE_SIZE("short" SIZE_OF_SHORT)
+CHECK_TYPE_SIZE("int" SIZE_OF_INT)
+CHECK_TYPE_SIZE("long" SIZE_OF_LONG)
+CHECK_TYPE_SIZE("long long" SIZE_OF_LONG_LONG)
+
+CHECK_TYPE_SIZE("unsigned short" SIZE_OF_UNSIGNED_SHORT)
+CHECK_TYPE_SIZE("unsigned" SIZE_OF_UNSIGNED)
+CHECK_TYPE_SIZE("unsigned long" SIZE_OF_UNSIGNED_LONG)
+CHECK_TYPE_SIZE("unsigned long long" SIZE_OF_UNSIGNED_LONG_LONG)
+
+CHECK_TYPE_SIZE("__int64" __INT64)
+CHECK_TYPE_SIZE("unsigned __int64" UNSIGNED___INT64)
+
+CHECK_TYPE_SIZE(int16_t INT16_T)
+CHECK_TYPE_SIZE(int32_t INT32_T)
+CHECK_TYPE_SIZE(int64_t INT64_T)
+CHECK_TYPE_SIZE(intmax_t INTMAX_T)
+CHECK_TYPE_SIZE(uint8_t UINT8_T)
+CHECK_TYPE_SIZE(uint16_t UINT16_T)
+CHECK_TYPE_SIZE(uint32_t UINT32_T)
+CHECK_TYPE_SIZE(uint64_t UINT64_T)
+CHECK_TYPE_SIZE(uintmax_t UINTMAX_T)
-#
CHECK_TYPE_SIZE(dev_t DEV_T)
IF(NOT HAVE_DEV_T)
IF(MSVC)
@@ -647,23 +852,6 @@ IF(NOT HAVE_ID_T)
ENDIF(WIN32)
ENDIF(NOT HAVE_ID_T)
#
-CHECK_TYPE_SIZE(int32_t INT32_T)
-IF(NOT HAVE_INT32_T)
- SET(int32_t "int")
-ENDIF(NOT HAVE_INT32_T)
-#
-CHECK_TYPE_SIZE(int64_t INT64_T)
-IF(NOT HAVE_INT64_T)
- IF(WIN32)
- SET(int64_t __int64)
- ENDIF(WIN32)
-ENDIF(NOT HAVE_INT64_T)
-#
-CHECK_TYPE_SIZE(intmax_t INTMAX_T)
-IF(NOT HAVE_INTMAX_T)
- SET(intmax_t "int64_t")
-ENDIF(NOT HAVE_INTMAX_T)
-#
CHECK_TYPE_SIZE(mode_t MODE_T)
IF(NOT HAVE_MODE_T)
IF(WIN32)
@@ -714,28 +902,6 @@ IF(NOT HAVE_PID_T)
ENDIF(WIN32)
ENDIF(NOT HAVE_PID_T)
#
-CHECK_TYPE_SIZE(uint16_t UINT16_T)
-IF(NOT HAVE_UINT16_T)
- SET(uint16_t "unsigned short")
-ENDIF(NOT HAVE_UINT16_T)
-#
-CHECK_TYPE_SIZE(uint32_t UINT32_T)
-IF(NOT HAVE_UINT32_T)
- SET(uint32_t "unsigned int")
-ENDIF(NOT HAVE_UINT32_T)
-#
-CHECK_TYPE_SIZE(uint64_t UINT64_T)
-IF(NOT HAVE_UINT64_T)
- IF(WIN32)
- SET(uint64_t "unsigned __int64")
- ENDIF(WIN32)
-ENDIF(NOT HAVE_UINT64_T)
-#
-CHECK_TYPE_SIZE(uintmax_t UINTMAX_T)
-IF(NOT HAVE_UINTMAX_T)
- SET(uintmax_t "uint64_t")
-ENDIF(NOT HAVE_UINTMAX_T)
-#
CHECK_TYPE_SIZE(intptr_t INTPTR_T)
IF(NOT HAVE_INTPTR_T)
IF("${CMAKE_SIZEOF_VOID_P}" EQUAL 8)
@@ -763,8 +929,6 @@ ENDIF(HAVE_SIZEOF_WCHAR_T)
#
CHECK_FILE_OFFSET_BITS()
-
-
#
# Check for Extended Attribute libraries, headers, and functions
#
@@ -772,21 +936,57 @@ IF(ENABLE_XATTR)
LA_CHECK_INCLUDE_FILE(attr/xattr.h HAVE_ATTR_XATTR_H)
LA_CHECK_INCLUDE_FILE(sys/xattr.h HAVE_SYS_XATTR_H)
LA_CHECK_INCLUDE_FILE(sys/extattr.h HAVE_SYS_EXTATTR_H)
- CHECK_LIBRARY_EXISTS(attr "setxattr" "" HAVE_ATTR_LIB)
- IF(HAVE_ATTR_LIB)
+ CHECK_LIBRARY_EXISTS(attr "setxattr" "" HAVE_LIBATTR)
+ IF(HAVE_LIBATTR)
SET(CMAKE_REQUIRED_LIBRARIES "attr")
- ENDIF(HAVE_ATTR_LIB)
+ ENDIF(HAVE_LIBATTR)
CHECK_SYMBOL_EXISTS(EXTATTR_NAMESPACE_USER "sys/types.h;sys/extattr.h" HAVE_DECL_EXTATTR_NAMESPACE_USER)
CHECK_FUNCTION_EXISTS_GLIBC(extattr_get_file HAVE_EXTATTR_GET_FILE)
CHECK_FUNCTION_EXISTS_GLIBC(extattr_list_file HAVE_EXTATTR_LIST_FILE)
CHECK_FUNCTION_EXISTS_GLIBC(extattr_set_fd HAVE_EXTATTR_SET_FD)
CHECK_FUNCTION_EXISTS_GLIBC(extattr_set_file HAVE_EXTATTR_SET_FILE)
+ CHECK_FUNCTION_EXISTS_GLIBC(fgetxattr HAVE_FGETXATTR)
+ CHECK_FUNCTION_EXISTS_GLIBC(flistxattr HAVE_FLISTXATTR)
CHECK_FUNCTION_EXISTS_GLIBC(fsetxattr HAVE_FSETXATTR)
CHECK_FUNCTION_EXISTS_GLIBC(getxattr HAVE_GETXATTR)
CHECK_FUNCTION_EXISTS_GLIBC(lgetxattr HAVE_LGETXATTR)
CHECK_FUNCTION_EXISTS_GLIBC(listxattr HAVE_LISTXATTR)
CHECK_FUNCTION_EXISTS_GLIBC(llistxattr HAVE_LLISTXATTR)
CHECK_FUNCTION_EXISTS_GLIBC(lsetxattr HAVE_LSETXATTR)
+ CHECK_FUNCTION_EXISTS_GLIBC(fgetea HAVE_FGETEA)
+ CHECK_FUNCTION_EXISTS_GLIBC(flistea HAVE_FLISTEA)
+ CHECK_FUNCTION_EXISTS_GLIBC(fsetea HAVE_FSETEA)
+ CHECK_FUNCTION_EXISTS_GLIBC(getea HAVE_GETEA)
+ CHECK_FUNCTION_EXISTS_GLIBC(lgetea HAVE_LGETEA)
+ CHECK_FUNCTION_EXISTS_GLIBC(listea HAVE_LISTEA)
+ CHECK_FUNCTION_EXISTS_GLIBC(llistea HAVE_LLISTEA)
+ CHECK_FUNCTION_EXISTS_GLIBC(lsetea HAVE_LSETEA)
+ELSE(ENABLE_XATTR)
+ SET(HAVE_ATTR_LIB FALSE)
+ SET(HAVE_ATTR_XATTR_H FALSE)
+ SET(HAVE_DECL_EXTATTR_NAMESPACE_USER FALSE)
+ SET(HAVE_EXTATTR_GET_FILE FALSE)
+ SET(HAVE_EXTATTR_LIST_FILE FALSE)
+ SET(HAVE_EXTATTR_SET_FD FALSE)
+ SET(HAVE_EXTATTR_SET_FILE FALSE)
+ SET(HAVE_FGETEA FALSE)
+ SET(HAVE_FGETXATTR FALSE)
+ SET(HAVE_FLISTEA FALSE)
+ SET(HAVE_FLISTXATTR FALSE)
+ SET(HAVE_FSETEA FALSE)
+ SET(HAVE_FSETXATTR FALSE)
+ SET(HAVE_GETEA FALSE)
+ SET(HAVE_GETXATTR FALSE)
+ SET(HAVE_LGETEA FALSE)
+ SET(HAVE_LGETXATTR FALSE)
+ SET(HAVE_LISTEA FALSE)
+ SET(HAVE_LISTXATTR FALSE)
+ SET(HAVE_LLISTEA FALSE)
+ SET(HAVE_LLISTXATTR FALSE)
+ SET(HAVE_LSETEA FALSE)
+ SET(HAVE_LSETXATTR FALSE)
+ SET(HAVE_SYS_EXTATTR_H FALSE)
+ SET(HAVE_SYS_XATTR_H FALSE)
ENDIF(ENABLE_XATTR)
#
@@ -798,12 +998,12 @@ ENDIF(ENABLE_XATTR)
# which makes the following checks rather more complex than I would like.
#
IF(ENABLE_ACL)
- CHECK_LIBRARY_EXISTS(acl "acl_get_file" "" HAVE_ACL_LIB)
- IF(HAVE_ACL_LIB)
+ CHECK_LIBRARY_EXISTS(acl "acl_get_file" "" HAVE_LIBACL)
+ IF(HAVE_LIBACL)
SET(CMAKE_REQUIRED_LIBRARIES "acl")
FIND_LIBRARY(ACL_LIBRARY NAMES acl)
LIST(APPEND ADDITIONAL_LIBS ${ACL_LIBRARY})
- ENDIF(HAVE_ACL_LIB)
+ ENDIF(HAVE_LIBACL)
#
CHECK_FUNCTION_EXISTS_GLIBC(acl_create_entry HAVE_ACL_CREATE_ENTRY)
CHECK_FUNCTION_EXISTS_GLIBC(acl_init HAVE_ACL_INIT)
@@ -817,16 +1017,47 @@ IF(ENABLE_ACL)
# test for specific permissions in a permset.) Linux uses the obvious
# name, FreeBSD adds _np to mark it as "non-Posix extension."
# Test for both as a double-check that we really have POSIX-style ACL support.
- CHECK_SYMBOL_EXISTS(acl_get_perm "${INCLUDES}" HAVE_ACL_GET_PERM)
- CHECK_SYMBOL_EXISTS(acl_get_perm_np "${INCLUDES}" HAVE_ACL_GET_PERM_NP)
- CHECK_SYMBOL_EXISTS(acl_get_link "${INCLUDES}" HAVE_ACL_GET_LINK)
- CHECK_SYMBOL_EXISTS(acl_get_link_np "${INCLUDES}" HAVE_ACL_GET_LINK_NP)
+ CHECK_FUNCTION_EXISTS(acl_get_perm HAVE_ACL_GET_PERM)
+ CHECK_FUNCTION_EXISTS(acl_get_perm_np HAVE_ACL_GET_PERM_NP)
+ CHECK_FUNCTION_EXISTS(acl_get_link HAVE_ACL_GET_LINK)
+ CHECK_FUNCTION_EXISTS(acl_get_link_np HAVE_ACL_GET_LINK_NP)
# MacOS has an acl.h that isn't POSIX. It can be detected by
# checking for ACL_USER
CHECK_SYMBOL_EXISTS(ACL_USER "${INCLUDES}" HAVE_ACL_USER)
+ELSE(ENABLE_ACL)
+ # If someone runs cmake, then disables ACL support, we need
+ # to forcibly override the cached values for these.
+ SET(HAVE_ACL_CREATE_ENTRY FALSE)
+ SET(HAVE_ACL_GET_LINK FALSE)
+ SET(HAVE_ACL_GET_LINK_NP FALSE)
+ SET(HAVE_ACL_GET_PERM FALSE)
+ SET(HAVE_ACL_GET_PERM_NP FALSE)
+ SET(HAVE_ACL_INIT FALSE)
+ SET(HAVE_ACL_LIB FALSE)
+ SET(HAVE_ACL_PERMSET_T FALSE)
+ SET(HAVE_ACL_SET_FD FALSE)
+ SET(HAVE_ACL_SET_FD_NP FALSE)
+ SET(HAVE_ACL_SET_FILE FALSE)
+ SET(HAVE_ACL_USER FALSE)
ENDIF(ENABLE_ACL)
+#
+# Check MD5/RMD160/SHA support
+# NOTE: Crypto checks must be run last before generating config.h
+#
+CHECK_CRYPTO("MD5;RMD160;SHA1;SHA256;SHA384;SHA512" LIBC)
+CHECK_CRYPTO("SHA256;SHA384;SHA512" LIBC2)
+CHECK_CRYPTO("SHA256;SHA384;SHA512" LIBC3)
+CHECK_CRYPTO("MD5;SHA1;SHA256;SHA384;SHA512" LIBSYSTEM)
+CHECK_CRYPTO("MD5;RMD160;SHA1;SHA256;SHA384;SHA512" NETTLE)
+CHECK_CRYPTO("MD5;RMD160;SHA1;SHA256;SHA384;SHA512" OPENSSL)
+
+# Libmd has to be probed after OpenSSL.
+CHECK_CRYPTO("MD5;RMD160;SHA1;SHA256;SHA512" LIBMD)
+
+CHECK_CRYPTO_WIN("MD5;SHA1;SHA256;SHA384;SHA512")
+
# Generate "config.h" from "build/cmake/config.h.in"
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/build/cmake/config.h.in
${CMAKE_CURRENT_BINARY_DIR}/config.h)
@@ -858,8 +1089,13 @@ IF(MSVC)
ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE)
ENDIF(MSVC)
+# We need CoreServices on Mac OS.
+IF(APPLE)
+ LIST(APPEND ADDITIONAL_LIBS "-framework CoreServices")
+ENDIF(APPLE)
+
IF(ENABLE_TEST)
-ADD_CUSTOM_TARGET(run_all_tests)
+ ADD_CUSTOM_TARGET(run_all_tests)
ENDIF(ENABLE_TEST)
add_subdirectory(libarchive)
diff --git a/COPYING b/COPYING
index 9dbf49dbf21c..b25880600230 100644
--- a/COPYING
+++ b/COPYING
@@ -16,8 +16,8 @@ the actual statements in the files are controlling.
a 3-clause UC Regents copyright; please read the individual source
files for details:
libarchive/archive_entry.c
- libarchive/archive_read_support_compression_compress.c
- libarchive/archive_write_set_compression_compress.c
+ libarchive/archive_read_support_filter_compress.c
+ libarchive/archive_write_set_filter_compress.c
libarchive/mtree.5
tar/matching.c
diff --git a/INSTALL b/INSTALL
index d91cc0691f43..33c58b7ed454 100644
--- a/INSTALL
+++ b/INSTALL
@@ -19,7 +19,7 @@ configure script and other build files:
To create a distribution, please use the 'distcheck' target:
/bin/sh build/autogen.sh && ./configure && make distcheck
-On non-Unix-like systems, use the "cmake" utility (available from
+On Unix-like and non-Unix-like systems, use the "cmake" utility (available from
http://cmake.org/) to generate suitable build files for your platform.
Cmake requires the name of the directory containing CmakeLists.txt and
the "generator" to use for your build environment. For example, to
@@ -27,4 +27,9 @@ build with Xcode on Mac OS, you can use the following command:
cmake -G "Xcode" ~/libarchive-download-dir/
The result will be appropriate makefiles, solution files, or project
files that can be used with the corresponding development tool.
-See the libarchive Wiki or the cmake site for further documentation. \ No newline at end of file
+The default on Unix-like systems is to generate Makefiles, so you
+can also use cmake instead of the configure script:
+ cmake ~/libarchive-download-dir/
+ make
+ make install
+See the libarchive Wiki or the cmake site for further documentation.
diff --git a/Makefile.am b/Makefile.am
index 100ce9f34665..2fd422f4f3d1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -21,10 +21,7 @@ TESTS= libarchive_test $(bsdtar_test_programs) $(bsdcpio_test_programs)
TESTS_ENVIRONMENT= $(libarchive_TESTS_ENVIRONMENT) $(bsdtar_TESTS_ENVIRONMENT) $(bsdcpio_TESTS_ENVIRONMENT)
# Always build and test both bsdtar and bsdcpio as part of 'distcheck'
DISTCHECK_CONFIGURE_FLAGS = --enable-bsdtar --enable-bsdcpio
-# Uncommenting this line can help diagnose some errors. This is ordinarily
-# enabled in the libarchive development branch but is disabled
-# for libarchive production releases.
-#AM_CFLAGS=-Wall -Werror
+AM_CFLAGS=-Wall
PLATFORMCPPFLAGS = @PLATFORMCPPFLAGS@
AM_CPPFLAGS=$(PLATFORMCPPFLAGS)
@@ -59,12 +56,6 @@ dist-hook:
-rm -f $(distdir)/*/Makefile $(distdir)/*/*/Makefile
cd $(distdir)/doc && /bin/sh update.sh
-# Verify cmake builds as part of the acceptance
-distcheck-hook:
- mkdir $(distdir)/_build/cmtest
- cd $(distdir)/_build/cmtest && cmake ../.. && make && make test
- rm -rf $(distdir)/_build/cmtest
-
#
# Extra rules for cleanup
#
@@ -92,24 +83,36 @@ distclean-local:
include_HEADERS= libarchive/archive.h libarchive/archive_entry.h
libarchive_la_SOURCES= \
+ libarchive/archive_acl.c \
+ libarchive/archive_acl_private.h \
libarchive/archive_check_magic.c \
libarchive/archive_crc32.h \
+ libarchive/archive_crypto.c \
+ libarchive/archive_crypto_private.h \
libarchive/archive_endian.h \
libarchive/archive_entry.c \
libarchive/archive_entry.h \
libarchive/archive_entry_copy_stat.c \
libarchive/archive_entry_link_resolver.c \
+ libarchive/archive_entry_locale.h \
libarchive/archive_entry_private.h \
+ libarchive/archive_entry_sparse.c \
libarchive/archive_entry_stat.c \
libarchive/archive_entry_strmode.c \
libarchive/archive_entry_xattr.c \
- libarchive/archive_hash.h \
+ libarchive/archive_options.c \
+ libarchive/archive_options_private.h \
libarchive/archive_platform.h \
+ libarchive/archive_ppmd_private.h \
+ libarchive/archive_ppmd7.c \
+ libarchive/archive_ppmd7_private.h \
libarchive/archive_private.h \
+ libarchive/archive_rb.c \
+ libarchive/archive_rb.h \
libarchive/archive_read.c \
libarchive/archive_read_data_into_fd.c \
- libarchive/archive_read_disk.c \
libarchive/archive_read_disk_entry_from_file.c \
+ libarchive/archive_read_disk_posix.c \
libarchive/archive_read_disk_private.h \
libarchive/archive_read_disk_set_standard_lookup.c \
libarchive/archive_read_extract.c \
@@ -118,32 +121,39 @@ libarchive_la_SOURCES= \
libarchive/archive_read_open_filename.c \
libarchive/archive_read_open_memory.c \
libarchive/archive_read_private.h \
- libarchive/archive_read_support_compression_all.c \
- libarchive/archive_read_support_compression_bzip2.c \
- libarchive/archive_read_support_compression_compress.c \
- libarchive/archive_read_support_compression_gzip.c \
- libarchive/archive_read_support_compression_none.c \
- libarchive/archive_read_support_compression_program.c \
- libarchive/archive_read_support_compression_rpm.c \
- libarchive/archive_read_support_compression_uu.c \
- libarchive/archive_read_support_compression_xz.c \
+ libarchive/archive_read_set_options.c \
+ libarchive/archive_read_support_filter_all.c \
+ libarchive/archive_read_support_filter_bzip2.c \
+ libarchive/archive_read_support_filter_compress.c \
+ libarchive/archive_read_support_filter_gzip.c \
+ libarchive/archive_read_support_filter_none.c \
+ libarchive/archive_read_support_filter_program.c \
+ libarchive/archive_read_support_filter_rpm.c \
+ libarchive/archive_read_support_filter_uu.c \
+ libarchive/archive_read_support_filter_xz.c \
+ libarchive/archive_read_support_format_7zip.c \
libarchive/archive_read_support_format_all.c \
libarchive/archive_read_support_format_ar.c \
+ libarchive/archive_read_support_format_by_code.c \
+ libarchive/archive_read_support_format_cab.c \
libarchive/archive_read_support_format_cpio.c \
libarchive/archive_read_support_format_empty.c \
libarchive/archive_read_support_format_iso9660.c \
+ libarchive/archive_read_support_format_lha.c \
libarchive/archive_read_support_format_mtree.c \
+ libarchive/archive_read_support_format_rar.c \
libarchive/archive_read_support_format_raw.c \
libarchive/archive_read_support_format_tar.c \
libarchive/archive_read_support_format_xar.c \
libarchive/archive_read_support_format_zip.c \
libarchive/archive_string.c \
libarchive/archive_string.h \
+ libarchive/archive_string_composition.h \
libarchive/archive_string_sprintf.c \
libarchive/archive_util.c \
libarchive/archive_virtual.c \
libarchive/archive_write.c \
- libarchive/archive_write_disk.c \
+ libarchive/archive_write_disk_posix.c \
libarchive/archive_write_disk_private.h \
libarchive/archive_write_disk_set_standard_lookup.c \
libarchive/archive_write_open_fd.c \
@@ -151,22 +161,27 @@ libarchive_la_SOURCES= \
libarchive/archive_write_open_filename.c \
libarchive/archive_write_open_memory.c \
libarchive/archive_write_private.h \
- libarchive/archive_write_set_compression_bzip2.c \
- libarchive/archive_write_set_compression_compress.c \
- libarchive/archive_write_set_compression_gzip.c \
- libarchive/archive_write_set_compression_none.c \
- libarchive/archive_write_set_compression_program.c \
- libarchive/archive_write_set_compression_xz.c \
+ libarchive/archive_write_add_filter_bzip2.c \
+ libarchive/archive_write_add_filter_compress.c \
+ libarchive/archive_write_add_filter_gzip.c \
+ libarchive/archive_write_add_filter_none.c \
+ libarchive/archive_write_add_filter_program.c \
+ libarchive/archive_write_add_filter_xz.c \
libarchive/archive_write_set_format.c \
+ libarchive/archive_write_set_format_7zip.c \
libarchive/archive_write_set_format_ar.c \
libarchive/archive_write_set_format_by_name.c \
libarchive/archive_write_set_format_cpio.c \
libarchive/archive_write_set_format_cpio_newc.c \
+ libarchive/archive_write_set_format_iso9660.c \
libarchive/archive_write_set_format_mtree.c \
libarchive/archive_write_set_format_pax.c \
libarchive/archive_write_set_format_shar.c \
libarchive/archive_write_set_format_ustar.c \
+ libarchive/archive_write_set_format_gnutar.c \
+ libarchive/archive_write_set_format_xar.c \
libarchive/archive_write_set_format_zip.c \
+ libarchive/archive_write_set_options.c \
libarchive/config_freebsd.h \
libarchive/filter_fork.c \
libarchive/filter_fork.h
@@ -174,23 +189,34 @@ libarchive_la_SOURCES= \
if INC_WINDOWS_FILES
libarchive_la_SOURCES+= \
libarchive/archive_entry_copy_bhfi.c \
+ libarchive/archive_read_disk_windows.c \
libarchive/archive_windows.h \
libarchive/archive_windows.c \
+ libarchive/archive_write_disk_windows.c \
libarchive/filter_fork_windows.c
endif
# -no-undefined marks that libarchive doesn't rely on symbols
# defined in the application. This is mandatory for cygwin.
libarchive_la_LDFLAGS= -no-undefined -version-info $(ARCHIVE_LIBTOOL_VERSION)
+libarchive_la_LIBADD= $(LTLIBICONV)
# Manpages to install
libarchive_man_MANS= \
libarchive/archive_entry.3 \
+ libarchive/archive_entry_acl.3 \
+ libarchive/archive_entry_linkify.3 \
+ libarchive/archive_entry_paths.3 \
+ libarchive/archive_entry_perms.3 \
+ libarchive/archive_entry_stat.3 \
+ libarchive/archive_entry_time.3 \
libarchive/archive_read.3 \
libarchive/archive_read_disk.3 \
+ libarchive/archive_read_set_options.3 \
libarchive/archive_util.3 \
libarchive/archive_write.3 \
libarchive/archive_write_disk.3 \
+ libarchive/archive_write_set_options.3 \
libarchive/cpio.5 \
libarchive/libarchive.3 \
libarchive/libarchive_internals.3 \
@@ -200,7 +226,6 @@ libarchive_man_MANS= \
# Additional libarchive files to include in the distribution
libarchive_EXTRA_DIST= \
- libarchive/test/list.h \
libarchive/archive_windows.c \
libarchive/archive_windows.h \
libarchive/filter_fork_windows.c \
@@ -221,25 +246,52 @@ libarchive_test_SOURCES= \
libarchive/test/main.c \
libarchive/test/read_open_memory.c \
libarchive/test/test.h \
- libarchive/test/test_acl_basic.c \
libarchive/test/test_acl_freebsd.c \
+ libarchive/test/test_acl_nfs4.c \
libarchive/test/test_acl_pax.c \
+ libarchive/test/test_acl_posix1e.c \
libarchive/test/test_archive_api_feature.c \
+ libarchive/test/test_archive_clear_error.c \
+ libarchive/test/test_archive_crypto.c \
+ libarchive/test/test_archive_read_close_twice.c \
+ libarchive/test/test_archive_read_close_twice_open_fd.c \
+ libarchive/test/test_archive_read_close_twice_open_filename.c \
+ libarchive/test/test_archive_read_next_header_empty.c \
+ libarchive/test/test_archive_read_next_header_raw.c \
+ libarchive/test/test_archive_read_open2.c \
+ libarchive/test/test_archive_read_set_filter_option.c \
+ libarchive/test/test_archive_read_set_format_option.c \
+ libarchive/test/test_archive_read_set_option.c \
+ libarchive/test/test_archive_read_set_options.c \
+ libarchive/test/test_archive_read_support.c \
+ libarchive/test/test_archive_set_error.c \
+ libarchive/test/test_archive_string.c \
+ libarchive/test/test_archive_string_conversion.c \
+ libarchive/test/test_archive_write_set_filter_option.c \
+ libarchive/test/test_archive_write_set_format_option.c \
+ libarchive/test/test_archive_write_set_option.c \
+ libarchive/test/test_archive_write_set_options.c \
libarchive/test/test_bad_fd.c \
libarchive/test/test_compat_bzip2.c \
libarchive/test/test_compat_cpio.c \
libarchive/test/test_compat_gtar.c \
libarchive/test/test_compat_gzip.c \
+ libarchive/test/test_compat_lzip.c \
libarchive/test/test_compat_lzma.c \
+ libarchive/test/test_compat_mac.c \
+ libarchive/test/test_compat_pax_libarchive_2x.c \
libarchive/test/test_compat_solaris_tar_acl.c \
+ libarchive/test/test_compat_solaris_pax_sparse.c \
libarchive/test/test_compat_tar_hardlink.c \
libarchive/test/test_compat_xz.c \
libarchive/test/test_compat_zip.c \
libarchive/test/test_empty_write.c \
libarchive/test/test_entry.c \
+ libarchive/test/test_entry_strmode.c \
libarchive/test/test_extattr_freebsd.c \
+ libarchive/test/test_filter_count.c \
libarchive/test/test_fuzz.c \
- libarchive/test/test_entry_strmode.c \
+ libarchive/test/test_gnutar_filename_encoding.c \
libarchive/test/test_link_resolver.c \
libarchive/test/test_open_failure.c \
libarchive/test/test_open_fd.c \
@@ -249,87 +301,121 @@ libarchive_test_SOURCES= \
libarchive/test/test_read_compress_program.c \
libarchive/test/test_read_data_large.c \
libarchive/test/test_read_disk.c \
+ libarchive/test/test_read_disk_directory_traversals.c \
libarchive/test/test_read_disk_entry_from_file.c \
libarchive/test/test_read_extract.c \
libarchive/test/test_read_file_nonexistent.c \
+ libarchive/test/test_read_format_7zip.c \
libarchive/test/test_read_format_ar.c \
+ libarchive/test/test_read_format_cab.c \
+ libarchive/test/test_read_format_cab_filename.c \
+ libarchive/test/test_read_format_cpio_afio.c \
libarchive/test/test_read_format_cpio_bin.c \
libarchive/test/test_read_format_cpio_bin_Z.c \
libarchive/test/test_read_format_cpio_bin_be.c \
libarchive/test/test_read_format_cpio_bin_bz2.c \
libarchive/test/test_read_format_cpio_bin_gz.c \
+ libarchive/test/test_read_format_cpio_bin_lzip.c \
libarchive/test/test_read_format_cpio_bin_lzma.c \
libarchive/test/test_read_format_cpio_bin_xz.c \
+ libarchive/test/test_read_format_cpio_filename.c \
libarchive/test/test_read_format_cpio_odc.c \
libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.c \
libarchive/test/test_read_format_cpio_svr4_gzip.c \
libarchive/test/test_read_format_cpio_svr4_gzip_rpm.c \
libarchive/test/test_read_format_cpio_svr4c_Z.c \
libarchive/test/test_read_format_empty.c \
+ libarchive/test/test_read_format_gtar_filename.c \
libarchive/test/test_read_format_gtar_gz.c \
libarchive/test/test_read_format_gtar_lzma.c \
libarchive/test/test_read_format_gtar_sparse.c \
libarchive/test/test_read_format_iso_Z.c \
libarchive/test/test_read_format_iso_multi_extent.c \
+ libarchive/test/test_read_format_iso_xorriso.c \
libarchive/test/test_read_format_isojoliet_bz2.c \
libarchive/test/test_read_format_isojoliet_long.c \
libarchive/test/test_read_format_isojoliet_rr.c \
+ libarchive/test/test_read_format_isojoliet_versioned.c \
libarchive/test/test_read_format_isorr_bz2.c \
libarchive/test/test_read_format_isorr_ce.c \
libarchive/test/test_read_format_isorr_new_bz2.c \
libarchive/test/test_read_format_isorr_rr_moved.c \
libarchive/test/test_read_format_isozisofs_bz2.c \
+ libarchive/test/test_read_format_lha.c \
+ libarchive/test/test_read_format_lha_filename.c \
libarchive/test/test_read_format_mtree.c \
libarchive/test/test_read_format_pax_bz2.c \
+ libarchive/test/test_read_format_rar.c \
libarchive/test/test_read_format_raw.c \
libarchive/test/test_read_format_tar.c \
libarchive/test/test_read_format_tar_empty_filename.c \
+ libarchive/test/test_read_format_tar_filename.c \
libarchive/test/test_read_format_tbz.c \
libarchive/test/test_read_format_tgz.c \
libarchive/test/test_read_format_tlz.c \
libarchive/test/test_read_format_txz.c \
libarchive/test/test_read_format_tz.c \
+ libarchive/test/test_read_format_ustar_filename.c \
libarchive/test/test_read_format_xar.c \
libarchive/test/test_read_format_zip.c \
+ libarchive/test/test_read_format_zip_filename.c \
libarchive/test/test_read_large.c \
libarchive/test/test_read_pax_truncated.c \
libarchive/test/test_read_position.c \
libarchive/test/test_read_truncated.c \
+ libarchive/test/test_read_truncated_filter.c \
libarchive/test/test_read_uu.c \
+ libarchive/test/test_sparse_basic.c \
libarchive/test/test_tar_filenames.c \
libarchive/test/test_tar_large.c \
libarchive/test/test_ustar_filenames.c \
+ libarchive/test/test_ustar_filename_encoding.c \
libarchive/test/test_write_compress.c \
libarchive/test/test_write_compress_bzip2.c \
libarchive/test/test_write_compress_gzip.c \
+ libarchive/test/test_write_compress_lzip.c \
libarchive/test/test_write_compress_lzma.c \
libarchive/test/test_write_compress_program.c \
libarchive/test/test_write_compress_xz.c \
libarchive/test/test_write_disk.c \
libarchive/test/test_write_disk_failures.c \
libarchive/test/test_write_disk_hardlink.c \
+ libarchive/test/test_write_disk_lookup.c \
libarchive/test/test_write_disk_perms.c \
libarchive/test/test_write_disk_secure.c \
libarchive/test/test_write_disk_sparse.c \
libarchive/test/test_write_disk_symlink.c \
libarchive/test/test_write_disk_times.c \
+ libarchive/test/test_write_format_7zip.c \
libarchive/test/test_write_format_ar.c \
libarchive/test/test_write_format_cpio.c \
libarchive/test/test_write_format_cpio_empty.c \
- libarchive/test/test_write_format_cpio_odc.c \
libarchive/test/test_write_format_cpio_newc.c \
+ libarchive/test/test_write_format_cpio_odc.c \
+ libarchive/test/test_write_format_gnutar.c \
+ libarchive/test/test_write_format_iso9660.c \
+ libarchive/test/test_write_format_iso9660_boot.c \
+ libarchive/test/test_write_format_iso9660_empty.c \
+ libarchive/test/test_write_format_iso9660_filename.c \
+ libarchive/test/test_write_format_iso9660_zisofs.c \
libarchive/test/test_write_format_mtree.c \
+ libarchive/test/test_write_format_mtree_fflags.c \
libarchive/test/test_write_format_pax.c \
libarchive/test/test_write_format_shar_empty.c \
libarchive/test/test_write_format_tar.c \
libarchive/test/test_write_format_tar_empty.c \
+ libarchive/test/test_write_format_tar_sparse.c \
libarchive/test/test_write_format_tar_ustar.c \
+ libarchive/test/test_write_format_xar.c \
+ libarchive/test/test_write_format_xar_empty.c \
libarchive/test/test_write_format_zip.c \
libarchive/test/test_write_format_zip_empty.c \
libarchive/test/test_write_format_zip_no_compression.c \
- libarchive/test/test_write_open_memory.c
+ libarchive/test/test_write_open_memory.c \
+ libarchive/test/test_zip_filename_encoding.c
libarchive_test_CPPFLAGS= -I$(top_srcdir)/libarchive -I$(top_builddir)/libarchive/test -DLIBARCHIVE_STATIC $(PLATFORMCPPFLAGS)
+libarchive_test_LDADD= $(LTLIBICONV)
# The "list.h" file just lists all of the tests defined in all of the sources.
# Building it automatically provides a sanity-check on libarchive_test_SOURCES
@@ -340,25 +426,83 @@ libarchive/test/list.h: Makefile
libarchive_TESTS_ENVIRONMENT= LIBARCHIVE_TEST_FILES=`cd $(top_srcdir);/bin/pwd`/libarchive/test
libarchive_test_EXTRA_DIST=\
+ libarchive/test/list.h \
+ libarchive/test/test_acl_pax.tar.uu \
+ libarchive/test/test_archive_string_conversion.txt.Z.uu \
libarchive/test/test_compat_bzip2_1.tbz.uu \
libarchive/test/test_compat_bzip2_2.tbz.uu \
libarchive/test/test_compat_cpio_1.cpio.uu \
libarchive/test/test_compat_gtar_1.tar.uu \
libarchive/test/test_compat_gzip_1.tgz.uu \
libarchive/test/test_compat_gzip_2.tgz.uu \
+ libarchive/test/test_compat_lzip_1.tlz.uu \
+ libarchive/test/test_compat_lzip_2.tlz.uu \
libarchive/test/test_compat_lzma_1.tlz.uu \
libarchive/test/test_compat_lzma_2.tlz.uu \
libarchive/test/test_compat_lzma_3.tlz.uu \
+ libarchive/test/test_compat_mac-1.tar.Z.uu \
+ libarchive/test/test_compat_mac-2.tar.Z.uu \
+ libarchive/test/test_compat_pax_libarchive_2x.tar.Z.uu \
libarchive/test/test_compat_solaris_tar_acl.tar.uu \
+ libarchive/test/test_compat_solaris_pax_sparse_1.pax.Z.uu \
+ libarchive/test/test_compat_solaris_pax_sparse_2.pax.Z.uu \
libarchive/test/test_compat_tar_hardlink_1.tar.uu \
libarchive/test/test_compat_xz_1.txz.uu \
libarchive/test/test_compat_zip_1.zip.uu \
+ libarchive/test/test_compat_zip_2.zip.uu \
+ libarchive/test/test_compat_zip_3.zip.uu \
+ libarchive/test/test_compat_zip_4.zip.uu \
+ libarchive/test/test_compat_zip_5.zip.uu \
+ libarchive/test/test_compat_zip_6.zip.uu \
+ libarchive/test/test_compat_zip_7.xps.uu \
libarchive/test/test_fuzz_1.iso.Z.uu \
+ libarchive/test/test_fuzz.cab.uu \
+ libarchive/test/test_fuzz.lzh.uu \
libarchive/test/test_pax_filename_encoding.tar.uu \
+ libarchive/test/test_read_format_7zip_bcj_bzip2.7z.uu \
+ libarchive/test/test_read_format_7zip_bcj_copy.7z.uu \
+ libarchive/test/test_read_format_7zip_bcj_deflate.7z.uu \
+ libarchive/test/test_read_format_7zip_bcj_lzma1.7z.uu \
+ libarchive/test/test_read_format_7zip_bcj_lzma2.7z.uu \
+ libarchive/test/test_read_format_7zip_bcj2_bzip2.7z.uu \
+ libarchive/test/test_read_format_7zip_bcj2_copy_1.7z.uu \
+ libarchive/test/test_read_format_7zip_bcj2_copy_2.7z.uu \
+ libarchive/test/test_read_format_7zip_bcj2_copy_lzma.7z.uu \
+ libarchive/test/test_read_format_7zip_bcj2_deflate.7z.uu \
+ libarchive/test/test_read_format_7zip_bcj2_lzma1_1.7z.uu \
+ libarchive/test/test_read_format_7zip_bcj2_lzma1_2.7z.uu \
+ libarchive/test/test_read_format_7zip_bcj2_lzma2_1.7z.uu \
+ libarchive/test/test_read_format_7zip_bcj2_lzma2_2.7z.uu \
+ libarchive/test/test_read_format_7zip_bzip2.7z.uu \
+ libarchive/test/test_read_format_7zip_copy.7z.uu \
+ libarchive/test/test_read_format_7zip_copy_2.7z.uu \
+ libarchive/test/test_read_format_7zip_deflate.7z.uu \
+ libarchive/test/test_read_format_7zip_delta_lzma1.7z.uu \
+ libarchive/test/test_read_format_7zip_delta_lzma2.7z.uu \
+ libarchive/test/test_read_format_7zip_empty_archive.7z.uu \
+ libarchive/test/test_read_format_7zip_empty_file.7z.uu \
+ libarchive/test/test_read_format_7zip_lzma1.7z.uu \
+ libarchive/test/test_read_format_7zip_lzma1_2.7z.uu \
+ libarchive/test/test_read_format_7zip_lzma1_lzma2.7z.uu \
+ libarchive/test/test_read_format_7zip_lzma2.7z.uu \
+ libarchive/test/test_read_format_7zip_ppmd.7z.uu \
+ libarchive/test/test_read_format_7zip_symbolic_name.7z.uu \
libarchive/test/test_read_format_ar.ar.uu \
+ libarchive/test/test_read_format_cab_1.cab.uu \
+ libarchive/test/test_read_format_cab_2.cab.uu \
+ libarchive/test/test_read_format_cab_3.cab.uu \
+ libarchive/test/test_read_format_cab_filename_cp932.cab.uu \
libarchive/test/test_read_format_cpio_bin_be.cpio.uu \
+ libarchive/test/test_read_format_cpio_filename_cp866.cpio.uu \
+ libarchive/test/test_read_format_cpio_filename_eucjp.cpio.uu \
+ libarchive/test/test_read_format_cpio_filename_koi8r.cpio.uu \
+ libarchive/test/test_read_format_cpio_filename_utf8_jp.cpio.uu \
+ libarchive/test/test_read_format_cpio_filename_utf8_ru.cpio.uu \
libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.rpm.uu \
libarchive/test/test_read_format_cpio_svr4_gzip_rpm.rpm.uu \
+ libarchive/test/test_read_format_gtar_filename_cp866.tar.Z.uu \
+ libarchive/test/test_read_format_gtar_filename_eucjp.tar.Z.uu \
+ libarchive/test/test_read_format_gtar_filename_koi8r.tar.Z.uu \
libarchive/test/test_read_format_gtar_sparse_1_13.tar.uu \
libarchive/test/test_read_format_gtar_sparse_1_17.tar.uu \
libarchive/test/test_read_format_gtar_sparse_1_17_posix00.tar.uu \
@@ -368,6 +512,7 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_format_iso.iso.Z.uu \
libarchive/test/test_read_format_iso_2.iso.Z.uu \
libarchive/test/test_read_format_iso_joliet.iso.Z.uu \
+ libarchive/test/test_read_format_iso_joliet_by_nero.iso.Z.uu \
libarchive/test/test_read_format_iso_joliet_long.iso.Z.uu \
libarchive/test/test_read_format_iso_joliet_rockridge.iso.Z.uu \
libarchive/test/test_read_format_iso_multi_extent.iso.Z.uu \
@@ -375,12 +520,47 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_format_iso_rockridge_ce.iso.Z.uu \
libarchive/test/test_read_format_iso_rockridge_new.iso.Z.uu \
libarchive/test/test_read_format_iso_rockridge_rr_moved.iso.Z.uu\
+ libarchive/test/test_read_format_iso_xorriso.iso.Z.uu \
libarchive/test/test_read_format_iso_zisofs.iso.Z.uu \
+ libarchive/test/test_read_format_lha_filename_cp932.lzh.uu \
+ libarchive/test/test_read_format_lha_header0.lzh.uu \
+ libarchive/test/test_read_format_lha_header1.lzh.uu \
+ libarchive/test/test_read_format_lha_header2.lzh.uu \
+ libarchive/test/test_read_format_lha_header3.lzh.uu \
+ libarchive/test/test_read_format_lha_lh0.lzh.uu \
+ libarchive/test/test_read_format_lha_lh6.lzh.uu \
+ libarchive/test/test_read_format_lha_lh7.lzh.uu \
+ libarchive/test/test_read_format_lha_withjunk.lzh.uu \
libarchive/test/test_read_format_mtree.mtree.uu \
+ libarchive/test/test_read_format_mtree_nomagic.mtree.uu \
+ libarchive/test/test_read_format_rar.rar.uu \
+ libarchive/test/test_read_format_rar_binary_data.rar.uu \
+ libarchive/test/test_read_format_rar_compress_best.rar.uu \
+ libarchive/test/test_read_format_rar_compress_normal.rar.uu \
+ libarchive/test/test_read_format_rar_multi_lzss_blocks.rar.uu \
+ libarchive/test/test_read_format_rar_noeof.rar.uu \
+ libarchive/test/test_read_format_rar_ppmd_lzss_conversion.rar.uu\
+ libarchive/test/test_read_format_rar_sfx.exe.uu \
+ libarchive/test/test_read_format_rar_subblock.rar.uu \
+ libarchive/test/test_read_format_rar_unicode.rar.uu \
+ libarchive/test/test_read_format_rar_windows.rar.uu \
libarchive/test/test_read_format_raw.data.Z.uu \
libarchive/test/test_read_format_raw.data.uu \
libarchive/test/test_read_format_tar_empty_filename.tar.uu \
+ libarchive/test/test_read_format_tar_filename_koi8r.tar.Z.uu \
+ libarchive/test/test_read_format_ustar_filename_cp866.tar.Z.uu \
+ libarchive/test/test_read_format_ustar_filename_eucjp.tar.Z.uu \
+ libarchive/test/test_read_format_ustar_filename_koi8r.tar.Z.uu \
libarchive/test/test_read_format_zip.zip.uu \
+ libarchive/test/test_read_format_zip_filename_cp866.zip.uu \
+ libarchive/test/test_read_format_zip_filename_cp932.zip.uu \
+ libarchive/test/test_read_format_zip_filename_koi8r.zip.uu \
+ libarchive/test/test_read_format_zip_filename_utf8_jp.zip.uu \
+ libarchive/test/test_read_format_zip_filename_utf8_ru2.zip.uu \
+ libarchive/test/test_read_format_zip_filename_utf8_ru.zip.uu \
+ libarchive/test/test_read_format_zip_length_at_end.zip.uu \
+ libarchive/test/test_read_format_zip_symlink.zip.uu \
+ libarchive/test/test_read_format_zip_ux.zip.uu \
libarchive/test/CMakeLists.txt \
libarchive/test/README
@@ -433,7 +613,7 @@ bsdtar_ldstatic=
bsdtar_ccstatic=
endif
-bsdtar_LDADD= libarchive.la libarchive_fe.la
+bsdtar_LDADD= libarchive.la libarchive_fe.la $(LTLIBICONV)
bsdtar_CPPFLAGS= -I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe $(bsdtar_ccstatic) $(PLATFORMCPPFLAGS)
bsdtar_LDFLAGS= $(bsdtar_ldstatic)
@@ -442,8 +622,7 @@ bsdtar_EXTRA_DIST= \
tar/bsdtar_windows.h \
tar/bsdtar_windows.c \
tar/CMakeLists.txt \
- tar/config_freebsd.h \
- tar/test/list.h
+ tar/config_freebsd.h
if BUILD_BSDTAR
@@ -468,24 +647,32 @@ bsdtar_test_SOURCES= \
tar/test/test_empty_mtree.c \
tar/test/test_getdate.c \
tar/test/test_help.c \
+ tar/test/test_option_C_upper.c \
+ tar/test/test_option_H_upper.c \
+ tar/test/test_option_L_upper.c \
+ tar/test/test_option_O_upper.c \
tar/test/test_option_T_upper.c \
+ tar/test/test_option_U_upper.c \
+ tar/test/test_option_X_upper.c \
+ tar/test/test_option_b.c \
+ tar/test/test_option_exclude.c \
+ tar/test/test_option_gid_gname.c \
+ tar/test/test_option_k.c \
+ tar/test/test_option_keep_newer_files.c \
+ tar/test/test_option_n.c \
+ tar/test/test_option_newer_than.c \
tar/test/test_option_q.c \
tar/test/test_option_r.c \
tar/test/test_option_s.c \
+ tar/test/test_option_uid_uname.c \
tar/test/test_patterns.c \
+ tar/test/test_print_longpath.c \
tar/test/test_stdio.c \
tar/test/test_strip_components.c \
tar/test/test_symlink_dir.c \
tar/test/test_version.c \
tar/test/test_windows.c
-# For now, bsdtar_test uses Windows shims from tar/bsdtar_windows.*
-if INC_WINDOWS_FILES
-bsdtar_test_SOURCES+= \
- tar/bsdtar_windows.h \
- tar/bsdtar_windows.c
-endif
-
bsdtar_test_CPPFLAGS=\
-I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe \
-I$(top_srcdir)/tar -I$(top_builddir)/tar/test \
@@ -503,9 +690,13 @@ bsdtar_TESTS_ENVIRONMENT=
endif
bsdtar_test_EXTRA_DIST= \
+ tar/test/list.h \
+ tar/test/test_option_keep_newer_files.tar.Z.uu \
+ tar/test/test_option_s.tar.Z.uu \
tar/test/test_patterns_2.tar.uu \
tar/test/test_patterns_3.tar.uu \
tar/test/test_patterns_4.tar.uu \
+ tar/test/test_print_longpath.tar.Z.uu \
tar/test/CMakeLists.txt
@@ -538,12 +729,11 @@ bsdcpio_ldstatic=
bsdcpio_ccstatic=
endif
-bsdcpio_LDADD= libarchive_fe.la libarchive.la
+bsdcpio_LDADD= libarchive_fe.la libarchive.la $(LTLIBICONV)
bsdcpio_CPPFLAGS= -I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe $(bsdcpio_ccstatic) $(PLATFORMCPPFLAGS)
bsdcpio_LDFLAGS= $(bsdcpio_ldstatic)
bsdcpio_EXTRA_DIST= \
- cpio/test/list.h \
cpio/bsdcpio.1 \
cpio/cpio_windows.h \
cpio/cpio_windows.c \
@@ -573,6 +763,7 @@ bsdcpio_test_SOURCES= \
cpio/test/test_cmdline.c \
cpio/test/test_format_newc.c \
cpio/test/test_gcpio_compat.c \
+ cpio/test/test_option_0.c \
cpio/test/test_option_B_upper.c \
cpio/test/test_option_C_upper.c \
cpio/test/test_option_J_upper.c \
@@ -614,6 +805,7 @@ bsdcpio_TESTS_ENVIRONMENT=
endif
bsdcpio_test_EXTRA_DIST= \
+ cpio/test/list.h \
cpio/test/test_gcpio_compat_ref.bin.uu \
cpio/test/test_gcpio_compat_ref.crc.uu \
cpio/test/test_gcpio_compat_ref.newc.uu \
diff --git a/NEWS b/NEWS
index 4a25fe37d99b..e9811b5b4bce 100644
--- a/NEWS
+++ b/NEWS
@@ -1,27 +1,80 @@
-Feb 05, 2011: Fix issue 134: Improve handling of open failures
-Dec 06, 2010: Fix issue 119: Relax ISO verification
-Dec 06, 2010: Fix issue 121: mtree parsing
-Dec 05, 2010: Fix extraction of GNU tar 'D' directory entries
-Dec 05, 2010: Be less demanding in LZMA/XZ compression tests
-Jun 30, 2010: libarchive 2.8.4 released
-Jun 30, 2010: Improved reliability of hash function detection
-Jun 30, 2010: Fix issues on ancient FreeBSD, QNX, ancient NetBSD and Minix
-
-Mar 14, 2010: libarchive 2.8.3 released
-Mar 14, 2010: Symlink dereference fix for Linux broke the build there; corrected.
-
-Mar 14, 2010: libarchive 2.8.2 released
-Mar 12, 2010: Fix NULL deference for short self-extracting zip archives.
+Jan 10, 2012: Issue 223: Skip atime tests if atime not supported
+Jan 09, 2012: Issue 222: Errors saving sparse files to pax archives
+Jan 09, 2012: Issue 221: allow archive_*_free(NULL)
+Dec 31, 2011: Issue 212: configure script on Solaris
+Dec 30, 2011: Issue 218: empty contents extracting Zip files with bsdcpio
+Dec 30, 2011: Issue 217: fix compile warning
+Dec 30, 2011: Issue 216: truncated filenames in listings
+Dec 28, 2011: Issue 210: memory leak on Windows
+Dec 28, 2011: Issue 206: fix hardlink tests on Windows 2000
+Dec 27, 2011: Issue 208: Don't hang when using external compression
+ program on Windows
+
+Dec 24, 2011: libarchive 3.0.2 released
+Dec 23, 2011: Various fixes merged from FreeBSD
+Dec 23, 2011: Symlink support in Zip reader and writer
+Dec 23, 2011: Robustness fixes to 7Zip reader
+
+Nov 27, 2011: libarchive 3.0.1b released
+
+Nov 26, 2011: 7Zip reader
+Nov 26, 2011: Small fixes to ISO and Zip to improve robustness with corrupted input
+Nov 24, 2011: Improve streaming Zip reader's support for uncompressed entries
+Nov 20, 2011: New seeking Zip reader supports SFX Zip archives
+Nov 20, 2011: Build fixes on Windows
+
+Nov 13, 2011: libarchive 3.0.0a released
+
+Nov 06, 2011: Update shared-library version calculations for libarchive 3.x
+Sep 04, 2011: Fix tar -s; follow GNU tar for controlling hardlink/symlink substitutions
+Aug 18, 2011: Fix reading ISO images built by NetBSD's mkisofs
+Aug 15, 2011: Old archive_read_support_compression_XXX functions are deprecated and
+ will disappear in libarchive 4.0.
+Jun 26, 2011: RAR reader
+Jun 16, 2011: Add tar:compat-2x option to emulate broken libarchive 2.x
+ handling of pax UTF-8 headers
+Apr 25, 2011: Refactor read_open() into a collection of single-item setters;
+ support the old interfaces as wrappers
+Apr 12, 2011: Split disk writer into separate POSIX and Windows implementations
+Apr 10, 2011: Improvements to character translations on Windows.
+Mar 30, 2011: More work to return errors instead of calling abort()
+Mar 23, 2011: Add charset option to many writers to control MBCS filenames
+Mar 17, 2011: Overhauled support for per-format extension options
+Mar 17, 2011: Track character set used for mbcs strings, support
+ translating to/from user-specified locale
+Mar 09, 2011: Recognize mtree files without requiring a signature
+Mar 06, 2011: Use iconv to convert to/from Unicode instead of making bad
+ assumptions about the C90 character set translation functions
+Feb 17, 2011: Fixes for AIX, TRU64, and other platforms
+Dec 22, 2010: CAB reader
+Dec 20, 2010: LHA/LZH reader
+Jul 03, 2010: minitar example demonstrates archive_read_disk directory traversal
+Jun 29, 2010: Many improvements to ISO reader compatibility
+Jun 26, 2010: Use larger buffers when copy files into an archive
+Jun 18, 2010: Reimplement Mac OS extensions in libarchive
+Jun 09, 2010: archive_read_disk now supports traversals
+May 28, 2010: XAR writer
+May 16, 2010: Fix ^T handling; don't exit on interrupted reads and writes
+May 09, 2010: Improved detection of platform-specific crypto support
+May 04, 2010: lzip read and write filters
+May 01, 2010: New options: tar --gid --gname --uid --uname
+Apr 28, 2010: Use Red-black tree for ISO reader/writer to improve performance
+Apr 17, 2010: Minimal writer for legacy GNU tar format
Mar 12, 2010: Don't dereference symlinks on Linux when reading ACLs.
-Mar 07, 2010: Better detection of SHA2 support for old OpenSSL versions.
-Mar 07, 2010: Fix parsing of input files for bsdtar -T.
-Mar 07, 2010: Do not leak setup_xattr into the global namespace.
-
-Mar 06, 2010: libarchive 2.8.1 released
Mar 06, 2010: Fix build when an older libarchive is already installed
-Mar 03, 2010: Use O_BINARY opening files in bsdtar
-Mar 02, 2010: Include missing archive_crc32.h
-Mar 01, 2010: Correctly include iconv.h required by libxml2.
+Feb 28, 2010: Relax handling of state failures; misuse by clients now generally
+ results in a sticky ARCHIVE_FATAL rather than a visit to abort()
+Feb 25, 2010: ISO writer
+Feb 21, 2010: Split many man pages into smaller chunks.
+Feb 21, 2010: Performance: Cheat on block sizes when reading archives from disk.
+Feb 21, 2010: Use int64_t instead of off_t, dev_t, ino_t, uid_t, and gid_t
+Feb 20, 2010: Document new ACL functions.
+Feb 19, 2010: Support multiple write filters
+Feb 07, 2010: Remove some legacy libarchive 1.x APIs
+Feb 04, 2010: Read afio headers
+Feb 02, 2010: Archive sparse files compatibly with GNU tar
+Feb 01, 2010: Integrate Apple extensions for Mac OS extended attributes into bsdtar
+Jan 31, 2010: Support cpio -V
Feb 04, 2010: libarchive 2.8.0 released
Jan 17, 2010: Fix error handling for 'echo nonexistent | cpio -o'
diff --git a/README b/README
index 03e47e85497e..69238386f6e1 100644
--- a/README
+++ b/README
@@ -13,8 +13,6 @@ This distribution bundle includes the following components:
essentially the same functionality
* examples: Some small example programs that you may find useful.
* examples/minitar: a compact sample demonstrating use of libarchive.
- I use this for testing link pollution; it should produce a very
- small executable file on most systems.
* contrib: Various items sent to me by third parties;
please contact the authors with any questions.
@@ -51,16 +49,11 @@ The manual pages above are provided in the 'doc' directory in
a number of different formats.
You should also read the copious comments in "archive.h" and the
-source code for the sample programs for more details. Please let me
+source code for the sample programs for more details. Please let us
know about any errors or omissions you find.
-Currently, the library automatically detects and reads the following:
- * gzip compression
- * bzip2 compression
- * compress/LZW compression
- * lzma and xz compression
- * GNU tar format (including GNU long filenames, long link names, and
- sparse files)
+Currently, the library automatically detects and reads the following fomats:
+ * GNU tar format (including GNU long filenames, long link names, and sparse files)
* Solaris 9 extended tar format (including ACLs)
* Old V7 tar archives
* POSIX ustar
@@ -73,22 +66,40 @@ Currently, the library automatically detects and reads the following:
* ZIP archives (with uncompressed or "deflate" compressed entries)
* GNU and BSD 'ar' archives
* 'mtree' format
-
-The library can write:
+ * Microsoft CAB format
+ * LHA and LZH archives
+ * RAR archives
+ * XAR archives
+
+The library also detects and handles any of the following before evaluating the archive:
+ * uuencoded files
+ * files with RPM wrapper
* gzip compression
* bzip2 compression
* compress/LZW compression
- * lzma and xz compression
+ * lzma, lzip, and xz compression
+
+The library can create archives in any of the following formats:
* POSIX ustar
* POSIX pax interchange format
* "restricted" pax format, which will create ustar archives except for
entries that require pax extensions (for long filenames, ACLs, etc).
+ * Old GNU tar format
* POSIX octet-oriented cpio
* SVR4 "newc" cpio
* shar archives
* ZIP archives (with uncompressed or "deflate" compressed entries)
* GNU and BSD 'ar' archives
* 'mtree' format
+ * ISO9660 format
+ * XAR archives
+
+When creating archives, the result can be filtered with any of the following:
+ * uuencode
+ * gzip compression
+ * bzip2 compression
+ * compress/LZW compression
+ * lzma, lzip, and xz compression
Notes about the library architecture:
diff --git a/build/autoconf/config.rpath b/build/autoconf/config.rpath
new file mode 100755
index 000000000000..8a8cf8edec5e
--- /dev/null
+++ b/build/autoconf/config.rpath
@@ -0,0 +1,696 @@
+#! /bin/sh
+#
+# NOTE: This file was brought from
+# http://git.savannah.gnu.org/cgit/gnulib.git/plain/build-aux/config.rpath
+# You should sometimes check if the file is updated and bring it to
+# our trunk and copy this note to the top of that file.
+#
+# Output a system dependent set of variables, describing how to set the
+# run time search path of shared libraries in an executable.
+#
+# Copyright 1996-2011 Free Software Foundation, Inc.
+# Taken from GNU libtool, 2001
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# The first argument passed to this file is the canonical host specification,
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld
+# should be set by the caller.
+#
+# The set of defined variables is at the end of this script.
+
+# Known limitations:
+# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer
+# than 256 bytes, otherwise the compiler driver will dump core. The only
+# known workaround is to choose shorter directory names for the build
+# directory and/or the installation directory.
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+shrext=.so
+
+host="$1"
+host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+# Code taken from libtool.m4's _LT_CC_BASENAME.
+
+for cc_temp in $CC""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
+
+# Code taken from libtool.m4's _LT_COMPILER_PIC.
+
+wl=
+if test "$GCC" = yes; then
+ wl='-Wl,'
+else
+ case "$host_os" in
+ aix*)
+ wl='-Wl,'
+ ;;
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ wl='-Wl,'
+ ;;
+ irix5* | irix6* | nonstopux*)
+ wl='-Wl,'
+ ;;
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ ecc*)
+ wl='-Wl,'
+ ;;
+ icc* | ifort*)
+ wl='-Wl,'
+ ;;
+ lf95*)
+ wl='-Wl,'
+ ;;
+ nagfor*)
+ wl='-Wl,-Wl,,'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+ wl='-Wl,'
+ ;;
+ ccc*)
+ wl='-Wl,'
+ ;;
+ xl* | bgxl* | bgf* | mpixl*)
+ wl='-Wl,'
+ ;;
+ como)
+ wl='-lopt='
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ F* | *Sun*Fortran*)
+ wl=
+ ;;
+ *Sun\ C*)
+ wl='-Wl,'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ newsos6)
+ ;;
+ *nto* | *qnx*)
+ ;;
+ osf3* | osf4* | osf5*)
+ wl='-Wl,'
+ ;;
+ rdos*)
+ ;;
+ solaris*)
+ case $cc_basename in
+ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ wl='-Qoption ld '
+ ;;
+ *)
+ wl='-Wl,'
+ ;;
+ esac
+ ;;
+ sunos4*)
+ wl='-Qoption ld '
+ ;;
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ wl='-Wl,'
+ ;;
+ sysv4*MP*)
+ ;;
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ wl='-Wl,'
+ ;;
+ unicos*)
+ wl='-Wl,'
+ ;;
+ uts4*)
+ ;;
+ esac
+fi
+
+# Code taken from libtool.m4's _LT_LINKER_SHLIBS.
+
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+
+case "$host_os" in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes; then
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ # Unlike libtool, we use -rpath here, not --rpath, since the documented
+ # option of GNU ld is called -rpath, not --rpath.
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ case "$host_os" in
+ aix[3-9]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ ld_shlibs=no
+ fi
+ ;;
+ amigaos*)
+ case "$host_cpu" in
+ powerpc)
+ ;;
+ m68k)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+ beos*)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ cygwin* | mingw* | pw32* | cegcc*)
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ haiku*)
+ ;;
+ interix[3-9]*)
+ hardcode_direct=no
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ netbsd*)
+ ;;
+ solaris*)
+ if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+ ld_shlibs=no
+ ;;
+ *)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ ;;
+ sunos4*)
+ hardcode_direct=yes
+ ;;
+ *)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ if test "$ld_shlibs" = no; then
+ hardcode_libdir_flag_spec=
+ fi
+else
+ case "$host_os" in
+ aix3*)
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test "$GCC" = yes; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+ aix[4-9]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ else
+ aix_use_runtimelinking=no
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ ;;
+ esac
+ fi
+ hardcode_direct=yes
+ hardcode_libdir_separator=':'
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" && \
+ strings "$collect2name" | grep resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ ;;
+ esac
+ fi
+ # Begin _LT_AC_SYS_LIBPATH_AIX.
+ echo 'int main () { return 0; }' > conftest.c
+ ${CC} ${LDFLAGS} conftest.c -o conftest
+ aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
+}'`
+ if test -z "$aix_libpath"; then
+ aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
+}'`
+ fi
+ if test -z "$aix_libpath"; then
+ aix_libpath="/usr/lib:/lib"
+ fi
+ rm -f conftest.c conftest
+ # End _LT_AC_SYS_LIBPATH_AIX.
+ if test "$aix_use_runtimelinking" = yes; then
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ else
+ if test "$host_cpu" = ia64; then
+ hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+ else
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ fi
+ fi
+ ;;
+ amigaos*)
+ case "$host_cpu" in
+ powerpc)
+ ;;
+ m68k)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+ bsdi[45]*)
+ ;;
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec=' '
+ libext=lib
+ ;;
+ darwin* | rhapsody*)
+ hardcode_direct=no
+ if { case $cc_basename in ifort*) true;; *) test "$GCC" = yes;; esac; }; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ dgux*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ ;;
+ freebsd2.2*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ ;;
+ freebsd2*)
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ ;;
+ freebsd* | dragonfly*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ ;;
+ hpux9*)
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ hpux10*)
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ fi
+ ;;
+ hpux11*)
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct=no
+ ;;
+ *)
+ hardcode_direct=yes
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ esac
+ fi
+ ;;
+ irix5* | irix6* | nonstopux*)
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+ netbsd*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ ;;
+ newsos6)
+ hardcode_direct=yes
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+ *nto* | *qnx*)
+ ;;
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ hardcode_direct=yes
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ else
+ case "$host_os" in
+ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ *)
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ osf3*)
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+ osf4* | osf5*)
+ if test "$GCC" = yes; then
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ else
+ # Both cc and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec='-rpath $libdir'
+ fi
+ hardcode_libdir_separator=:
+ ;;
+ solaris*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ sunos4*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ ;;
+ sysv4)
+ case $host_vendor in
+ sni)
+ hardcode_direct=yes # is this really true???
+ ;;
+ siemens)
+ hardcode_direct=no
+ ;;
+ motorola)
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ ;;
+ sysv4.3*)
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ ld_shlibs=yes
+ fi
+ ;;
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+ ;;
+ sysv5* | sco3.2v5* | sco5v6*)
+ hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+ hardcode_libdir_separator=':'
+ ;;
+ uts4*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ ;;
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+fi
+
+# Check dynamic linker characteristics
+# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER.
+# Unlike libtool.m4, here we don't care about _all_ names of the library, but
+# only about the one the linker finds when passed -lNAME. This is the last
+# element of library_names_spec in libtool.m4, or possibly two of them if the
+# linker has special search rules.
+library_names_spec= # the last element of library_names_spec in libtool.m4
+libname_spec='lib$name'
+case "$host_os" in
+ aix3*)
+ library_names_spec='$libname.a'
+ ;;
+ aix[4-9]*)
+ library_names_spec='$libname$shrext'
+ ;;
+ amigaos*)
+ case "$host_cpu" in
+ powerpc*)
+ library_names_spec='$libname$shrext' ;;
+ m68k)
+ library_names_spec='$libname.a' ;;
+ esac
+ ;;
+ beos*)
+ library_names_spec='$libname$shrext'
+ ;;
+ bsdi[45]*)
+ library_names_spec='$libname$shrext'
+ ;;
+ cygwin* | mingw* | pw32* | cegcc*)
+ shrext=.dll
+ library_names_spec='$libname.dll.a $libname.lib'
+ ;;
+ darwin* | rhapsody*)
+ shrext=.dylib
+ library_names_spec='$libname$shrext'
+ ;;
+ dgux*)
+ library_names_spec='$libname$shrext'
+ ;;
+ freebsd* | dragonfly*)
+ case "$host_os" in
+ freebsd[123]*)
+ library_names_spec='$libname$shrext$versuffix' ;;
+ *)
+ library_names_spec='$libname$shrext' ;;
+ esac
+ ;;
+ gnu*)
+ library_names_spec='$libname$shrext'
+ ;;
+ haiku*)
+ library_names_spec='$libname$shrext'
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ case $host_cpu in
+ ia64*)
+ shrext=.so
+ ;;
+ hppa*64*)
+ shrext=.sl
+ ;;
+ *)
+ shrext=.sl
+ ;;
+ esac
+ library_names_spec='$libname$shrext'
+ ;;
+ interix[3-9]*)
+ library_names_spec='$libname$shrext'
+ ;;
+ irix5* | irix6* | nonstopux*)
+ library_names_spec='$libname$shrext'
+ case "$host_os" in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;;
+ *) libsuff= shlibsuff= ;;
+ esac
+ ;;
+ esac
+ ;;
+ linux*oldld* | linux*aout* | linux*coff*)
+ ;;
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ library_names_spec='$libname$shrext'
+ ;;
+ knetbsd*-gnu)
+ library_names_spec='$libname$shrext'
+ ;;
+ netbsd*)
+ library_names_spec='$libname$shrext'
+ ;;
+ newsos6)
+ library_names_spec='$libname$shrext'
+ ;;
+ *nto* | *qnx*)
+ library_names_spec='$libname$shrext'
+ ;;
+ openbsd*)
+ library_names_spec='$libname$shrext$versuffix'
+ ;;
+ os2*)
+ libname_spec='$name'
+ shrext=.dll
+ library_names_spec='$libname.a'
+ ;;
+ osf3* | osf4* | osf5*)
+ library_names_spec='$libname$shrext'
+ ;;
+ rdos*)
+ ;;
+ solaris*)
+ library_names_spec='$libname$shrext'
+ ;;
+ sunos4*)
+ library_names_spec='$libname$shrext$versuffix'
+ ;;
+ sysv4 | sysv4.3*)
+ library_names_spec='$libname$shrext'
+ ;;
+ sysv4*MP*)
+ library_names_spec='$libname$shrext'
+ ;;
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ library_names_spec='$libname$shrext'
+ ;;
+ tpf*)
+ library_names_spec='$libname$shrext'
+ ;;
+ uts4*)
+ library_names_spec='$libname$shrext'
+ ;;
+esac
+
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"`
+shlibext=`echo "$shrext" | sed -e 's,^\.,,'`
+escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
+escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
+escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
+
+LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
+
+# How to pass a linker flag through the compiler.
+wl="$escaped_wl"
+
+# Static library suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally "so").
+shlibext="$shlibext"
+
+# Format of library name prefix.
+libname_spec="$escaped_libname_spec"
+
+# Library names that the linker finds when passed -lNAME.
+library_names_spec="$escaped_library_names_spec"
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec"
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator="$hardcode_libdir_separator"
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct="$hardcode_direct"
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L="$hardcode_minus_L"
+
+EOF
diff --git a/build/autoconf/iconv.m4 b/build/autoconf/iconv.m4
new file mode 100644
index 000000000000..98fcd64d313c
--- /dev/null
+++ b/build/autoconf/iconv.m4
@@ -0,0 +1,268 @@
+# iconv.m4 serial 18 (gettext-0.18.2)
+dnl Copyright (C) 2000-2002, 2007-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+AC_DEFUN([AM_ICONV_LINKFLAGS_BODY],
+[
+ dnl Prerequisites of AC_LIB_LINKFLAGS_BODY.
+ AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+ AC_REQUIRE([AC_LIB_RPATH])
+
+ dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
+ dnl accordingly.
+ AC_LIB_LINKFLAGS_BODY([iconv])
+])
+
+AC_DEFUN([AM_ICONV_LINK],
+[
+ dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and
+ dnl those with the standalone portable GNU libiconv installed).
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+
+ dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
+ dnl accordingly.
+ AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY])
+
+ dnl Add $INCICONV to CPPFLAGS before performing the following checks,
+ dnl because if the user has installed libiconv and not disabled its use
+ dnl via --without-libiconv-prefix, he wants to use it. The first
+ dnl AC_LINK_IFELSE will then fail, the second AC_LINK_IFELSE will succeed.
+ am_save_CPPFLAGS="$CPPFLAGS"
+ AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV])
+
+ AC_CACHE_CHECK([for iconv], [am_cv_func_iconv], [
+ am_cv_func_iconv="no, consider installing GNU libiconv"
+ am_cv_lib_iconv=no
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[
+#include <stdlib.h>
+#include <iconv.h>
+ ]],
+ [[iconv_t cd = iconv_open("","");
+ iconv(cd,NULL,NULL,NULL,NULL);
+ iconv_close(cd);]])],
+ [am_cv_func_iconv=yes])
+ if test "$am_cv_func_iconv" != yes; then
+ am_save_LIBS="$LIBS"
+ LIBS="$LIBS $LIBICONV"
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[
+#include <stdlib.h>
+#include <iconv.h>
+ ]],
+ [[iconv_t cd = iconv_open("","");
+ iconv(cd,NULL,NULL,NULL,NULL);
+ iconv_close(cd);]])],
+ [am_cv_lib_iconv=yes]
+ [am_cv_func_iconv=yes])
+ LIBS="$am_save_LIBS"
+ fi
+ ])
+ if test "$am_cv_func_iconv" = yes; then
+ AC_CACHE_CHECK([for working iconv], [am_cv_func_iconv_works], [
+ dnl This tests against bugs in AIX 5.1, AIX 6.1..7.1, HP-UX 11.11,
+ dnl Solaris 10.
+ am_save_LIBS="$LIBS"
+ if test $am_cv_lib_iconv = yes; then
+ LIBS="$LIBS $LIBICONV"
+ fi
+ AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([[
+#include <iconv.h>
+#include <string.h>
+int main ()
+{
+ int result = 0;
+ /* Test against AIX 5.1 bug: Failures are not distinguishable from successful
+ returns. */
+ {
+ iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8");
+ if (cd_utf8_to_88591 != (iconv_t)(-1))
+ {
+ static const char input[] = "\342\202\254"; /* EURO SIGN */
+ char buf[10];
+ const char *inptr = input;
+ size_t inbytesleft = strlen (input);
+ char *outptr = buf;
+ size_t outbytesleft = sizeof (buf);
+ size_t res = iconv (cd_utf8_to_88591,
+ (char **) &inptr, &inbytesleft,
+ &outptr, &outbytesleft);
+ if (res == 0)
+ result |= 1;
+ iconv_close (cd_utf8_to_88591);
+ }
+ }
+ /* Test against Solaris 10 bug: Failures are not distinguishable from
+ successful returns. */
+ {
+ iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646");
+ if (cd_ascii_to_88591 != (iconv_t)(-1))
+ {
+ static const char input[] = "\263";
+ char buf[10];
+ const char *inptr = input;
+ size_t inbytesleft = strlen (input);
+ char *outptr = buf;
+ size_t outbytesleft = sizeof (buf);
+ size_t res = iconv (cd_ascii_to_88591,
+ (char **) &inptr, &inbytesleft,
+ &outptr, &outbytesleft);
+ if (res == 0)
+ result |= 2;
+ iconv_close (cd_ascii_to_88591);
+ }
+ }
+ /* Test against AIX 6.1..7.1 bug: Buffer overrun. */
+ {
+ iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1");
+ if (cd_88591_to_utf8 != (iconv_t)(-1))
+ {
+ static const char input[] = "\304";
+ static char buf[2] = { (char)0xDE, (char)0xAD };
+ const char *inptr = input;
+ size_t inbytesleft = 1;
+ char *outptr = buf;
+ size_t outbytesleft = 1;
+ size_t res = iconv (cd_88591_to_utf8,
+ (char **) &inptr, &inbytesleft,
+ &outptr, &outbytesleft);
+ if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD)
+ result |= 4;
+ iconv_close (cd_88591_to_utf8);
+ }
+ }
+#if 0 /* This bug could be worked around by the caller. */
+ /* Test against HP-UX 11.11 bug: Positive return value instead of 0. */
+ {
+ iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591");
+ if (cd_88591_to_utf8 != (iconv_t)(-1))
+ {
+ static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
+ char buf[50];
+ const char *inptr = input;
+ size_t inbytesleft = strlen (input);
+ char *outptr = buf;
+ size_t outbytesleft = sizeof (buf);
+ size_t res = iconv (cd_88591_to_utf8,
+ (char **) &inptr, &inbytesleft,
+ &outptr, &outbytesleft);
+ if ((int)res > 0)
+ result |= 8;
+ iconv_close (cd_88591_to_utf8);
+ }
+ }
+#endif
+ /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is
+ provided. */
+ if (/* Try standardized names. */
+ iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1)
+ /* Try IRIX, OSF/1 names. */
+ && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1)
+ /* Try AIX names. */
+ && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1)
+ /* Try HP-UX names. */
+ && iconv_open ("utf8", "eucJP") == (iconv_t)(-1))
+ result |= 16;
+ return result;
+}]])],
+ [am_cv_func_iconv_works=yes],
+ [am_cv_func_iconv_works=no],
+ [
+changequote(,)dnl
+ case "$host_os" in
+ aix* | hpux*) am_cv_func_iconv_works="guessing no" ;;
+ *) am_cv_func_iconv_works="guessing yes" ;;
+ esac
+changequote([,])dnl
+ ])
+ LIBS="$am_save_LIBS"
+ ])
+ case "$am_cv_func_iconv_works" in
+ *no) am_func_iconv=no am_cv_lib_iconv=no ;;
+ *) am_func_iconv=yes ;;
+ esac
+ else
+ am_func_iconv=no am_cv_lib_iconv=no
+ fi
+ if test "$am_func_iconv" = yes; then
+ AC_DEFINE([HAVE_ICONV], [1],
+ [Define if you have the iconv() function and it works.])
+ fi
+ if test "$am_cv_lib_iconv" = yes; then
+ AC_MSG_CHECKING([how to link with libiconv])
+ AC_MSG_RESULT([$LIBICONV])
+ else
+ dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV
+ dnl either.
+ CPPFLAGS="$am_save_CPPFLAGS"
+ LIBICONV=
+ LTLIBICONV=
+ fi
+ AC_SUBST([LIBICONV])
+ AC_SUBST([LTLIBICONV])
+])
+
+dnl Define AM_ICONV using AC_DEFUN_ONCE for Autoconf >= 2.64, in order to
+dnl avoid warnings like
+dnl "warning: AC_REQUIRE: `AM_ICONV' was expanded before it was required".
+dnl This is tricky because of the way 'aclocal' is implemented:
+dnl - It requires defining an auxiliary macro whose name ends in AC_DEFUN.
+dnl Otherwise aclocal's initial scan pass would miss the macro definition.
+dnl - It requires a line break inside the AC_DEFUN_ONCE and AC_DEFUN expansions.
+dnl Otherwise aclocal would emit many "Use of uninitialized value $1"
+dnl warnings.
+m4_define([gl_iconv_AC_DEFUN],
+ m4_version_prereq([2.64],
+ [[AC_DEFUN_ONCE(
+ [$1], [$2])]],
+ [m4_ifdef([gl_00GNULIB],
+ [[AC_DEFUN_ONCE(
+ [$1], [$2])]],
+ [[AC_DEFUN(
+ [$1], [$2])]])]))
+gl_iconv_AC_DEFUN([AM_ICONV],
+[
+ AM_ICONV_LINK
+ if test "$am_cv_func_iconv" = yes; then
+ AC_MSG_CHECKING([for iconv declaration])
+ AC_CACHE_VAL([am_cv_proto_iconv], [
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[
+#include <stdlib.h>
+#include <iconv.h>
+extern
+#ifdef __cplusplus
+"C"
+#endif
+#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus)
+size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
+#else
+size_t iconv();
+#endif
+ ]],
+ [[]])],
+ [am_cv_proto_iconv_arg1=""],
+ [am_cv_proto_iconv_arg1="const"])
+ am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"])
+ am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'`
+ AC_MSG_RESULT([
+ $am_cv_proto_iconv])
+ AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1],
+ [Define as const if the declaration of iconv() needs const.])
+ dnl Also substitute ICONV_CONST in the gnulib generated <iconv.h>.
+ m4_ifdef([gl_ICONV_H_DEFAULTS],
+ [AC_REQUIRE([gl_ICONV_H_DEFAULTS])
+ if test -n "$am_cv_proto_iconv_arg1"; then
+ ICONV_CONST="const"
+ fi
+ ])
+ fi
+])
diff --git a/build/autoconf/lib-ld.m4 b/build/autoconf/lib-ld.m4
new file mode 100644
index 000000000000..ae003f7c5943
--- /dev/null
+++ b/build/autoconf/lib-ld.m4
@@ -0,0 +1,109 @@
+# lib-ld.m4 serial 5 (gettext-0.18.2)
+dnl Copyright (C) 1996-2003, 2009-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl Subroutines of libtool.m4,
+dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision
+dnl with libtool.m4.
+
+dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no.
+AC_DEFUN([AC_LIB_PROG_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], [acl_cv_prog_gnu_ld],
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ acl_cv_prog_gnu_ld=yes ;;
+*)
+ acl_cv_prog_gnu_ld=no ;;
+esac])
+with_gnu_ld=$acl_cv_prog_gnu_ld
+])
+
+dnl From libtool-1.4. Sets the variable LD.
+AC_DEFUN([AC_LIB_PROG_LD],
+[AC_ARG_WITH([gnu-ld],
+[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]],
+test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+# Prepare PATH_SEPARATOR.
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which
+ # contains only /bin. Note that ksh looks also at the FPATH variable,
+ # so we have to set that as well for the test.
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \
+ && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \
+ || PATH_SEPARATOR=';'
+ }
+fi
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by GCC])
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [[\\/]* | [A-Za-z]:[\\/]*)]
+ [re_direlt='/[^/][^/]*/\.\./']
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL([acl_cv_path_LD],
+[if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ acl_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in
+ *GNU* | *'with BFD'*)
+ test "$with_gnu_ld" != no && break ;;
+ *)
+ test "$with_gnu_ld" != yes && break ;;
+ esac
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ acl_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$acl_cv_path_LD"
+if test -n "$LD"; then
+ AC_MSG_RESULT([$LD])
+else
+ AC_MSG_RESULT([no])
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_LIB_PROG_LD_GNU
+])
diff --git a/build/autoconf/lib-link.m4 b/build/autoconf/lib-link.m4
new file mode 100644
index 000000000000..e7c9ba9d3d71
--- /dev/null
+++ b/build/autoconf/lib-link.m4
@@ -0,0 +1,777 @@
+# lib-link.m4 serial 26 (gettext-0.18.2)
+dnl Copyright (C) 2001-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+AC_PREREQ([2.54])
+
+dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and
+dnl the libraries corresponding to explicit and implicit dependencies.
+dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and
+dnl augments the CPPFLAGS variable.
+dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname
+dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
+AC_DEFUN([AC_LIB_LINKFLAGS],
+[
+ AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+ AC_REQUIRE([AC_LIB_RPATH])
+ pushdef([Name],[m4_translit([$1],[./+-], [____])])
+ pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
+ AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [
+ AC_LIB_LINKFLAGS_BODY([$1], [$2])
+ ac_cv_lib[]Name[]_libs="$LIB[]NAME"
+ ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME"
+ ac_cv_lib[]Name[]_cppflags="$INC[]NAME"
+ ac_cv_lib[]Name[]_prefix="$LIB[]NAME[]_PREFIX"
+ ])
+ LIB[]NAME="$ac_cv_lib[]Name[]_libs"
+ LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs"
+ INC[]NAME="$ac_cv_lib[]Name[]_cppflags"
+ LIB[]NAME[]_PREFIX="$ac_cv_lib[]Name[]_prefix"
+ AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
+ AC_SUBST([LIB]NAME)
+ AC_SUBST([LTLIB]NAME)
+ AC_SUBST([LIB]NAME[_PREFIX])
+ dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the
+ dnl results of this search when this library appears as a dependency.
+ HAVE_LIB[]NAME=yes
+ popdef([NAME])
+ popdef([Name])
+])
+
+dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode, [missing-message])
+dnl searches for libname and the libraries corresponding to explicit and
+dnl implicit dependencies, together with the specified include files and
+dnl the ability to compile and link the specified testcode. The missing-message
+dnl defaults to 'no' and may contain additional hints for the user.
+dnl If found, it sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME}
+dnl and LTLIB${NAME} variables and augments the CPPFLAGS variable, and
+dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs
+dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty.
+dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname
+dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
+AC_DEFUN([AC_LIB_HAVE_LINKFLAGS],
+[
+ AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+ AC_REQUIRE([AC_LIB_RPATH])
+ pushdef([Name],[m4_translit([$1],[./+-], [____])])
+ pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
+
+ dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME
+ dnl accordingly.
+ AC_LIB_LINKFLAGS_BODY([$1], [$2])
+
+ dnl Add $INC[]NAME to CPPFLAGS before performing the following checks,
+ dnl because if the user has installed lib[]Name and not disabled its use
+ dnl via --without-lib[]Name-prefix, he wants to use it.
+ ac_save_CPPFLAGS="$CPPFLAGS"
+ AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
+
+ AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [
+ ac_save_LIBS="$LIBS"
+ dnl If $LIB[]NAME contains some -l options, add it to the end of LIBS,
+ dnl because these -l options might require -L options that are present in
+ dnl LIBS. -l options benefit only from the -L options listed before it.
+ dnl Otherwise, add it to the front of LIBS, because it may be a static
+ dnl library that depends on another static library that is present in LIBS.
+ dnl Static libraries benefit only from the static libraries listed after
+ dnl it.
+ case " $LIB[]NAME" in
+ *" -l"*) LIBS="$LIBS $LIB[]NAME" ;;
+ *) LIBS="$LIB[]NAME $LIBS" ;;
+ esac
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM([[$3]], [[$4]])],
+ [ac_cv_lib[]Name=yes],
+ [ac_cv_lib[]Name='m4_if([$5], [], [no], [[$5]])'])
+ LIBS="$ac_save_LIBS"
+ ])
+ if test "$ac_cv_lib[]Name" = yes; then
+ HAVE_LIB[]NAME=yes
+ AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the lib][$1 library.])
+ AC_MSG_CHECKING([how to link with lib[]$1])
+ AC_MSG_RESULT([$LIB[]NAME])
+ else
+ HAVE_LIB[]NAME=no
+ dnl If $LIB[]NAME didn't lead to a usable library, we don't need
+ dnl $INC[]NAME either.
+ CPPFLAGS="$ac_save_CPPFLAGS"
+ LIB[]NAME=
+ LTLIB[]NAME=
+ LIB[]NAME[]_PREFIX=
+ fi
+ AC_SUBST([HAVE_LIB]NAME)
+ AC_SUBST([LIB]NAME)
+ AC_SUBST([LTLIB]NAME)
+ AC_SUBST([LIB]NAME[_PREFIX])
+ popdef([NAME])
+ popdef([Name])
+])
+
+dnl Determine the platform dependent parameters needed to use rpath:
+dnl acl_libext,
+dnl acl_shlibext,
+dnl acl_libname_spec,
+dnl acl_library_names_spec,
+dnl acl_hardcode_libdir_flag_spec,
+dnl acl_hardcode_libdir_separator,
+dnl acl_hardcode_direct,
+dnl acl_hardcode_minus_L.
+AC_DEFUN([AC_LIB_RPATH],
+[
+ dnl Tell automake >= 1.10 to complain if config.rpath is missing.
+ m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])])
+ AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS
+ AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host
+ AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir
+ AC_CACHE_CHECK([for shared library run path origin], [acl_cv_rpath], [
+ CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \
+ ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh
+ . ./conftest.sh
+ rm -f ./conftest.sh
+ acl_cv_rpath=done
+ ])
+ wl="$acl_cv_wl"
+ acl_libext="$acl_cv_libext"
+ acl_shlibext="$acl_cv_shlibext"
+ acl_libname_spec="$acl_cv_libname_spec"
+ acl_library_names_spec="$acl_cv_library_names_spec"
+ acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec"
+ acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator"
+ acl_hardcode_direct="$acl_cv_hardcode_direct"
+ acl_hardcode_minus_L="$acl_cv_hardcode_minus_L"
+ dnl Determine whether the user wants rpath handling at all.
+ AC_ARG_ENABLE([rpath],
+ [ --disable-rpath do not hardcode runtime library paths],
+ :, enable_rpath=yes)
+])
+
+dnl AC_LIB_FROMPACKAGE(name, package)
+dnl declares that libname comes from the given package. The configure file
+dnl will then not have a --with-libname-prefix option but a
+dnl --with-package-prefix option. Several libraries can come from the same
+dnl package. This declaration must occur before an AC_LIB_LINKFLAGS or similar
+dnl macro call that searches for libname.
+AC_DEFUN([AC_LIB_FROMPACKAGE],
+[
+ pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
+ define([acl_frompackage_]NAME, [$2])
+ popdef([NAME])
+ pushdef([PACK],[$2])
+ pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
+ define([acl_libsinpackage_]PACKUP,
+ m4_ifdef([acl_libsinpackage_]PACKUP, [m4_defn([acl_libsinpackage_]PACKUP)[, ]],)[lib$1])
+ popdef([PACKUP])
+ popdef([PACK])
+])
+
+dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and
+dnl the libraries corresponding to explicit and implicit dependencies.
+dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables.
+dnl Also, sets the LIB${NAME}_PREFIX variable to nonempty if libname was found
+dnl in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
+AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
+[
+ AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
+ pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
+ pushdef([PACK],[m4_ifdef([acl_frompackage_]NAME, [acl_frompackage_]NAME, lib[$1])])
+ pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
+ pushdef([PACKLIBS],[m4_ifdef([acl_frompackage_]NAME, [acl_libsinpackage_]PACKUP, lib[$1])])
+ dnl Autoconf >= 2.61 supports dots in --with options.
+ pushdef([P_A_C_K],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[m4_translit(PACK,[.],[_])],PACK)])
+ dnl By default, look in $includedir and $libdir.
+ use_additional=yes
+ AC_LIB_WITH_FINAL_PREFIX([
+ eval additional_includedir=\"$includedir\"
+ eval additional_libdir=\"$libdir\"
+ ])
+ AC_ARG_WITH(P_A_C_K[-prefix],
+[[ --with-]]P_A_C_K[[-prefix[=DIR] search for ]PACKLIBS[ in DIR/include and DIR/lib
+ --without-]]P_A_C_K[[-prefix don't search for ]PACKLIBS[ in includedir and libdir]],
+[
+ if test "X$withval" = "Xno"; then
+ use_additional=no
+ else
+ if test "X$withval" = "X"; then
+ AC_LIB_WITH_FINAL_PREFIX([
+ eval additional_includedir=\"$includedir\"
+ eval additional_libdir=\"$libdir\"
+ ])
+ else
+ additional_includedir="$withval/include"
+ additional_libdir="$withval/$acl_libdirstem"
+ if test "$acl_libdirstem2" != "$acl_libdirstem" \
+ && ! test -d "$withval/$acl_libdirstem"; then
+ additional_libdir="$withval/$acl_libdirstem2"
+ fi
+ fi
+ fi
+])
+ dnl Search the library and its dependencies in $additional_libdir and
+ dnl $LDFLAGS. Using breadth-first-seach.
+ LIB[]NAME=
+ LTLIB[]NAME=
+ INC[]NAME=
+ LIB[]NAME[]_PREFIX=
+ dnl HAVE_LIB${NAME} is an indicator that LIB${NAME}, LTLIB${NAME} have been
+ dnl computed. So it has to be reset here.
+ HAVE_LIB[]NAME=
+ rpathdirs=
+ ltrpathdirs=
+ names_already_handled=
+ names_next_round='$1 $2'
+ while test -n "$names_next_round"; do
+ names_this_round="$names_next_round"
+ names_next_round=
+ for name in $names_this_round; do
+ already_handled=
+ for n in $names_already_handled; do
+ if test "$n" = "$name"; then
+ already_handled=yes
+ break
+ fi
+ done
+ if test -z "$already_handled"; then
+ names_already_handled="$names_already_handled $name"
+ dnl See if it was already located by an earlier AC_LIB_LINKFLAGS
+ dnl or AC_LIB_HAVE_LINKFLAGS call.
+ uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'`
+ eval value=\"\$HAVE_LIB$uppername\"
+ if test -n "$value"; then
+ if test "$value" = yes; then
+ eval value=\"\$LIB$uppername\"
+ test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value"
+ eval value=\"\$LTLIB$uppername\"
+ test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value"
+ else
+ dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined
+ dnl that this library doesn't exist. So just drop it.
+ :
+ fi
+ else
+ dnl Search the library lib$name in $additional_libdir and $LDFLAGS
+ dnl and the already constructed $LIBNAME/$LTLIBNAME.
+ found_dir=
+ found_la=
+ found_so=
+ found_a=
+ eval libname=\"$acl_libname_spec\" # typically: libname=lib$name
+ if test -n "$acl_shlibext"; then
+ shrext=".$acl_shlibext" # typically: shrext=.so
+ else
+ shrext=
+ fi
+ if test $use_additional = yes; then
+ dir="$additional_libdir"
+ dnl The same code as in the loop below:
+ dnl First look for a shared library.
+ if test -n "$acl_shlibext"; then
+ if test -f "$dir/$libname$shrext"; then
+ found_dir="$dir"
+ found_so="$dir/$libname$shrext"
+ else
+ if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
+ ver=`(cd "$dir" && \
+ for f in "$libname$shrext".*; do echo "$f"; done \
+ | sed -e "s,^$libname$shrext\\\\.,," \
+ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
+ | sed 1q ) 2>/dev/null`
+ if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
+ found_dir="$dir"
+ found_so="$dir/$libname$shrext.$ver"
+ fi
+ else
+ eval library_names=\"$acl_library_names_spec\"
+ for f in $library_names; do
+ if test -f "$dir/$f"; then
+ found_dir="$dir"
+ found_so="$dir/$f"
+ break
+ fi
+ done
+ fi
+ fi
+ fi
+ dnl Then look for a static library.
+ if test "X$found_dir" = "X"; then
+ if test -f "$dir/$libname.$acl_libext"; then
+ found_dir="$dir"
+ found_a="$dir/$libname.$acl_libext"
+ fi
+ fi
+ if test "X$found_dir" != "X"; then
+ if test -f "$dir/$libname.la"; then
+ found_la="$dir/$libname.la"
+ fi
+ fi
+ fi
+ if test "X$found_dir" = "X"; then
+ for x in $LDFLAGS $LTLIB[]NAME; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ case "$x" in
+ -L*)
+ dir=`echo "X$x" | sed -e 's/^X-L//'`
+ dnl First look for a shared library.
+ if test -n "$acl_shlibext"; then
+ if test -f "$dir/$libname$shrext"; then
+ found_dir="$dir"
+ found_so="$dir/$libname$shrext"
+ else
+ if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
+ ver=`(cd "$dir" && \
+ for f in "$libname$shrext".*; do echo "$f"; done \
+ | sed -e "s,^$libname$shrext\\\\.,," \
+ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
+ | sed 1q ) 2>/dev/null`
+ if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
+ found_dir="$dir"
+ found_so="$dir/$libname$shrext.$ver"
+ fi
+ else
+ eval library_names=\"$acl_library_names_spec\"
+ for f in $library_names; do
+ if test -f "$dir/$f"; then
+ found_dir="$dir"
+ found_so="$dir/$f"
+ break
+ fi
+ done
+ fi
+ fi
+ fi
+ dnl Then look for a static library.
+ if test "X$found_dir" = "X"; then
+ if test -f "$dir/$libname.$acl_libext"; then
+ found_dir="$dir"
+ found_a="$dir/$libname.$acl_libext"
+ fi
+ fi
+ if test "X$found_dir" != "X"; then
+ if test -f "$dir/$libname.la"; then
+ found_la="$dir/$libname.la"
+ fi
+ fi
+ ;;
+ esac
+ if test "X$found_dir" != "X"; then
+ break
+ fi
+ done
+ fi
+ if test "X$found_dir" != "X"; then
+ dnl Found the library.
+ LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name"
+ if test "X$found_so" != "X"; then
+ dnl Linking with a shared library. We attempt to hardcode its
+ dnl directory into the executable's runpath, unless it's the
+ dnl standard /usr/lib.
+ if test "$enable_rpath" = no \
+ || test "X$found_dir" = "X/usr/$acl_libdirstem" \
+ || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then
+ dnl No hardcoding is needed.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
+ else
+ dnl Use an explicit option to hardcode DIR into the resulting
+ dnl binary.
+ dnl Potentially add DIR to ltrpathdirs.
+ dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
+ haveit=
+ for x in $ltrpathdirs; do
+ if test "X$x" = "X$found_dir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ ltrpathdirs="$ltrpathdirs $found_dir"
+ fi
+ dnl The hardcoding into $LIBNAME is system dependent.
+ if test "$acl_hardcode_direct" = yes; then
+ dnl Using DIR/libNAME.so during linking hardcodes DIR into the
+ dnl resulting binary.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
+ else
+ if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then
+ dnl Use an explicit option to hardcode DIR into the resulting
+ dnl binary.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
+ dnl Potentially add DIR to rpathdirs.
+ dnl The rpathdirs will be appended to $LIBNAME at the end.
+ haveit=
+ for x in $rpathdirs; do
+ if test "X$x" = "X$found_dir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ rpathdirs="$rpathdirs $found_dir"
+ fi
+ else
+ dnl Rely on "-L$found_dir".
+ dnl But don't add it if it's already contained in the LDFLAGS
+ dnl or the already constructed $LIBNAME
+ haveit=
+ for x in $LDFLAGS $LIB[]NAME; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ if test "X$x" = "X-L$found_dir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir"
+ fi
+ if test "$acl_hardcode_minus_L" != no; then
+ dnl FIXME: Not sure whether we should use
+ dnl "-L$found_dir -l$name" or "-L$found_dir $found_so"
+ dnl here.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
+ else
+ dnl We cannot use $acl_hardcode_runpath_var and LD_RUN_PATH
+ dnl here, because this doesn't fit in flags passed to the
+ dnl compiler. So give up. No hardcoding. This affects only
+ dnl very old systems.
+ dnl FIXME: Not sure whether we should use
+ dnl "-L$found_dir -l$name" or "-L$found_dir $found_so"
+ dnl here.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
+ fi
+ fi
+ fi
+ fi
+ else
+ if test "X$found_a" != "X"; then
+ dnl Linking with a static library.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a"
+ else
+ dnl We shouldn't come here, but anyway it's good to have a
+ dnl fallback.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name"
+ fi
+ fi
+ dnl Assume the include files are nearby.
+ additional_includedir=
+ case "$found_dir" in
+ */$acl_libdirstem | */$acl_libdirstem/)
+ basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'`
+ if test "$name" = '$1'; then
+ LIB[]NAME[]_PREFIX="$basedir"
+ fi
+ additional_includedir="$basedir/include"
+ ;;
+ */$acl_libdirstem2 | */$acl_libdirstem2/)
+ basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'`
+ if test "$name" = '$1'; then
+ LIB[]NAME[]_PREFIX="$basedir"
+ fi
+ additional_includedir="$basedir/include"
+ ;;
+ esac
+ if test "X$additional_includedir" != "X"; then
+ dnl Potentially add $additional_includedir to $INCNAME.
+ dnl But don't add it
+ dnl 1. if it's the standard /usr/include,
+ dnl 2. if it's /usr/local/include and we are using GCC on Linux,
+ dnl 3. if it's already present in $CPPFLAGS or the already
+ dnl constructed $INCNAME,
+ dnl 4. if it doesn't exist as a directory.
+ if test "X$additional_includedir" != "X/usr/include"; then
+ haveit=
+ if test "X$additional_includedir" = "X/usr/local/include"; then
+ if test -n "$GCC"; then
+ case $host_os in
+ linux* | gnu* | k*bsd*-gnu) haveit=yes;;
+ esac
+ fi
+ fi
+ if test -z "$haveit"; then
+ for x in $CPPFLAGS $INC[]NAME; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ if test "X$x" = "X-I$additional_includedir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ if test -d "$additional_includedir"; then
+ dnl Really add $additional_includedir to $INCNAME.
+ INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir"
+ fi
+ fi
+ fi
+ fi
+ fi
+ dnl Look for dependencies.
+ if test -n "$found_la"; then
+ dnl Read the .la file. It defines the variables
+ dnl dlname, library_names, old_library, dependency_libs, current,
+ dnl age, revision, installed, dlopen, dlpreopen, libdir.
+ save_libdir="$libdir"
+ case "$found_la" in
+ */* | *\\*) . "$found_la" ;;
+ *) . "./$found_la" ;;
+ esac
+ libdir="$save_libdir"
+ dnl We use only dependency_libs.
+ for dep in $dependency_libs; do
+ case "$dep" in
+ -L*)
+ additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'`
+ dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME.
+ dnl But don't add it
+ dnl 1. if it's the standard /usr/lib,
+ dnl 2. if it's /usr/local/lib and we are using GCC on Linux,
+ dnl 3. if it's already present in $LDFLAGS or the already
+ dnl constructed $LIBNAME,
+ dnl 4. if it doesn't exist as a directory.
+ if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \
+ && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then
+ haveit=
+ if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \
+ || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then
+ if test -n "$GCC"; then
+ case $host_os in
+ linux* | gnu* | k*bsd*-gnu) haveit=yes;;
+ esac
+ fi
+ fi
+ if test -z "$haveit"; then
+ haveit=
+ for x in $LDFLAGS $LIB[]NAME; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ if test "X$x" = "X-L$additional_libdir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ if test -d "$additional_libdir"; then
+ dnl Really add $additional_libdir to $LIBNAME.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir"
+ fi
+ fi
+ haveit=
+ for x in $LDFLAGS $LTLIB[]NAME; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ if test "X$x" = "X-L$additional_libdir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ if test -d "$additional_libdir"; then
+ dnl Really add $additional_libdir to $LTLIBNAME.
+ LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir"
+ fi
+ fi
+ fi
+ fi
+ ;;
+ -R*)
+ dir=`echo "X$dep" | sed -e 's/^X-R//'`
+ if test "$enable_rpath" != no; then
+ dnl Potentially add DIR to rpathdirs.
+ dnl The rpathdirs will be appended to $LIBNAME at the end.
+ haveit=
+ for x in $rpathdirs; do
+ if test "X$x" = "X$dir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ rpathdirs="$rpathdirs $dir"
+ fi
+ dnl Potentially add DIR to ltrpathdirs.
+ dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
+ haveit=
+ for x in $ltrpathdirs; do
+ if test "X$x" = "X$dir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ ltrpathdirs="$ltrpathdirs $dir"
+ fi
+ fi
+ ;;
+ -l*)
+ dnl Handle this in the next round.
+ names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'`
+ ;;
+ *.la)
+ dnl Handle this in the next round. Throw away the .la's
+ dnl directory; it is already contained in a preceding -L
+ dnl option.
+ names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'`
+ ;;
+ *)
+ dnl Most likely an immediate library name.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep"
+ LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep"
+ ;;
+ esac
+ done
+ fi
+ else
+ dnl Didn't find the library; assume it is in the system directories
+ dnl known to the linker and runtime loader. (All the system
+ dnl directories known to the linker should also be known to the
+ dnl runtime loader, otherwise the system is severely misconfigured.)
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
+ LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name"
+ fi
+ fi
+ fi
+ done
+ done
+ if test "X$rpathdirs" != "X"; then
+ if test -n "$acl_hardcode_libdir_separator"; then
+ dnl Weird platform: only the last -rpath option counts, the user must
+ dnl pass all path elements in one option. We can arrange that for a
+ dnl single library, but not when more than one $LIBNAMEs are used.
+ alldirs=
+ for found_dir in $rpathdirs; do
+ alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir"
+ done
+ dnl Note: acl_hardcode_libdir_flag_spec uses $libdir and $wl.
+ acl_save_libdir="$libdir"
+ libdir="$alldirs"
+ eval flag=\"$acl_hardcode_libdir_flag_spec\"
+ libdir="$acl_save_libdir"
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
+ else
+ dnl The -rpath options are cumulative.
+ for found_dir in $rpathdirs; do
+ acl_save_libdir="$libdir"
+ libdir="$found_dir"
+ eval flag=\"$acl_hardcode_libdir_flag_spec\"
+ libdir="$acl_save_libdir"
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
+ done
+ fi
+ fi
+ if test "X$ltrpathdirs" != "X"; then
+ dnl When using libtool, the option that works for both libraries and
+ dnl executables is -R. The -R options are cumulative.
+ for found_dir in $ltrpathdirs; do
+ LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir"
+ done
+ fi
+ popdef([P_A_C_K])
+ popdef([PACKLIBS])
+ popdef([PACKUP])
+ popdef([PACK])
+ popdef([NAME])
+])
+
+dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR,
+dnl unless already present in VAR.
+dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes
+dnl contains two or three consecutive elements that belong together.
+AC_DEFUN([AC_LIB_APPENDTOVAR],
+[
+ for element in [$2]; do
+ haveit=
+ for x in $[$1]; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ if test "X$x" = "X$element"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ [$1]="${[$1]}${[$1]:+ }$element"
+ fi
+ done
+])
+
+dnl For those cases where a variable contains several -L and -l options
+dnl referring to unknown libraries and directories, this macro determines the
+dnl necessary additional linker options for the runtime path.
+dnl AC_LIB_LINKFLAGS_FROM_LIBS([LDADDVAR], [LIBSVALUE], [USE-LIBTOOL])
+dnl sets LDADDVAR to linker options needed together with LIBSVALUE.
+dnl If USE-LIBTOOL evaluates to non-empty, linking with libtool is assumed,
+dnl otherwise linking without libtool is assumed.
+AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS],
+[
+ AC_REQUIRE([AC_LIB_RPATH])
+ AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
+ $1=
+ if test "$enable_rpath" != no; then
+ if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then
+ dnl Use an explicit option to hardcode directories into the resulting
+ dnl binary.
+ rpathdirs=
+ next=
+ for opt in $2; do
+ if test -n "$next"; then
+ dir="$next"
+ dnl No need to hardcode the standard /usr/lib.
+ if test "X$dir" != "X/usr/$acl_libdirstem" \
+ && test "X$dir" != "X/usr/$acl_libdirstem2"; then
+ rpathdirs="$rpathdirs $dir"
+ fi
+ next=
+ else
+ case $opt in
+ -L) next=yes ;;
+ -L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'`
+ dnl No need to hardcode the standard /usr/lib.
+ if test "X$dir" != "X/usr/$acl_libdirstem" \
+ && test "X$dir" != "X/usr/$acl_libdirstem2"; then
+ rpathdirs="$rpathdirs $dir"
+ fi
+ next= ;;
+ *) next= ;;
+ esac
+ fi
+ done
+ if test "X$rpathdirs" != "X"; then
+ if test -n ""$3""; then
+ dnl libtool is used for linking. Use -R options.
+ for dir in $rpathdirs; do
+ $1="${$1}${$1:+ }-R$dir"
+ done
+ else
+ dnl The linker is used for linking directly.
+ if test -n "$acl_hardcode_libdir_separator"; then
+ dnl Weird platform: only the last -rpath option counts, the user
+ dnl must pass all path elements in one option.
+ alldirs=
+ for dir in $rpathdirs; do
+ alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$dir"
+ done
+ acl_save_libdir="$libdir"
+ libdir="$alldirs"
+ eval flag=\"$acl_hardcode_libdir_flag_spec\"
+ libdir="$acl_save_libdir"
+ $1="$flag"
+ else
+ dnl The -rpath options are cumulative.
+ for dir in $rpathdirs; do
+ acl_save_libdir="$libdir"
+ libdir="$dir"
+ eval flag=\"$acl_hardcode_libdir_flag_spec\"
+ libdir="$acl_save_libdir"
+ $1="${$1}${$1:+ }$flag"
+ done
+ fi
+ fi
+ fi
+ fi
+ fi
+ AC_SUBST([$1])
+])
diff --git a/build/autoconf/lib-prefix.m4 b/build/autoconf/lib-prefix.m4
new file mode 100644
index 000000000000..7e5f0bde03d8
--- /dev/null
+++ b/build/autoconf/lib-prefix.m4
@@ -0,0 +1,224 @@
+# lib-prefix.m4 serial 7 (gettext-0.18)
+dnl Copyright (C) 2001-2005, 2008-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and
+dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't
+dnl require excessive bracketing.
+ifdef([AC_HELP_STRING],
+[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])],
+[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])])
+
+dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed
+dnl to access previously installed libraries. The basic assumption is that
+dnl a user will want packages to use other packages he previously installed
+dnl with the same --prefix option.
+dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate
+dnl libraries, but is otherwise very convenient.
+AC_DEFUN([AC_LIB_PREFIX],
+[
+ AC_BEFORE([$0], [AC_LIB_LINKFLAGS])
+ AC_REQUIRE([AC_PROG_CC])
+ AC_REQUIRE([AC_CANONICAL_HOST])
+ AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
+ AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+ dnl By default, look in $includedir and $libdir.
+ use_additional=yes
+ AC_LIB_WITH_FINAL_PREFIX([
+ eval additional_includedir=\"$includedir\"
+ eval additional_libdir=\"$libdir\"
+ ])
+ AC_LIB_ARG_WITH([lib-prefix],
+[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib
+ --without-lib-prefix don't search for libraries in includedir and libdir],
+[
+ if test "X$withval" = "Xno"; then
+ use_additional=no
+ else
+ if test "X$withval" = "X"; then
+ AC_LIB_WITH_FINAL_PREFIX([
+ eval additional_includedir=\"$includedir\"
+ eval additional_libdir=\"$libdir\"
+ ])
+ else
+ additional_includedir="$withval/include"
+ additional_libdir="$withval/$acl_libdirstem"
+ fi
+ fi
+])
+ if test $use_additional = yes; then
+ dnl Potentially add $additional_includedir to $CPPFLAGS.
+ dnl But don't add it
+ dnl 1. if it's the standard /usr/include,
+ dnl 2. if it's already present in $CPPFLAGS,
+ dnl 3. if it's /usr/local/include and we are using GCC on Linux,
+ dnl 4. if it doesn't exist as a directory.
+ if test "X$additional_includedir" != "X/usr/include"; then
+ haveit=
+ for x in $CPPFLAGS; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ if test "X$x" = "X-I$additional_includedir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ if test "X$additional_includedir" = "X/usr/local/include"; then
+ if test -n "$GCC"; then
+ case $host_os in
+ linux* | gnu* | k*bsd*-gnu) haveit=yes;;
+ esac
+ fi
+ fi
+ if test -z "$haveit"; then
+ if test -d "$additional_includedir"; then
+ dnl Really add $additional_includedir to $CPPFLAGS.
+ CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir"
+ fi
+ fi
+ fi
+ fi
+ dnl Potentially add $additional_libdir to $LDFLAGS.
+ dnl But don't add it
+ dnl 1. if it's the standard /usr/lib,
+ dnl 2. if it's already present in $LDFLAGS,
+ dnl 3. if it's /usr/local/lib and we are using GCC on Linux,
+ dnl 4. if it doesn't exist as a directory.
+ if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then
+ haveit=
+ for x in $LDFLAGS; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ if test "X$x" = "X-L$additional_libdir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then
+ if test -n "$GCC"; then
+ case $host_os in
+ linux*) haveit=yes;;
+ esac
+ fi
+ fi
+ if test -z "$haveit"; then
+ if test -d "$additional_libdir"; then
+ dnl Really add $additional_libdir to $LDFLAGS.
+ LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir"
+ fi
+ fi
+ fi
+ fi
+ fi
+])
+
+dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix,
+dnl acl_final_exec_prefix, containing the values to which $prefix and
+dnl $exec_prefix will expand at the end of the configure script.
+AC_DEFUN([AC_LIB_PREPARE_PREFIX],
+[
+ dnl Unfortunately, prefix and exec_prefix get only finally determined
+ dnl at the end of configure.
+ if test "X$prefix" = "XNONE"; then
+ acl_final_prefix="$ac_default_prefix"
+ else
+ acl_final_prefix="$prefix"
+ fi
+ if test "X$exec_prefix" = "XNONE"; then
+ acl_final_exec_prefix='${prefix}'
+ else
+ acl_final_exec_prefix="$exec_prefix"
+ fi
+ acl_save_prefix="$prefix"
+ prefix="$acl_final_prefix"
+ eval acl_final_exec_prefix=\"$acl_final_exec_prefix\"
+ prefix="$acl_save_prefix"
+])
+
+dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the
+dnl variables prefix and exec_prefix bound to the values they will have
+dnl at the end of the configure script.
+AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX],
+[
+ acl_save_prefix="$prefix"
+ prefix="$acl_final_prefix"
+ acl_save_exec_prefix="$exec_prefix"
+ exec_prefix="$acl_final_exec_prefix"
+ $1
+ exec_prefix="$acl_save_exec_prefix"
+ prefix="$acl_save_prefix"
+])
+
+dnl AC_LIB_PREPARE_MULTILIB creates
+dnl - a variable acl_libdirstem, containing the basename of the libdir, either
+dnl "lib" or "lib64" or "lib/64",
+dnl - a variable acl_libdirstem2, as a secondary possible value for
+dnl acl_libdirstem, either the same as acl_libdirstem or "lib/sparcv9" or
+dnl "lib/amd64".
+AC_DEFUN([AC_LIB_PREPARE_MULTILIB],
+[
+ dnl There is no formal standard regarding lib and lib64.
+ dnl On glibc systems, the current practice is that on a system supporting
+ dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under
+ dnl $prefix/lib64 and 32-bit libraries go under $prefix/lib. We determine
+ dnl the compiler's default mode by looking at the compiler's library search
+ dnl path. If at least one of its elements ends in /lib64 or points to a
+ dnl directory whose absolute pathname ends in /lib64, we assume a 64-bit ABI.
+ dnl Otherwise we use the default, namely "lib".
+ dnl On Solaris systems, the current practice is that on a system supporting
+ dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under
+ dnl $prefix/lib/64 (which is a symlink to either $prefix/lib/sparcv9 or
+ dnl $prefix/lib/amd64) and 32-bit libraries go under $prefix/lib.
+ AC_REQUIRE([AC_CANONICAL_HOST])
+ acl_libdirstem=lib
+ acl_libdirstem2=
+ case "$host_os" in
+ solaris*)
+ dnl See Solaris 10 Software Developer Collection > Solaris 64-bit Developer's Guide > The Development Environment
+ dnl <http://docs.sun.com/app/docs/doc/816-5138/dev-env?l=en&a=view>.
+ dnl "Portable Makefiles should refer to any library directories using the 64 symbolic link."
+ dnl But we want to recognize the sparcv9 or amd64 subdirectory also if the
+ dnl symlink is missing, so we set acl_libdirstem2 too.
+ AC_CACHE_CHECK([for 64-bit host], [gl_cv_solaris_64bit],
+ [AC_EGREP_CPP([sixtyfour bits], [
+#ifdef _LP64
+sixtyfour bits
+#endif
+ ], [gl_cv_solaris_64bit=yes], [gl_cv_solaris_64bit=no])
+ ])
+ if test $gl_cv_solaris_64bit = yes; then
+ acl_libdirstem=lib/64
+ case "$host_cpu" in
+ sparc*) acl_libdirstem2=lib/sparcv9 ;;
+ i*86 | x86_64) acl_libdirstem2=lib/amd64 ;;
+ esac
+ fi
+ ;;
+ *)
+ searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'`
+ if test -n "$searchpath"; then
+ acl_save_IFS="${IFS= }"; IFS=":"
+ for searchdir in $searchpath; do
+ if test -d "$searchdir"; then
+ case "$searchdir" in
+ */lib64/ | */lib64 ) acl_libdirstem=lib64 ;;
+ */../ | */.. )
+ # Better ignore directories of this form. They are misleading.
+ ;;
+ *) searchdir=`cd "$searchdir" && pwd`
+ case "$searchdir" in
+ */lib64 ) acl_libdirstem=lib64 ;;
+ esac ;;
+ esac
+ fi
+ done
+ IFS="$acl_save_IFS"
+ fi
+ ;;
+ esac
+ test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem"
+])
diff --git a/build/autogen.sh b/build/autogen.sh
index ad7d245b794a..d82a401f920c 100755
--- a/build/autogen.sh
+++ b/build/autogen.sh
@@ -40,8 +40,9 @@ cd ..
# Clean up the source dir as much as we can.
/bin/sh build/clean.sh
-# Substitute the integer version into Libarchive's archive.h
+# Substitute the versions into Libarchive's archive.h and archive_entry.h
perl -p -i -e "s/^(#define\tARCHIVE_VERSION_NUMBER).*/\$1 $VN/" libarchive/archive.h
+perl -p -i -e "s/^(#define\tARCHIVE_VERSION_NUMBER).*/\$1 $VN/" libarchive/archive_entry.h
perl -p -i -e "s/^(#define\tARCHIVE_VERSION_STRING).*/\$1 \"libarchive $VS\"/" libarchive/archive.h
# Substitute versions into configure.ac as well
perl -p -i -e 's/(m4_define\(\[LIBARCHIVE_VERSION_S\]),.*\)/$1,['"$VS"'])/' configure.ac
@@ -59,10 +60,3 @@ esac
autoconf
autoheader
automake -a -c
-
-curl 'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD' > build/autoconf/config.guess
-curl 'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD' > build/autoconf/config.sub
-
-./configure
-make distcheck
-make dist-zip
diff --git a/build/clean.sh b/build/clean.sh
index 5b4c5624a60d..e4465f8a786c 100644
--- a/build/clean.sh
+++ b/build/clean.sh
@@ -1,17 +1,16 @@
#!/bin/sh
+#
+# Attempt to remove as many generated files as we can.
+# Ideally, a well-used development sandbox would look like
+# a pristine checkout after running this script.
+#
+
if [ \! -f build/version ]; then
echo 'Must run the clean script from the top-level dir of the libarchive distribution' 1>&2
exit 1
fi
-#
-# The automake-generated 'maintainer-clean' target does clean up a
-# lot. If that fails, try plain 'clean' in case we're using the cmake
-# or other makefile. But don't worry if we can't...
-#
-make maintainer-clean || make clean || true
-
# If we're on BSD, blow away the build dir under /usr/obj
rm -rf /usr/obj`pwd`
@@ -19,22 +18,32 @@ rm -rf /usr/obj`pwd`
# Try to clean up a bit more...
#
-find . -name '*.So' | xargs rm
-find . -name '*.a' | xargs rm
-find . -name '*.la' | xargs rm
-find . -name '*.lo' | xargs rm
-find . -name '*.o' | xargs rm
-find . -name '*.orig' | xargs rm
-find . -name '*.po' | xargs rm
-find . -name '*.rej' | xargs rm
-find . -name '*~' | xargs rm
-find . -name '.depend' | xargs rm
+find . -name '*.So' | xargs rm -f
+find . -name '*.a' | xargs rm -f
+find . -name '*.la' | xargs rm -f
+find . -name '*.lo' | xargs rm -f
+find . -name '*.o' | xargs rm -f
+find . -name '*.orig' | xargs rm -f
+find . -name '*.po' | xargs rm -f
+find . -name '*.rej' | xargs rm -f
+find . -name '*~' | xargs rm -f
+find . -name '.depend' | xargs rm -f
find . -name '.deps' | xargs rm -rf
-find . -name '.dirstamp' | xargs rm
+find . -name '.dirstamp' | xargs rm -f
find . -name '.libs' | xargs rm -rf
+find . -name 'CMakeFiles' | xargs rm -rf
+find . -name 'cmake_install.cmake' | xargs rm -f
+find . -name 'CTestTestfile.cmake' | xargs rm -f
+rm -rf Testing
rm -rf autom4te.cache
+rm -rf bin
+rm -rf cmake.tmp
+rm -rf libarchive/Testing
+rm -f CMakeCache.txt
+rm -f DartConfiguration.tcl
+rm -f Makefile
rm -f Makefile.in
rm -f aclocal.m4
rm -f bsdcpio
@@ -42,7 +51,8 @@ rm -f bsdcpio_test
rm -f bsdtar
rm -f bsdtar_test
rm -f build/autoconf/compile
-rm -f build/autoconf/config.*
+rm -f build/autoconf/config.guess
+rm -f build/autoconf/config.sub
rm -f build/autoconf/depcomp
rm -f build/autoconf/install-sh
rm -f build/autoconf/libtool.m4
@@ -60,7 +70,9 @@ rm -f config.log
rm -f config.status
rm -f configure
rm -f cpio/*.1.gz
+rm -f cpio/Makefile
rm -f cpio/bsdcpio
+rm -f cpio/test/Makefile
rm -f cpio/test/bsdcpio_test
rm -f cpio/test/list.h
rm -f doc/html/*
@@ -69,13 +81,17 @@ rm -f doc/pdf/*
rm -f doc/text/*
rm -f doc/wiki/*
rm -f libarchive/*.[35].gz
+rm -f libarchive/Makefile
rm -f libarchive/libarchive.so*
+rm -f libarchive/test/Makefile
rm -f libarchive/test/libarchive_test
rm -f libarchive/test/list.h
rm -f libarchive_test
rm -f libtool
rm -f stamp-h1
rm -f tar/*.1.gz
+rm -f tar/Makefile
rm -f tar/bsdtar
+rm -f tar/test/Makefile
rm -f tar/test/bsdtar_test
rm -f tar/test/list.h
diff --git a/build/cmake/AddTest28.cmake b/build/cmake/AddTest28.cmake
deleted file mode 100644
index ab26a9a9b8bf..000000000000
--- a/build/cmake/AddTest28.cmake
+++ /dev/null
@@ -1,107 +0,0 @@
-# - Macro approximating the CMake 2.8 ADD_TEST(NAME) signature.
-# ADD_TEST_28(NAME <name> COMMAND <command> [arg1 [arg2 ...]])
-# <name> - The name of the test
-# <command> - The test executable
-# [argN...] - Arguments to the test executable
-# This macro approximates the ADD_TEST(NAME) signature provided in
-# CMake 2.8 but works with CMake 2.6 too. See CMake 2.8 documentation
-# of ADD_TEST()for details.
-#
-# This macro automatically replaces a <command> that names an
-# executable target with the target location. A generator expression
-# of the form "$<TARGET_FILE:tgt>" is supported in both the command
-# and arguments of the test. Howerver, this macro only works for
-# targets without per-config output name properties set.
-#
-# Example usage:
-# add_test(NAME mytest COMMAND testDriver --exe $<TARGET_FILE:myexe>)
-# This creates a test "mytest" whose command runs a testDriver tool
-# passing the full path to the executable file produced by target
-# "myexe".
-
-#=============================================================================
-# Copyright 2009 Kitware, Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-# 1. Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer
-# in this position and unchanged.
-# 2. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-# IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#=============================================================================
-
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6.3)
-
-# CMake 2.8 supports ADD_TEST(NAME) natively.
-IF(NOT "${CMAKE_VERSION}" VERSION_LESS "2.8")
- MACRO(ADD_TEST_28)
- ADD_TEST(${ARGV})
- ENDMACRO()
- RETURN()
-ENDIF()
-
-# Simulate ADD_TEST(NAME) signature from CMake 2.8.
-MACRO(ADD_TEST_28 NAME name COMMAND command)
- # Enforce the signature.
- IF(NOT "x${NAME}" STREQUAL "xNAME")
- MESSAGE(FATAL_ERROR "First ADD_TEST_28 argument must be \"NAME\"")
- ENDIF()
- IF(NOT "x${COMMAND}" STREQUAL "xCOMMAND")
- MESSAGE(FATAL_ERROR "Third ADD_TEST_28 argument must be \"COMMAND\"")
- ENDIF()
-
- # Perform "COMMAND myexe ..." substitution.
- SET(cmd "${command}")
- IF(TARGET "${cmd}")
- _ADD_TEST_28_GET_EXE(${cmd} cmd)
- ENDIF()
-
- # Perform "COMMAND ... $<TARGET_FILE:myexe> ..." substitution.
- SET(target_file "\\$<TARGET_FILE:(.+)>")
- SET(args)
- FOREACH(ARG ${cmd} ${ARGN})
- SET(arg "${ARG}")
- IF("${arg}" MATCHES "${target_file}")
- STRING(REGEX REPLACE "${target_file}" "\\1" tgt "${arg}")
- IF(TARGET "${tgt}")
- _ADD_TEST_28_GET_EXE(${tgt} exe)
- STRING(REGEX REPLACE "${target_file}" "${exe}" arg "${arg}")
- ENDIF()
- ENDIF()
- LIST(APPEND args "${arg}")
- ENDFOREACH()
-
- # Invoke old ADD_TEST() signature with transformed arguments.
- ADD_TEST(${name} ${args})
-ENDMACRO()
-
-# Get the test-time location of an executable target.
-MACRO(_ADD_TEST_28_GET_EXE tgt exe_var)
- # The LOCATION property gives a build-time location.
- GET_TARGET_PROPERTY(${exe_var} ${tgt} LOCATION)
-
- # In single-configuration generatrs the build-time and test-time
- # locations are the same because there is no per-config variable
- # reference. In multi-configuration generators the following
- # substitution converts the build-time configuration variable
- # reference to a test-time configuration variable reference.
- IF(CMAKE_CONFIGURATION_TYPES)
- STRING(REPLACE "${CMAKE_CFG_INTDIR}" "\${CTEST_CONFIGURATION_TYPE}"
- ${exe_var} "${${exe_var}}")
- ENDIF(CMAKE_CONFIGURATION_TYPES)
-ENDMACRO()
diff --git a/build/cmake/FindLZMA.cmake b/build/cmake/FindLZMA.cmake
index 1d065c4abcc7..0b46b2cdd125 100644
--- a/build/cmake/FindLZMA.cmake
+++ b/build/cmake/FindLZMA.cmake
@@ -14,7 +14,7 @@ IF (LZMA_INCLUDE_DIR)
ENDIF (LZMA_INCLUDE_DIR)
FIND_PATH(LZMA_INCLUDE_DIR lzma.h)
-FIND_LIBRARY(LZMA_LIBRARY NAMES lzma )
+FIND_LIBRARY(LZMA_LIBRARY NAMES lzma liblzma)
# handle the QUIETLY and REQUIRED arguments and set LZMA_FOUND to TRUE if
# all listed variables are TRUE
@@ -46,7 +46,3 @@ ELSE(LZMA_FOUND)
SET( LZMADEC_LIBRARIES )
ENDIF(LZMADEC_FOUND)
ENDIF(LZMA_FOUND)
-
-
-MARK_AS_ADVANCED( LZMA_LIBRARY LZMA_INCLUDE_DIR
- LZMADEC_LIBRARY LZMADEC_INCLUDE_DIR )
diff --git a/build/cmake/config.h.in b/build/cmake/config.h.in
index d2f14b4e464e..b1690515d7a8 100644
--- a/build/cmake/config.h.in
+++ b/build/cmake/config.h.in
@@ -1,91 +1,287 @@
-/* config.h. Generated from config.h.cmake by cmake configure */
+/* config.h. Generated from build/cmake/config.h.in by cmake configure */
+
+/*
+ * Ensure we have C99-style int64_t, etc, all defined.
+ */
+
+/* First, we need to know if the system has already defined them. */
+#cmakedefine HAVE_INT16_T
+#cmakedefine HAVE_INT32_T
+#cmakedefine HAVE_INT64_T
+#cmakedefine HAVE_INTMAX_T
+
+#cmakedefine HAVE_UINT8_T
+#cmakedefine HAVE_UINT16_T
+#cmakedefine HAVE_UINT32_T
+#cmakedefine HAVE_UINT64_T
+#cmakedefine HAVE_UINTMAX_T
+
+/* We might have the types we want under other spellings. */
+#cmakedefine HAVE___INT64
+#cmakedefine HAVE_U_INT64_T
+#cmakedefine HAVE_UNSIGNED___INT64
+
+/* The sizes of various standard integer types. */
+@SIZE_OF_SHORT_CODE@
+@SIZE_OF_INT_CODE@
+@SIZE_OF_LONG_CODE@
+@SIZE_OF_LONG_LONG_CODE@
+@SIZE_OF_UNSIGNED_SHORT_CODE@
+@SIZE_OF_UNSIGNED_CODE@
+@SIZE_OF_UNSIGNED_LONG_CODE@
+@SIZE_OF_UNSIGNED_LONG_LONG_CODE@
+
+/*
+ * If we lack int64_t, define it to the first of __int64, int, long, and long long
+ * that exists and is the right size.
+ */
+#if !defined(HAVE_INT64_T) && defined(HAVE___INT64)
+typedef __int64 int64_t;
+#define HAVE_INT64_T
+#endif
+
+#if !defined(HAVE_INT64_T) && SIZE_OF_INT == 8
+typedef int int64_t;
+#define HAVE_INT64_T
+#endif
+
+#if !defined(HAVE_INT64_T) && SIZE_OF_LONG == 8
+typedef long int64_t;
+#define HAVE_INT64_T
+#endif
+
+#if !defined(HAVE_INT64_T) && SIZE_OF_LONG_LONG == 8
+typedef long long int64_t;
+#define HAVE_INT64_T
+#endif
+
+#if !defined(HAVE_INT64_T)
+#error No 64-bit integer type was found.
+#endif
+
+/*
+ * Similarly for int32_t
+ */
+#if !defined(HAVE_INT32_T) && SIZE_OF_INT == 4
+typedef long int32_t;
+#define HAVE_INT32_T
+#endif
+
+#if !defined(HAVE_INT32_T) && SIZE_OF_LONG == 4
+typedef long int32_t;
+#define HAVE_INT32_T
+#endif
+
+#if !defined(HAVE_INT32_T)
+#error No 32-bit integer type was found.
+#endif
+
+/*
+ * Similarly for int16_t
+ */
+#if !defined(HAVE_INT16_T) && SIZE_OF_INT == 2
+typedef int int16_t;
+#define HAVE_INT16_T
+#endif
+
+#if !defined(HAVE_INT16_T) && SIZE_OF_SHORT == 2
+typedef short int16_t;
+#define HAVE_INT16_T
+#endif
+
+#if !defined(HAVE_INT16_T)
+#error No 16-bit integer type was found.
+#endif
+
+/*
+ * Similarly for uint64_t
+ */
+#if !defined(HAVE_UINT64_T) && defined(HAVE_UNSIGNED___INT64)
+typedef unsigned __int64 uint64_t;
+#define HAVE_UINT64_T
+#endif
+
+#if !defined(HAVE_UINT64_T) && SIZE_OF_UNSIGNED == 8
+typedef unsigned uint64_t;
+#define HAVE_UINT64_T
+#endif
+
+#if !defined(HAVE_UINT64_T) && SIZE_OF_UNSIGNED_LONG == 8
+typedef unsigned long uint64_t;
+#define HAVE_UINT64_T
+#endif
+
+#if !defined(HAVE_UINT64_T) && SIZE_OF_UNSIGNED_LONG_LONG == 8
+typedef unsigned long long uint64_t;
+#define HAVE_UINT64_T
+#endif
+
+#if !defined(HAVE_UINT64_T)
+#error No 64-bit unsigned integer type was found.
+#endif
+
+
+/*
+ * Similarly for uint32_t
+ */
+#if !defined(HAVE_UINT32_T) && SIZE_OF_UNSIGNED == 4
+typedef unsigned uint32_t;
+#define HAVE_UINT32_T
+#endif
+
+#if !defined(HAVE_UINT32_T) && SIZE_OF_UNSIGNED_LONG == 4
+typedef unsigned long uint32_t;
+#define HAVE_UINT32_T
+#endif
+
+#if !defined(HAVE_UINT32_T)
+#error No 32-bit unsigned integer type was found.
+#endif
+
+/*
+ * Similarly for uint16_t
+ */
+#if !defined(HAVE_UINT16_T) && SIZE_OF_UNSIGNED == 2
+typedef unsigned uint16_t;
+#define HAVE_UINT16_T
+#endif
+
+#if !defined(HAVE_UINT16_T) && SIZE_OF_UNSIGNED_SHORT == 2
+typedef unsigned short uint16_t;
+#define HAVE_UINT16_T
+#endif
+
+#if !defined(HAVE_UINT16_T)
+#error No 16-bit unsigned integer type was found.
+#endif
+
+/*
+ * Similarly for uint8_t
+ */
+#if !defined(HAVE_UINT8_T)
+typedef unsigned char uint8_t;
+#define HAVE_UINT8_T
+#endif
+
+#if !defined(HAVE_UINT16_T)
+#error No 8-bit unsigned integer type was found.
+#endif
+
+/* Define intmax_t and uintmax_t if they are not already defined. */
+#if !defined(HAVE_INTMAX_T)
+typedef int64_t intmax_t;
+#define INTMAX_MIN INT64_MIN
+#define INTMAX_MAX INT64_MAX
+#endif
+
+#if !defined(HAVE_UINTMAX_T)
+typedef uint64_t uintmax_t;
+#endif
/* Define ZLIB_WINAPI if zlib was built on Visual Studio. */
#cmakedefine ZLIB_WINAPI 1
-/* MD5 via ARCHIVE_HASH_MD5_LIBC supported. */
-#cmakedefine ARCHIVE_HASH_MD5_LIBC
+/* MD5 via ARCHIVE_CRYPTO_MD5_LIBC supported. */
+#cmakedefine ARCHIVE_CRYPTO_MD5_LIBC 1
-/* MD5 via ARCHIVE_HASH_MD5_LIBSYSTEM supported. */
-#cmakedefine ARCHIVE_HASH_MD5_LIBSYSTEM
+/* MD5 via ARCHIVE_CRYPTO_MD5_LIBSYSTEM supported. */
+#cmakedefine ARCHIVE_CRYPTO_MD5_LIBSYSTEM 1
-/* MD5 via ARCHIVE_HASH_MD5_OPENSSL supported. */
-#cmakedefine ARCHIVE_HASH_MD5_OPENSSL
+/* MD5 via ARCHIVE_CRYPTO_MD5_NETTLE supported. */
+#cmakedefine ARCHIVE_CRYPTO_MD5_NETTLE 1
-/* MD5 via ARCHIVE_HASH_MD5_WIN supported. */
-#cmakedefine ARCHIVE_HASH_MD5_WIN
+/* MD5 via ARCHIVE_CRYPTO_MD5_OPENSSL supported. */
+#cmakedefine ARCHIVE_CRYPTO_MD5_OPENSSL 1
-/* RMD160 via ARCHIVE_HASH_RMD160_LIBC supported. */
-#cmakedefine ARCHIVE_HASH_RMD160_LIBC
+/* MD5 via ARCHIVE_CRYPTO_MD5_WIN supported. */
+#cmakedefine ARCHIVE_CRYPTO_MD5_WIN 1
-/* RMD160 via ARCHIVE_HASH_RMD160_OPENSSL supported. */
-#cmakedefine ARCHIVE_HASH_RMD160_OPENSSL
+/* RMD160 via ARCHIVE_CRYPTO_RMD160_LIBC supported. */
+#cmakedefine ARCHIVE_CRYPTO_RMD160_LIBC 1
-/* SHA1 via ARCHIVE_HASH_SHA1_LIBC supported. */
-#cmakedefine ARCHIVE_HASH_SHA1_LIBC
+/* RMD160 via ARCHIVE_CRYPTO_RMD160_NETTLE supported. */
+#cmakedefine ARCHIVE_CRYPTO_RMD160_NETTLE 1
-/* SHA1 via ARCHIVE_HASH_SHA1_LIBSYSTEM supported. */
-#cmakedefine ARCHIVE_HASH_SHA1_LIBSYSTEM
+/* RMD160 via ARCHIVE_CRYPTO_RMD160_OPENSSL supported. */
+#cmakedefine ARCHIVE_CRYPTO_RMD160_OPENSSL 1
-/* SHA1 via ARCHIVE_HASH_SHA1_OPENSSL supported. */
-#cmakedefine ARCHIVE_HASH_SHA1_OPENSSL
+/* SHA1 via ARCHIVE_CRYPTO_SHA1_LIBC supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA1_LIBC 1
-/* SHA1 via ARCHIVE_HASH_SHA1_WIN supported. */
-#cmakedefine ARCHIVE_HASH_SHA1_WIN
+/* SHA1 via ARCHIVE_CRYPTO_SHA1_LIBSYSTEM supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA1_LIBSYSTEM 1
-/* SHA256 via ARCHIVE_HASH_SHA256_LIBC supported. */
-#cmakedefine ARCHIVE_HASH_SHA256_LIBC
+/* SHA1 via ARCHIVE_CRYPTO_SHA1_NETTLE supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA1_NETTLE 1
-/* SHA256 via ARCHIVE_HASH_SHA256_LIBC2 supported. */
-#cmakedefine ARCHIVE_HASH_SHA256_LIBC2
+/* SHA1 via ARCHIVE_CRYPTO_SHA1_OPENSSL supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA1_OPENSSL 1
-/* SHA256 via ARCHIVE_HASH_SHA256_LIBC3 supported. */
-#cmakedefine ARCHIVE_HASH_SHA256_LIBC3
+/* SHA1 via ARCHIVE_CRYPTO_SHA1_WIN supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA1_WIN 1
-/* SHA256 via ARCHIVE_HASH_SHA256_LIBSYSTEM supported. */
-#cmakedefine ARCHIVE_HASH_SHA256_LIBSYSTEM
+/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBC supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA256_LIBC 1
-/* SHA256 via ARCHIVE_HASH_SHA256_OPENSSL supported. */
-#cmakedefine ARCHIVE_HASH_SHA256_OPENSSL
+/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBC2 supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA256_LIBC2 1
-/* SHA256 via ARCHIVE_HASH_SHA256_WIN supported. */
-#cmakedefine ARCHIVE_HASH_SHA256_WIN
+/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBC3 supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA256_LIBC3 1
-/* SHA384 via ARCHIVE_HASH_SHA384_LIBC supported. */
-#cmakedefine ARCHIVE_HASH_SHA384_LIBC
+/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBSYSTEM supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA256_LIBSYSTEM 1
-/* SHA384 via ARCHIVE_HASH_SHA384_LIBC2 supported. */
-#cmakedefine ARCHIVE_HASH_SHA384_LIBC2
+/* SHA256 via ARCHIVE_CRYPTO_SHA256_NETTLE supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA256_NETTLE 1
-/* SHA384 via ARCHIVE_HASH_SHA384_LIBC3 supported. */
-#cmakedefine ARCHIVE_HASH_SHA384_LIBC3
+/* SHA256 via ARCHIVE_CRYPTO_SHA256_OPENSSL supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA256_OPENSSL 1
-/* SHA384 via ARCHIVE_HASH_SHA384_LIBSYSTEM supported. */
-#cmakedefine ARCHIVE_HASH_SHA384_LIBSYSTEM
+/* SHA256 via ARCHIVE_CRYPTO_SHA256_WIN supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA256_WIN 1
-/* SHA384 via ARCHIVE_HASH_SHA384_OPENSSL supported. */
-#cmakedefine ARCHIVE_HASH_SHA384_OPENSSL
+/* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBC supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA384_LIBC 1
-/* SHA384 via ARCHIVE_HASH_SHA384_WIN supported. */
-#cmakedefine ARCHIVE_HASH_SHA384_WIN
+/* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBC2 supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA384_LIBC2 1
-/* SHA512 via ARCHIVE_HASH_SHA512_LIBC supported. */
-#cmakedefine ARCHIVE_HASH_SHA512_LIBC
+/* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBC3 supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA384_LIBC3 1
-/* SHA512 via ARCHIVE_HASH_SHA512_LIBC2 supported. */
-#cmakedefine ARCHIVE_HASH_SHA512_LIBC2
+/* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBSYSTEM supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA384_LIBSYSTEM 1
-/* SHA512 via ARCHIVE_HASH_SHA512_LIBC3 supported. */
-#cmakedefine ARCHIVE_HASH_SHA512_LIBC3
+/* SHA384 via ARCHIVE_CRYPTO_SHA384_NETTLE supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA384_NETTLE 1
-/* SHA512 via ARCHIVE_HASH_SHA512_LIBSYSTEM supported. */
-#cmakedefine ARCHIVE_HASH_SHA512_LIBSYSTEM
+/* SHA384 via ARCHIVE_CRYPTO_SHA384_OPENSSL supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA384_OPENSSL 1
-/* SHA512 via ARCHIVE_HASH_SHA512_OPENSSL supported. */
-#cmakedefine ARCHIVE_HASH_SHA512_OPENSSL
+/* SHA384 via ARCHIVE_CRYPTO_SHA384_WIN supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA384_WIN 1
-/* SHA512 via ARCHIVE_HASH_SHA512_WIN supported. */
-#cmakedefine ARCHIVE_HASH_SHA512_WIN
+/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBC supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA512_LIBC 1
+
+/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBC2 supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA512_LIBC2 1
+
+/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBC3 supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA512_LIBC3 1
+
+/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBSYSTEM supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA512_LIBSYSTEM 1
+
+/* SHA512 via ARCHIVE_CRYPTO_SHA512_NETTLE supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA512_NETTLE 1
+
+/* SHA512 via ARCHIVE_CRYPTO_SHA512_OPENSSL supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA512_OPENSSL 1
+
+/* SHA512 via ARCHIVE_CRYPTO_SHA512_WIN supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA512_WIN 1
/* Version number of bsdcpio */
#cmakedefine BSDCPIO_VERSION_STRING "${BSDCPIO_VERSION_STRING}"
@@ -147,11 +343,11 @@
/* Define to 1 if you have the `chroot' function. */
#cmakedefine HAVE_CHROOT 1
-/* Define to 1 if you have the `CreateHardLinkA' function. */
-#cmakedefine HAVE_CREATEHARDLINKA 1
+/* Define to 1 if you have the <copyfile.h> header file. */
+#cmakedefine HAVE_COPYFILE_H 1
-/* Define to 1 if you have the `CreateHardLinkW' function. */
-#cmakedefine HAVE_CREATEHARDLINKW 1
+/* Define to 1 if you have the `ctime_r' function. */
+#cmakedefine HAVE_CTIME_R 1
/* Define to 1 if you have the <ctype.h> header file. */
#cmakedefine HAVE_CTYPE_H 1
@@ -167,14 +363,6 @@
don't. */
#cmakedefine HAVE_DECL_INT64_MIN 1
-/* Define to 1 if you have the declaration of `optarg', and to 0 if you don't.
- */
-#cmakedefine HAVE_DECL_OPTARG 1
-
-/* Define to 1 if you have the declaration of `optind', and to 0 if you don't.
- */
-#cmakedefine HAVE_DECL_OPTIND 1
-
/* Define to 1 if you have the declaration of `SIZE_MAX', and to 0 if you
don't. */
#cmakedefine HAVE_DECL_SIZE_MAX 1
@@ -238,6 +426,9 @@
/* Define to 1 if you have the `extattr_set_file' function. */
#cmakedefine HAVE_EXTATTR_SET_FILE 1
+/* Define to 1 if EXTATTR_NAMESPACE_USER is defined in sys/extattr.h. */
+#cmakedefine HAVE_DECL_EXTATTR_NAMESPACE_USER 1
+
/* Define to 1 if you have the `fchdir' function. */
#cmakedefine HAVE_FCHDIR 1
@@ -256,18 +447,45 @@
/* Define to 1 if you have the <fcntl.h> header file. */
#cmakedefine HAVE_FCNTL_H 1
+/* Define to 1 if you have the `fdopendir' function. */
+#cmakedefine HAVE_FDOPENDIR 1
+
+/* Define to 1 if you have the `fgetea' function. */
+#cmakedefine HAVE_FGETEA 1
+
+/* Define to 1 if you have the `fgetxattr' function. */
+#cmakedefine HAVE_FGETXATTR 1
+
+/* Define to 1 if you have the `flistea' function. */
+#cmakedefine HAVE_FLISTEA 1
+
+/* Define to 1 if you have the `flistxattr' function. */
+#cmakedefine HAVE_FLISTXATTR 1
+
/* Define to 1 if you have the `fork' function. */
#cmakedefine HAVE_FORK 1
/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
#cmakedefine HAVE_FSEEKO 1
+/* Define to 1 if you have the `fsetea' function. */
+#cmakedefine HAVE_FSETEA 1
+
/* Define to 1 if you have the `fsetxattr' function. */
#cmakedefine HAVE_FSETXATTR 1
/* Define to 1 if you have the `fstat' function. */
#cmakedefine HAVE_FSTAT 1
+/* Define to 1 if you have the `fstatat' function. */
+#cmakedefine HAVE_FSTATAT 1
+
+/* Define to 1 if you have the `fstatfs' function. */
+#cmakedefine HAVE_FSTATFS 1
+
+/* Define to 1 if you have the `fstatvfs' function. */
+#cmakedefine HAVE_FSTATVFS 1
+
/* Define to 1 if you have the `ftruncate' function. */
#cmakedefine HAVE_FTRUNCATE 1
@@ -277,6 +495,12 @@
/* Define to 1 if you have the `futimes' function. */
#cmakedefine HAVE_FUTIMES 1
+/* Define to 1 if you have the `futimesat' function. */
+#cmakedefine HAVE_FUTIMESAT 1
+
+/* Define to 1 if you have the `getea' function. */
+#cmakedefine HAVE_GETEA 1
+
/* Define to 1 if you have the `geteuid' function. */
#cmakedefine HAVE_GETEUID 1
@@ -286,23 +510,32 @@
/* Define to 1 if you have the `getgrnam_r' function. */
#cmakedefine HAVE_GETGRNAM_R 1
+/* Define to 1 if you have the `getpid' function. */
+#cmakedefine HAVE_GETPID 1
+
/* Define to 1 if you have the `getpwnam_r' function. */
#cmakedefine HAVE_GETPWNAM_R 1
/* Define to 1 if you have the `getpwuid_r' function. */
#cmakedefine HAVE_GETPWUID_R 1
-/* Define to 1 if you have the `getpid' function. */
-#cmakedefine HAVE_GETPID 1
+/* Define to 1 if you have the `getvfsbyname' function. */
+#cmakedefine HAVE_GETVFSBYNAME 1
/* Define to 1 if you have the `getxattr' function. */
#cmakedefine HAVE_GETXATTR 1
+/* Define to 1 if you have the `gmtime_r' function. */
+#cmakedefine HAVE_GMTIME_R 1
+
/* Define to 1 if you have the <grp.h> header file. */
#cmakedefine HAVE_GRP_H 1
-/* Define to 1 if the system has the type `intmax_t'. */
-#cmakedefine HAVE_INTMAX_T 1
+/* Define to 1 if you have the `iconv' function. */
+#cmakedefine HAVE_ICONV 1
+
+/* Define to 1 if you have the <iconv.h> header file. */
+#cmakedefine HAVE_ICONV_H 1
/* Define to 1 if you have the <inttypes.h> header file. */
#cmakedefine HAVE_INTTYPES_H 1
@@ -322,6 +555,9 @@
/* Define to 1 if you have the `lchown' function. */
#cmakedefine HAVE_LCHOWN 1
+/* Define to 1 if you have the `lgetea' function. */
+#cmakedefine HAVE_LGETEA 1
+
/* Define to 1 if you have the `lgetxattr' function. */
#cmakedefine HAVE_LGETXATTR 1
@@ -352,30 +588,57 @@
/* Define to 1 if you have the <libxml/xmlreader.h> header file. */
#cmakedefine HAVE_LIBXML_XMLREADER_H 1
+/* Define to 1 if you have the <libxml/xmlwriter.h> header file. */
+#cmakedefine HAVE_LIBXML_XMLWRITER_H 1
+
/* Define to 1 if you have the `z' library (-lz). */
#cmakedefine HAVE_LIBZ 1
/* Define to 1 if you have the <limits.h> header file. */
#cmakedefine HAVE_LIMITS_H 1
-/* Define to 1 if you have the link() function. */
+/* Define to 1 if you have the `link' function. */
#cmakedefine HAVE_LINK 1
+/* Define to 1 if you have the <linux/fiemap.h> header file. */
+#cmakedefine HAVE_LINUX_FIEMAP_H 1
+
/* Define to 1 if you have the <linux/fs.h> header file. */
#cmakedefine HAVE_LINUX_FS_H 1
+/* Define to 1 if you have the <linux/magic.h> header file. */
+#cmakedefine HAVE_LINUX_MAGIC_H 1
+
+/* Define to 1 if you have the `listea' function. */
+#cmakedefine HAVE_LISTEA 1
+
/* Define to 1 if you have the `listxattr' function. */
#cmakedefine HAVE_LISTXATTR 1
+/* Define to 1 if you have the `llistea' function. */
+#cmakedefine HAVE_LLISTEA 1
+
/* Define to 1 if you have the `llistxattr' function. */
#cmakedefine HAVE_LLISTXATTR 1
+/* Define to 1 if you have the <localcharset.h> header file. */
+#cmakedefine HAVE_LOCALCHARSET_H 1
+
+/* Define to 1 if you have the `locale_charset' function. */
+#cmakedefine HAVE_LOCALE_CHARSET 1
+
/* Define to 1 if you have the <locale.h> header file. */
#cmakedefine HAVE_LOCALE_H 1
+/* Define to 1 if you have the `localtime_r' function. */
+#cmakedefine HAVE_LOCALTIME_R 1
+
/* Define to 1 if the system has the type `long long int'. */
#cmakedefine HAVE_LONG_LONG_INT 1
+/* Define to 1 if you have the `lsetea' function. */
+#cmakedefine HAVE_LSETEA 1
+
/* Define to 1 if you have the `lsetxattr' function. */
#cmakedefine HAVE_LSETXATTR 1
@@ -395,6 +658,12 @@
/* Define to 1 if you have the <lzma.h> header file. */
#cmakedefine HAVE_LZMA_H 1
+/* Define to 1 if you have the `mbrtowc' function. */
+#cmakedefine HAVE_MBRTOWC 1
+
+/* Define to 1 if you have the `mbsnrtowcs' function. */
+#cmakedefine HAVE_MBSNRTOWCS 1
+
/* Define to 1 if you have the `memmove' function. */
#cmakedefine HAVE_MEMMOVE 1
@@ -410,12 +679,18 @@
/* Define to 1 if you have the `mknod' function. */
#cmakedefine HAVE_MKNOD 1
+/* Define to 1 if you have the `mkstemp' function. */
+#cmakedefine HAVE_MKSTEMP 1
+
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
#cmakedefine HAVE_NDIR_H 1
/* Define to 1 if you have the `nl_langinfo' function. */
#cmakedefine HAVE_NL_LANGINFO 1
+/* Define to 1 if you have the `openat' function. */
+#cmakedefine HAVE_OPENAT 1
+
/* Define to 1 if you have the <paths.h> header file. */
#cmakedefine HAVE_PATHS_H 1
@@ -434,9 +709,15 @@
/* Define to 1 if you have the <pwd.h> header file. */
#cmakedefine HAVE_PWD_H 1
+/* Define to 1 if you have the `readdir_r' function. */
+#cmakedefine HAVE_READDIR_R 1
+
/* Define to 1 if you have the `readlink' function. */
#cmakedefine HAVE_READLINK 1
+/* Define to 1 if you have the `readlinkat' function. */
+#cmakedefine HAVE_READLINKAT 1
+
/* Define to 1 if you have the <regex.h> header file. */
#cmakedefine HAVE_REGEX_H 1
@@ -455,6 +736,12 @@
/* Define to 1 if you have the <signal.h> header file. */
#cmakedefine HAVE_SIGNAL_H 1
+/* Define to 1 if you have the `statfs' function. */
+#cmakedefine HAVE_STATFS 1
+
+/* Define to 1 if you have the `statvfs' function. */
+#cmakedefine HAVE_STATVFS 1
+
/* Define to 1 if `stat' has the bug that it succeeds when given the
zero-length file name argument. */
#cmakedefine HAVE_STAT_EMPTY_STRING_BUG 1
@@ -492,34 +779,43 @@
/* Define to 1 if you have the `strrchr' function. */
#cmakedefine HAVE_STRRCHR 1
-/* Define to 1 if `st_birthtime' is member of `struct stat'. */
+/* Define to 1 if `f_namemax' is a member of `struct statfs'. */
+#cmakedefine HAVE_STRUCT_STATFS_F_NAMEMAX 1
+
+/* Define to 1 if `st_birthtime' is a member of `struct stat'. */
#cmakedefine HAVE_STRUCT_STAT_ST_BIRTHTIME 1
-/* Define to 1 if `st_birthtimespec.tv_nsec' is member of `struct stat'. */
+/* Define to 1 if `st_birthtimespec.tv_nsec' is a member of `struct stat'. */
#cmakedefine HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC 1
-/* Define to 1 if `st_blksize' is member of `struct stat'. */
+/* Define to 1 if `st_blksize' is a member of `struct stat'. */
#cmakedefine HAVE_STRUCT_STAT_ST_BLKSIZE 1
-/* Define to 1 if `st_flags' is member of `struct stat'. */
+/* Define to 1 if `st_flags' is a member of `struct stat'. */
#cmakedefine HAVE_STRUCT_STAT_ST_FLAGS 1
-/* Define to 1 if `st_mtimespec.tv_nsec' is member of `struct stat'. */
+/* Define to 1 if `st_mtimespec.tv_nsec' is a member of `struct stat'. */
#cmakedefine HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC 1
-/* Define to 1 if `st_mtime_n' is member of `struct stat'. */
+/* Define to 1 if `st_mtime_n' is a member of `struct stat'. */
#cmakedefine HAVE_STRUCT_STAT_ST_MTIME_N 1
-/* Define to 1 if `st_mtime_usec' is member of `struct stat'. */
+/* Define to 1 if `st_mtime_usec' is a member of `struct stat'. */
#cmakedefine HAVE_STRUCT_STAT_ST_MTIME_USEC 1
-/* Define to 1 if `st_mtim.tv_nsec' is member of `struct stat'. */
+/* Define to 1 if `st_mtim.tv_nsec' is a member of `struct stat'. */
#cmakedefine HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC 1
-/* Define to 1 if `st_umtime' is member of `struct stat'. */
+/* Define to 1 if `st_umtime' is a member of `struct stat'. */
#cmakedefine HAVE_STRUCT_STAT_ST_UMTIME 1
-/* Define to 1 if you have the symlink() function. */
+/* Define to 1 if `tm_gmtoff' is a member of `struct tm'. */
+#cmakedefine HAVE_STRUCT_TM_TM_GMTOFF 1
+
+/* Define to 1 if `__tm_gmtoff' is a member of `struct tm'. */
+#cmakedefine HAVE_STRUCT_TM___TM_GMTOFF 1
+
+/* Define to 1 if you have the `symlink' function. */
#cmakedefine HAVE_SYMLINK 1
/* Define to 1 if you have the <sys/acl.h> header file. */
@@ -532,6 +828,9 @@
*/
#cmakedefine HAVE_SYS_DIR_H 1
+/* Define to 1 if you have the <sys/ea.h> header file. */
+#cmakedefine HAVE_SYS_EA_H 1
+
/* Define to 1 if you have the <sys/extattr.h> header file. */
#cmakedefine HAVE_SYS_EXTATTR_H 1
@@ -541,6 +840,9 @@
/* Define to 1 if you have the <sys/mkdev.h> header file. */
#cmakedefine HAVE_SYS_MKDEV_H 1
+/* Define to 1 if you have the <sys/mount.h> header file. */
+#cmakedefine HAVE_SYS_MOUNT_H 1
+
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
*/
#cmakedefine HAVE_SYS_NDIR_H 1
@@ -554,6 +856,12 @@
/* Define to 1 if you have the <sys/select.h> header file. */
#cmakedefine HAVE_SYS_SELECT_H 1
+/* Define to 1 if you have the <sys/statfs.h> header file. */
+#cmakedefine HAVE_SYS_STATFS_H 1
+
+/* Define to 1 if you have the <sys/statvfs.h> header file. */
+#cmakedefine HAVE_SYS_STATVFS_H 1
+
/* Define to 1 if you have the <sys/stat.h> header file. */
#cmakedefine HAVE_SYS_STAT_H 1
@@ -566,6 +874,12 @@
/* Define to 1 if you have the <sys/utime.h> header file. */
#cmakedefine HAVE_SYS_UTIME_H 1
+/* Define to 1 if you have the <sys/utsname.h> header file. */
+#cmakedefine HAVE_SYS_UTSNAME_H 1
+
+/* Define to 1 if you have the <sys/vfs.h> header file. */
+#cmakedefine HAVE_SYS_VFS_H 1
+
/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
#cmakedefine HAVE_SYS_WAIT_H 1
@@ -581,9 +895,6 @@
/* Define to 1 if you have the `tzset' function. */
#cmakedefine HAVE_TZSET 1
-/* Define to 1 if the system has the type `uintmax_t'. */
-#cmakedefine HAVE_UINTMAX_T 1
-
/* Define to 1 if you have the <unistd.h> header file. */
#cmakedefine HAVE_UNISTD_H 1
@@ -632,15 +943,24 @@
/* Define to 1 if you have the `wcslen' function. */
#cmakedefine HAVE_WCSLEN 1
+/* Define to 1 if you have the `wcsnrtombs' function. */
+#cmakedefine HAVE_WCSNRTOMBS 1
+
/* Define to 1 if you have the `wctomb' function. */
#cmakedefine HAVE_WCTOMB 1
/* Define to 1 if you have the <wctype.h> header file. */
#cmakedefine HAVE_WCTYPE_H 1
+/* Define to 1 if you have the <wincrypt.h> header file. */
+#cmakedefine HAVE_WINCRYPT_H 1
+
/* Define to 1 if you have the <windows.h> header file. */
#cmakedefine HAVE_WINDOWS_H 1
+/* Define to 1 if you have the <winioctl.h> header file. */
+#cmakedefine HAVE_WINIOCTL_H 1
+
/* Define to 1 if you have _CrtSetReportMode in <crtdbg.h> */
#cmakedefine HAVE__CrtSetReportMode 1
@@ -650,9 +970,30 @@
/* Define to 1 if you have the `wmemcpy' function. */
#cmakedefine HAVE_WMEMCPY 1
+/* Define to 1 if you have a working EXT2_IOC_GETFLAGS */
+#cmakedefine HAVE_WORKING_EXT2_IOC_GETFLAGS 1
+
/* Define to 1 if you have the <zlib.h> header file. */
#cmakedefine HAVE_ZLIB_H 1
+/* Define to 1 if you have the `_ctime64_s' function. */
+#cmakedefine HAVE__CTIME64_S 1
+
+/* Define to 1 if you have the `_fseeki64' function. */
+#cmakedefine HAVE__FSEEKI64 1
+
+/* Define to 1 if you have the `_get_timezone' function. */
+#cmakedefine HAVE__GET_TIMEZONE 1
+
+/* Define to 1 if you have the `_localtime64_s' function. */
+#cmakedefine HAVE__LOCALTIME64_S 1
+
+/* Define to 1 if you have the `_mkgmtime64' function. */
+#cmakedefine HAVE__MKGMTIME64 1
+
+/* Define as const if the declaration of iconv() needs const. */
+#define ICONV_CONST ${ICONV_CONST}
+
/* Version number of libarchive as a single integer */
#cmakedefine LIBARCHIVE_VERSION_NUMBER "${LIBARCHIVE_VERSION_NUMBER}"
@@ -683,6 +1024,33 @@
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#cmakedefine TIME_WITH_SYS_TIME 1
+/*
+ * Some platform requires a macro to use extension functions.
+ */
+#cmakedefine SAFE_TO_DEFINE_EXTENSIONS 1
+#ifdef SAFE_TO_DEFINE_EXTENSIONS
+/* Enable extensions on AIX 3, Interix. */
+#ifndef _ALL_SOURCE
+# define _ALL_SOURCE 1
+#endif
+/* Enable GNU extensions on systems that have them. */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE 1
+#endif
+/* Enable threading extensions on Solaris. */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# define _POSIX_PTHREAD_SEMANTICS 1
+#endif
+/* Enable extensions on HP NonStop. */
+#ifndef _TANDEM_SOURCE
+# define _TANDEM_SOURCE 1
+#endif
+/* Enable general extensions on Solaris. */
+#ifndef __EXTENSIONS__
+# define __EXTENSIONS__ 1
+#endif
+#endif /* SAFE_TO_DEFINE_EXTENSIONS */
+
/* Version number of package */
#cmakedefine VERSION "${VERSION}"
@@ -695,10 +1063,9 @@
/* Define for large files, on AIX-style hosts. */
#cmakedefine _LARGE_FILES ${_LARGE_FILES}
-/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,
- <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
- #define below would cause a syntax error. */
-#cmakedefine _UINT64_T
+/* Define for Windows to use Windows 2000+ APIs. */
+#cmakedefine _WIN32_WINNT ${_WIN32_WINNT}
+#cmakedefine WINVER ${WINVER}
/* Define to empty if `const' does not conform to ANSI C. */
#cmakedefine const ${const}
@@ -709,17 +1076,6 @@
/* Define to `unsigned long' if <sys/types.h> does not define. */
#cmakedefine id_t ${id_t}
-/* Define to `int' if <sys/types.h> doesn't define. */
-#cmakedefine int32_t ${int32_t}
-
-/* Define to the type of a signed integer type of width exactly 64 bits if
- such a type exists and the standard includes do not define it. */
-#cmakedefine int64_t ${int64_t}
-
-/* Define to the widest signed integer type if <stdint.h> and <inttypes.h> do
- not define. */
-#cmakedefine intmax_t ${intmax_t}
-
/* Define to `int' if <sys/types.h> does not define. */
#cmakedefine mode_t ${mode_t}
@@ -738,20 +1094,6 @@
/* Define to `int' if <sys/types.h> doesn't define. */
#cmakedefine uid_t ${uid_t}
-/* Define to `unsigned short' if <sys/types.h> doesn't define. */
-#cmakedefine uint16_t ${uint16_t}
-
-/* Define to `unsigned int' if <sys/types.h> doesn't define. */
-#cmakedefine uint32_t ${uint32_t}
-
-/* Define to the type of an unsigned integer type of width exactly 64 bits if
- such a type exists and the standard includes do not define it. */
-#cmakedefine uint64_t ${uint64_t}
-
-/* Define to the widest unsigned integer type if <stdint.h> and <inttypes.h>
- do not define. */
-#cmakedefine uintmax_t ${uintmax_t}
-
/* Define to `int' if <sys/types.h> does not define. */
#cmakedefine intptr_t ${intptr_t}
diff --git a/build/makerelease.sh b/build/makerelease.sh
new file mode 100755
index 000000000000..a8aa23b026c0
--- /dev/null
+++ b/build/makerelease.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+
+#
+# This script exists primarily to document some of the
+# steps needed when building an "official libarchive distribution".
+# Feel free to hack it up as necessary to adjust to the peculiarities
+# of a particular build environment.
+#
+
+PATH=/usr/local/gnu-autotools/bin/:$PATH
+export PATH
+
+# Start from one level above the build directory
+if [ -f version ]; then
+ cd ..
+fi
+
+if [ \! -f build/version ]; then
+ echo "Can't find source directory"
+ exit 1
+fi
+
+# BSD make's "OBJDIR" support freaks out the automake-generated
+# Makefile. Effectively disable it.
+export MAKEOBJDIRPREFIX=/junk
+
+set -ex
+
+#
+# Scrub the local tree before running the build tests below.
+#
+/bin/sh build/clean.sh
+
+#
+# Verify the CMake-generated build
+#
+mkdir -p _cmtest
+cd _cmtest
+cmake ..
+make
+make test
+cd ..
+rm -rf _cmtest
+# TODO: Build distribution using cmake
+
+#
+# Construct and verify the autoconf build system
+#
+/bin/sh build/autogen.sh
+
+# Get the newest config.guess/config.sub from savannah.gnu.org
+curl 'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD' > build/autoconf/config.guess
+curl 'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD' > build/autoconf/config.sub
+
+./configure
+make distcheck
+make dist-zip
diff --git a/build/pkgconfig/libarchive.pc.in b/build/pkgconfig/libarchive.pc.in
index 5f1d6a63d03c..95d715951774 100644
--- a/build/pkgconfig/libarchive.pc.in
+++ b/build/pkgconfig/libarchive.pc.in
@@ -6,5 +6,6 @@ includedir=@includedir@
Name: libarchive
Description: library that can create and read several streaming archive formats
Version: @VERSION@
-Libs: -larchive
+Cflags: -I${includedir}
+Libs: -L${libdir} -larchive
Libs.private: @LIBS@
diff --git a/build/utils/gen_archive_string_composition_h.sh b/build/utils/gen_archive_string_composition_h.sh
new file mode 100755
index 000000000000..95dbe167d5e5
--- /dev/null
+++ b/build/utils/gen_archive_string_composition_h.sh
@@ -0,0 +1,418 @@
+#!/bin/sh
+#
+# This needs http://unicode.org/Public/UNIDATA/UnicodeData.txt
+#
+inputfile="$1" # Expect UnicodeData.txt
+outfile=archive_string_composition.h
+pickout=/tmp/mk_unicode_composition_tbl$$.awk
+#################################################################################
+#
+# Append the file header of "archive_string_composition.h"
+#
+#################################################################################
+append_copyright()
+{
+cat > ${outfile} <<CR_END
+/*-
+ * Copyright (c) 2011 libarchive Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * \$FreeBSD\$
+ *
+ */
+
+/*
+ * ATTENTION!
+ * This file is generated by build/utils/gen_archive_string_composition_h.sh
+ * from http://unicode.org/Public/UNIDATA/UnicodeData.txt
+ *
+ * See also http://unicode.org/report/tr15/
+ */
+
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
+#ifndef ARCHIVE_STRING_COMPOSITION_H_INCLUDED
+#define ARCHIVE_STRING_COMPOSITION_H_INCLUDED
+
+struct unicode_composition_table {
+ uint32_t cp1;
+ uint32_t cp2;
+ uint32_t nfc;
+};
+
+CR_END
+}
+#################################################################################
+#
+# awk script
+#
+#################################################################################
+cat > ${pickout} <<AWK_END
+#
+BEGIN {
+ FS = ";"
+ min = "";
+ max = "";
+ cmd="sort | awk -F ' ' '{printf \"\\\\t{ 0x%s , 0x%s , 0x%s },\\\\n\",\$1,\$2,\$3}'"
+ print "static const struct unicode_composition_table u_composition_table[] = {"
+}
+END {
+ close(cmd)
+ print "};"
+ print ""
+ #
+ # Output Canonical Combining Class tables used for translating NFD to NFC.
+ #
+ printf "#define CANONICAL_CLASS_MIN\\t0x%s\\n", min
+ printf "#define CANONICAL_CLASS_MAX\\t0x%s\\n", max
+ print ""
+ printf "#define IS_DECOMPOSABLE_BLOCK(uc)\\t\\\\\n"
+ printf "\\t(((uc)>>8) <= 0x%X && u_decomposable_blocks[(uc)>>8])\\n", highnum
+ printf "static const char u_decomposable_blocks[0x%X+1] = {\\n\\t", highnum
+ #
+ # Output blockmap
+ for (i = 0; i <= highnum; i++) {
+ if (i != 0 && i % 32 == 0)
+ printf "\\n\\t"
+ # Additionally Hangul[11XX(17), AC00(172) - D7FF(215)] is decomposable.
+ if (blockmap[i] || i == 17 || (i >= 172 && i <= 215))
+ printf "1,"
+ else
+ printf "0,"
+ }
+ printf "\\n};\\n\\n"
+ #
+ # Output a macro to get a canonical combining class.
+ #
+ print "/* Get Canonical Combining Class(CCC). */"
+ printf "#define CCC(uc)\\t\\\\\n"
+ printf "\\t(((uc) > 0x%s)?0:\\\\\\n", max
+ printf "\\tccc_val[ccc_val_index[ccc_index[(uc)>>8]][((uc)>>4)&0x0F]][(uc)&0x0F])\\n"
+ print ""
+ #
+ # Output a canonical combining class value table.
+ #
+ midcnt = 0
+ printf "/* The table of the value of Canonical Cimbining Class */\\n"
+ print "static const unsigned char ccc_val[][16] = {"
+ print " /* idx=0: XXXX0 - XXXXF */"
+ print " { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },"
+ for (h = 0; h <= highnum; h++) {
+ if (!blockmap[h])
+ continue;
+ for (m = 0; m < 16; m++) {
+ if (!xx_blockmap[h, m])
+ continue;
+ midcnt++
+ printf " /* idx=%d: %03X%1X0 - %03X%1XF */\\n {", midcnt, h, m, h, m
+ for (l = 0; l < 15; l++) {
+ printf "%d, ", xxx_blockmap[h, m, l]
+ }
+ printf "%d },\n", xxx_blockmap[h, m, 15]
+ }
+ }
+ printf "};\n"
+ #
+ # Output the index table of the canonical combining class value table.
+ #
+ cnt = 0
+ midcnt = 0
+ printf "\\n/* The index table to ccc_val[*][16] */\\n"
+ print "static const unsigned char ccc_val_index[][16] = {"
+ print " /* idx=0: XXX00 - XXXFF */"
+ print " { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },"
+ for (h = 0; h <= highnum; h++) {
+ if (!blockmap[h])
+ continue;
+ cnt++
+ printf " /* idx=%d: %03X00 - %03XFF */\\n {", cnt, h, h
+ for (m = 0; m < 16; m++) {
+ if (m != 0)
+ printf ","
+ if (xx_blockmap[h, m]) {
+ midcnt++
+ printf "%2d", midcnt
+ } else
+ printf " 0"
+ }
+ printf " },\\n"
+ }
+ printf "};\\n"
+ #
+ # Output the index table to the index table of the canonical combining
+ # class value table.
+ #
+ printf "\\n/* The index table to ccc_val_index[*][16] */\\n"
+ printf "static const unsigned char ccc_index[] = {\\n ", h
+ cnt = 0
+ for (h = 0; h <= highnum; h++) {
+ if (h != 0 && h % 24 == 0)
+ printf "\\n "
+ if (blockmap[h]) {
+ cnt++;
+ printf "%2d,", cnt
+ } else
+ printf " 0,"
+ }
+ print "};"
+ print ""
+ print "#endif /* ARCHIVE_STRING_COMPOSITION_H_INCLUDED */"
+}
+#
+#
+function hextoi(hex)
+{
+ dec = 0
+ for (i=0; i < length(hex); i++) {
+ x = substr(hex, i+1, 1)
+ if (x ~/[0-9]/)
+ dec = dec * 16 + x;
+ else if (x == "A")
+ dec = dec * 16 + 10;
+ else if (x == "B")
+ dec = dec * 16 + 11;
+ else if (x == "C")
+ dec = dec * 16 + 12;
+ else if (x == "D")
+ dec = dec * 16 + 13;
+ else if (x == "E")
+ dec = dec * 16 + 14;
+ else if (x == "F")
+ dec = dec * 16 + 15;
+ }
+ return dec
+}
+#
+# Collect Canonical Combining Class values.
+#
+\$4 ~/^[0-9A-F]+$/ {
+ if (\$4 !~/^0$/) {
+ if (min == "") {
+ min = \$1
+ }
+ max = \$1
+ high = substr(\$1, 1, length(\$1) -2)
+ highnum = hextoi(high)
+ mid = substr(\$1, length(\$1) -1, 1)
+ midnum = hextoi(mid)
+ low = substr(\$1, length(\$1), 1)
+ lownum = hextoi(low)
+ blockmap[highnum] = 1
+ xx_blockmap[highnum, midnum] = 1
+ xxx_blockmap[highnum, midnum, lownum] = \$4
+ }
+}
+#
+# Following code points are not decomposed in MAC OS.
+# U+2000 - U+2FFF
+# U+F900 - U+FAFF
+# U+2F800 - U+2FAFF
+#
+#\$1 ~/^2[0-9A-F][0-9A-F][0-9A-F]\$/ {
+# next
+#}
+#\$1 ~/^F[9A][0-9A-F][0-9A-F]\$/ {
+# next
+#}
+#\$1 ~/^2F[89A][0-9A-F][0-9A-F]\$/ {
+# next
+#}
+#
+# Exclusion code points specified by
+# http://unicode.org/Public/UNIDATA/CompositionExclusions.txt
+##
+# 1. Script Specifices
+##
+\$1 ~/^095[89ABCDEF]\$/ {
+ next
+}
+\$1 ~/^09D[CDF]\$/ {
+ next
+}
+\$1 ~/^0A3[36]\$/ {
+ next
+}
+\$1 ~/^0A5[9ABE]\$/ {
+ next
+}
+\$1 ~/^0B5[CD]\$/ {
+ next
+}
+\$1 ~/^0F4[3D]\$/ {
+ next
+}
+\$1 ~/^0F5[27C]\$/ {
+ next
+}
+\$1 ~/^0F69\$/ {
+ next
+}
+\$1 ~/^0F7[68]\$/ {
+ next
+}
+\$1 ~/^0F9[3D]\$/ {
+ next
+}
+\$1 ~/^0FA[27C]\$/ {
+ next
+}
+\$1 ~/^0FB9\$/ {
+ next
+}
+\$1 ~/^FB1[DF]\$/ {
+ next
+}
+\$1 ~/^FB2[ABCDEF]\$/ {
+ next
+}
+\$1 ~/^FB3[012345689ABCE]\$/ {
+ next
+}
+\$1 ~/^FB4[01346789ABCDE]\$/ {
+ next
+}
+##
+# 2. Post Composition Version precomposed characters
+##
+\$1 ~/^2ADC\$/ {
+ next
+}
+\$1 ~/^1D15[EF]\$/ {
+ next
+}
+\$1 ~/^1D16[01234]\$/ {
+ next
+}
+\$1 ~/^1D1B[BCDEF]\$/ {
+ next
+}
+\$1 ~/^1D1C0\$/ {
+ next
+}
+##
+# 3. Singleton Decompositions
+##
+\$1 ~/^034[01]\$/ {
+ next
+}
+\$1 ~/^037[4E]\$/ {
+ next
+}
+\$1 ~/^0387\$/ {
+ next
+}
+\$1 ~/^1F7[13579BD]\$/ {
+ next
+}
+\$1 ~/^1FB[BE]\$/ {
+ next
+}
+\$1 ~/^1FC[9B]\$/ {
+ next
+}
+\$1 ~/^1FD[3B]\$/ {
+ next
+}
+\$1 ~/^1FE[3BEF]\$/ {
+ next
+}
+\$1 ~/^1FF[9BD]\$/ {
+ next
+}
+\$1 ~/^200[01]\$/ {
+ next
+}
+\$1 ~/^212[6AB]\$/ {
+ next
+}
+\$1 ~/^232[9A]\$/ {
+ next
+}
+\$1 ~/^F9[0-9A-F][0-9A-F]\$/ {
+ next
+}
+\$1 ~/^FA0[0-9A-D]\$/ {
+ next
+}
+\$1 ~/^FA1[025-9A-E]\$/ {
+ next
+}
+\$1 ~/^FA2[0256A-D]\$/ {
+ next
+}
+\$1 ~/^FA[3-5][0-9A-F]\$/ {
+ next
+}
+\$1 ~/^FA6[0-9A-D]\$/ {
+ next
+}
+\$1 ~/^FA[7-9A-C][0-9A-F]\$/ {
+ next
+}
+\$1 ~/^FAD[0-9]\$/ {
+ next
+}
+\$1 ~/^2F[89][0-9A-F][0-9A-F]\$/ {
+ next
+}
+\$1 ~/^2FA0[0-9A-F]\$/ {
+ next
+}
+\$1 ~/^2FA1[0-9A-D]\$/ {
+ next
+}
+##
+# 4. Non-Starter Decompositions
+##
+\$1 ~/^0344\$/ {
+ next
+}
+\$1 ~/^0F7[35]\$/ {
+ next
+}
+\$1 ~/^0F81\$/ {
+ next
+}
+#
+# Output combinations for NFD ==> NFC.
+#
+\$6 ~/^[0-9A-F]+ [0-9A-F]+\$/ {
+ split(\$6, cp, " ")
+ if (length(\$1) == 4)
+ print "0"cp[1], "0"cp[2], "0"\$1 | cmd
+ else
+ print cp[1], cp[2], \$1 | cmd
+}
+AWK_END
+#################################################################################
+#
+# Run awk a script.
+#
+#################################################################################
+append_copyright
+awk -f ${pickout} ${inputfile} >> ${outfile}
+#
+# Remove awk the script.
+rm ${pickout}
diff --git a/build/version b/build/version
index 4f810f734517..85738f4df655 100644
--- a/build/version
+++ b/build/version
@@ -1 +1 @@
-2008005
+3000003
diff --git a/configure.ac b/configure.ac
index 5a93cd674e6f..75c2ca3e99fa 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4,18 +4,20 @@ dnl First, define all of the version numbers up front.
dnl In particular, this allows the version macro to be used in AC_INIT
dnl These first two version numbers are updated automatically on each release.
-m4_define([LIBARCHIVE_VERSION_S],[2.8.5])
-m4_define([LIBARCHIVE_VERSION_N],[2008005])
+m4_define([LIBARCHIVE_VERSION_S],[3.0.3])
+m4_define([LIBARCHIVE_VERSION_N],[3000003])
dnl bsdtar and bsdcpio versioning tracks libarchive
m4_define([BSDTAR_VERSION_S],LIBARCHIVE_VERSION_S())
m4_define([BSDCPIO_VERSION_S],LIBARCHIVE_VERSION_S())
+AC_PREREQ(2.65)
+
#
# Now starts the "real" configure script.
#
-AC_INIT([libarchive],LIBARCHIVE_VERSION_S(),[kientzle@freebsd.org])
+AC_INIT([libarchive],LIBARCHIVE_VERSION_S(),[kientzle@FreeBSD.org])
# Make sure the srcdir contains "libarchive" directory
AC_CONFIG_SRCDIR([libarchive])
# Use auxiliary subscripts from this subdirectory (cleans up root)
@@ -25,15 +27,21 @@ AC_CONFIG_MACRO_DIR([build/autoconf])
# Must follow AC_CONFIG macros above...
AM_INIT_AUTOMAKE()
-# Libtool versioning uses different conventions on different
-# platforms. At least on FreeBSD, libtool uses an overly complex
-# convention that attempts to solve problems that most people just
-# don't have and which just causes confusion for most end users.
-ARCHIVE_MAJOR=$(( LIBARCHIVE_VERSION_N() / 1000000 ))
+# Libtool's "interface version" can be computed from the libarchive version.
+
+# Libtool interface version bumps on any API change, so increments
+# whenever libarchive minor version does.
ARCHIVE_MINOR=$(( (LIBARCHIVE_VERSION_N() / 1000) % 1000 ))
+# Libarchive 2.7 == libtool interface 9 = 2 + 7
+# Libarchive 2.8 == libtool interface 10 = 2 + 8
+# Libarchive 2.9 == libtool interface 11 = 2 + 8
+# Libarchive 3.0 == libtool interface 12
+# Libarchive 3.x == libtool interface 12 + x
+ARCHIVE_INTERFACE=`echo $((12 + ${ARCHIVE_MINOR}))`
+# Libarchive revision is bumped on any source change === libtool revision
ARCHIVE_REVISION=$(( LIBARCHIVE_VERSION_N() % 1000 ))
-ARCHIVE_LIBTOOL_MAJOR=`echo $((${ARCHIVE_MAJOR} + ${ARCHIVE_MINOR}))`
-ARCHIVE_LIBTOOL_VERSION=$ARCHIVE_LIBTOOL_MAJOR:$ARCHIVE_REVISION:$ARCHIVE_MINOR
+# Libarchive minor is bumped on any interface addition === libtool age
+ARCHIVE_LIBTOOL_VERSION=$ARCHIVE_INTERFACE:$ARCHIVE_REVISION:$ARCHIVE_MINOR
# Stick the version numbers into config.h
AC_DEFINE([LIBARCHIVE_VERSION_STRING],"LIBARCHIVE_VERSION_S()",
@@ -189,17 +197,47 @@ case $host in
;;
esac
+# We need CoreServices on Mac OS.
+case $host in
+ *darwin* )
+ LIBS="${LIBS} -framework CoreServices"
+ ;;
+esac
+
# Checks for header files.
AC_HEADER_DIRENT
AC_HEADER_SYS_WAIT
-AC_CHECK_HEADERS([acl/libacl.h attr/xattr.h ctype.h errno.h])
-AC_CHECK_HEADERS([ext2fs/ext2_fs.h fcntl.h grp.h])
-AC_CHECK_HEADERS([inttypes.h io.h langinfo.h limits.h linux/fs.h])
+AC_CHECK_HEADERS([acl/libacl.h attr/xattr.h copyfile.h ctype.h])
+AC_CHECK_HEADERS([errno.h ext2fs/ext2_fs.h fcntl.h grp.h])
+
+AC_CACHE_CHECK([whether EXT2_IOC_GETFLAGS is usable],
+ [ac_cv_have_decl_EXT2_IOC_GETFLAGS],
+ [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([@%:@include <sys/ioctl.h>
+@%:@include <ext2fs/ext2_fs.h>],
+ [int x = EXT2_IOC_GETFLAGS])],
+ [AS_VAR_SET([ac_cv_have_decl_EXT2_IOC_GETFLAGS], [yes])],
+ [AS_VAR_SET([ac_cv_have_decl_EXT2_IOC_GETFLAGS], [no])])])
+
+AS_VAR_IF([ac_cv_have_decl_EXT2_IOC_GETFLAGS], [yes],
+ [AC_DEFINE_UNQUOTED([HAVE_WORKING_EXT2_IOC_GETFLAGS], [1],
+ [Define to 1 if you have a working EXT2_IOC_GETFLAGS])])
+
+AC_CHECK_HEADERS([inttypes.h io.h langinfo.h limits.h])
+AC_CHECK_HEADERS([linux/fiemap.h linux/fs.h linux/magic.h])
AC_CHECK_HEADERS([locale.h paths.h poll.h pwd.h regex.h signal.h stdarg.h])
AC_CHECK_HEADERS([stdint.h stdlib.h string.h])
-AC_CHECK_HEADERS([sys/acl.h sys/cdefs.h sys/extattr.h sys/ioctl.h sys/mkdev.h])
-AC_CHECK_HEADERS([sys/param.h sys/poll.h sys/select.h sys/time.h sys/utime.h])
-AC_CHECK_HEADERS([time.h unistd.h utime.h wchar.h wctype.h windows.h])
+AC_CHECK_HEADERS([sys/acl.h sys/cdefs.h sys/extattr.h sys/ioctl.h])
+AC_CHECK_HEADERS([sys/mkdev.h sys/mount.h])
+AC_CHECK_HEADERS([sys/param.h sys/poll.h sys/select.h sys/statfs.h sys/statvfs.h])
+AC_CHECK_HEADERS([sys/time.h sys/utime.h sys/utsname.h sys/vfs.h])
+AC_CHECK_HEADERS([time.h unistd.h utime.h wchar.h wctype.h])
+AC_CHECK_HEADERS([windows.h])
+# check windows.h first; the other headers require it.
+AC_CHECK_HEADERS([wincrypt.h winioctl.h],[],[],
+[[#ifdef HAVE_WINDOWS_H
+# include <windows.h>
+#endif
+]])
# Checks for libraries.
AC_ARG_WITH([zlib],
@@ -226,6 +264,25 @@ if test "x$with_lzmadec" != "xno"; then
AC_CHECK_LIB(lzmadec,lzmadec_decode)
fi
+AC_ARG_WITH([iconv],
+ AS_HELP_STRING([--without-iconv], [Don't try to link against iconv]))
+
+if test "x$with_iconv" != "xno"; then
+ AC_CHECK_HEADERS([iconv.h],[],[],[#include <stdlib.h>])
+ AM_ICONV
+ if test "x$am_cv_func_iconv" = "xyes"; then
+ AC_CHECK_HEADERS([localcharset.h])
+ am_save_LIBS="$LIBS"
+ LIBS="${LIBS} ${LIBICONV}"
+ AC_CHECK_FUNCS([locale_charset])
+ LIBS="${am_save_LIBS}"
+ if test "x$ac_cv_func_locale_charset" != "xyes"; then
+ # If locale_charset() is not in libiconv, we have to find libcharset.
+ AC_CHECK_LIB(charset,locale_charset)
+ fi
+ fi
+fi
+
AC_ARG_WITH([lzma],
AS_HELP_STRING([--without-lzma], [Don't build support for xz through lzma]))
@@ -234,8 +291,13 @@ if test "x$with_lzma" != "xno"; then
AC_CHECK_LIB(lzma,lzma_stream_decoder)
fi
+AC_ARG_WITH([nettle],
+ AS_HELP_STRING([--without-nettle], [Don't build with crypto support from Nettle]))
AC_ARG_WITH([openssl],
AS_HELP_STRING([--without-openssl], [Don't build support for mtree and xar hashes through openssl]))
+case "$host_os" in
+ *darwin* ) with_openssl=no ;;
+esac
AC_ARG_WITH([xml2],
AS_HELP_STRING([--without-xml2], [Don't build support for xar through libxml2]))
@@ -247,9 +309,11 @@ if test "x$with_xml2" != "xno"; then
if test "x$XML2_CONFIG" != "x"; then
CPPFLAGS="${CPPFLAGS} `${XML2_CONFIG} --cflags`"
LIBS="${LIBS} `${XML2_CONFIG} --libs`"
+ AC_CHECK_LIB(xml2,xmlInitParser,[true],AC_MSG_FAILURE(Missing xml2 library))
+ else
+ AC_CHECK_LIB(xml2,xmlInitParser)
fi
- AC_CHECK_HEADERS([libxml/xmlreader.h])
- AC_CHECK_LIB(xml2,xmlInitParser)
+ AC_CHECK_HEADERS([libxml/xmlreader.h libxml/xmlwriter.h])
fi
if test "x$ac_cv_header_libxml_xmlreader_h" != "xyes"; then
if test "x$with_expat" != "xno"; then
@@ -258,72 +322,6 @@ if test "x$ac_cv_header_libxml_xmlreader_h" != "xyes"; then
fi
fi
-AC_DEFUN([MD_CHECK], [
- if test "$found_$1" != yes; then
- saved_LIBS="$LIBS"
- saved_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS -I$srcdir/libarchive"
- if test $ac_cv_header_sys_types_h = yes; then
- CPPFLAGS="$CPPFLAGS -DHAVE_SYS_TYPES_H=1"
- fi
- LIBS="$LIBS $4"
- AC_MSG_CHECKING([support for ARCHIVE_HASH_$1_$2])
- AC_LINK_IFELSE([
-#define $1_COMPILE_TEST
-#define ARCHIVE_HASH_$1_$2
-#define __LIBARCHIVE_BUILD
-#include "archive_hash.h"
-
-int
-main(int argc, char **argv)
-{
- archive_$3_ctx ctx;
-
- archive_$3_init(&ctx);
- archive_$3_update(&ctx, *argv, argc);
- archive_$3_final(&ctx, *argv);
- return 0;
-}
-],
- [ AC_MSG_RESULT([yes])
- found_$1=yes
- mdLIBS="$mdLIBS $4"
- AC_DEFINE(ARCHIVE_HASH_$1_$2, 1, [ $1 via ARCHIVE_HASH_$1_$2 supported.])
- ],
- [ AC_MSG_RESULT([no])])
- LIBS="$saved_LIBS"
- CPPFLAGS="$saved_CPPFLAGS"
- fi
-])
-
-MD_CHECK(MD5, LIBC, md5)
-MD_CHECK(MD5, LIBSYSTEM, md5)
-MD_CHECK(RMD160, LIBC, rmd160)
-MD_CHECK(SHA1, LIBC, sha1)
-MD_CHECK(SHA1, LIBSYSTEM, sha1)
-MD_CHECK(SHA256, LIBC, sha256)
-MD_CHECK(SHA256, LIBC2, sha256)
-MD_CHECK(SHA256, LIBC3, sha256)
-MD_CHECK(SHA256, LIBSYSTEM, sha256)
-MD_CHECK(SHA384, LIBC, sha384)
-MD_CHECK(SHA384, LIBC2, sha384)
-MD_CHECK(SHA384, LIBC3, sha384)
-MD_CHECK(SHA384, LIBSYSTEM, sha384)
-MD_CHECK(SHA512, LIBC, sha512)
-MD_CHECK(SHA512, LIBC2, sha512)
-MD_CHECK(SHA512, LIBC3, sha512)
-MD_CHECK(SHA512, LIBSYSTEM, sha512)
-
-if test "x$with_openssl" != "xno"; then
- MD_CHECK(MD5, OPENSSL, md5, -lcrypto)
- MD_CHECK(RMD160, OPENSSL, rmd160, -lcrypto)
- MD_CHECK(SHA1, OPENSSL, sha1, -lcrypto)
- MD_CHECK(SHA256, OPENSSL, sha256, -lcrypto)
- MD_CHECK(SHA384, OPENSSL, sha384, -lcrypto)
- MD_CHECK(SHA512, OPENSSL, sha512, -lcrypto)
-fi
-LIBS="$LIBS $mdLIBS"
-
# TODO: Give the user the option of using a pre-existing system
# libarchive. This will define HAVE_LIBARCHIVE which will cause
# bsdtar_platform.h to use #include <...> for the libarchive headers.
@@ -344,6 +342,19 @@ AC_TYPE_SIZE_T
AC_CHECK_TYPE(id_t, [unsigned long])
AC_CHECK_TYPE(uintptr_t, [unsigned int])
+# Check for tm_gmtoff in struct tm
+AC_CHECK_MEMBERS([struct tm.tm_gmtoff, struct tm.__tm_gmtoff],,,
+[
+#include <time.h>
+])
+
+# Check for f_namemax in struct statfs
+AC_CHECK_MEMBERS([struct statfs.f_namemax],,,
+[
+#include <sys/param.h>
+#include <sys/mount.h>
+])
+
# Check for birthtime in struct stat
AC_CHECK_MEMBERS([struct stat.st_birthtime])
@@ -364,14 +375,24 @@ AC_CHECK_MEMBERS([struct stat.st_flags])
# TODO: Check for %ju and %llu support directly.
AC_CHECK_TYPES([uintmax_t, unsigned long long])
-# We need int64_t, uint64_t, intmax_t, and uintmax_t
+# We use C99-style integer types
+# Declare them if the local platform doesn't already do so.
AC_TYPE_INTMAX_T
-AC_TYPE_INT64_T
AC_TYPE_UINTMAX_T
+AC_TYPE_INT64_T
AC_TYPE_UINT64_T
+AC_TYPE_INT32_T
+AC_TYPE_UINT32_T
+AC_TYPE_INT16_T
+AC_TYPE_UINT16_T
+AC_TYPE_UINT8_T
-# TODO: If any of these are missing, define them right here.
-AC_CHECK_DECLS([SIZE_MAX, SSIZE_MAX, INT64_MAX, INT64_MIN, UINT64_MAX, UINT32_MAX])
+AC_CHECK_DECLS([SIZE_MAX, INT64_MAX, INT64_MIN, UINT64_MAX, UINT32_MAX])
+
+AC_CHECK_DECL([SSIZE_MAX],
+ [AC_DEFINE(HAVE_DECL_SSIZE_MAX, 1, [Define to 1 if you have the declaration of `SSIZE_MAX', and to 0 if you don't.])],
+ [],
+ [#include <limits.h>])
AC_CHECK_DECL([EFTYPE],
[AC_DEFINE(HAVE_EFTYPE, 1, [A possible errno value for invalid file format errors])],
@@ -403,20 +424,34 @@ AC_FUNC_VPRINTF
# To avoid necessity for including windows.h or special forward declaration
# workarounds, we use 'void *' for 'struct SECURITY_ATTRIBUTES *'
AC_CHECK_STDCALL_FUNC([CreateHardLinkA],[const char *, const char *, void *])
-AC_CHECK_FUNCS([chflags chown chroot])
-AC_CHECK_FUNCS([fchdir fchflags fchmod fchown fcntl fork])
-AC_CHECK_FUNCS([fstat ftruncate futimens futimes geteuid getpid])
-AC_CHECK_FUNCS([getgrgid_r getgrnam_r getpwnam_r getpwuid_r ])
-AC_CHECK_FUNCS([lchflags lchmod lchown link lstat])
-AC_CHECK_FUNCS([lutimes memmove memset mkdir mkfifo mknod])
-AC_CHECK_FUNCS([nl_langinfo pipe poll readlink])
-AC_CHECK_FUNCS([select setenv setlocale sigaction])
+AC_CHECK_FUNCS([chflags chown chroot ctime_r])
+AC_CHECK_FUNCS([fchdir fchflags fchmod fchown fcntl fdopendir fork])
+AC_CHECK_FUNCS([fstat fstatat fstatfs fstatvfs ftruncate])
+AC_CHECK_FUNCS([futimens futimes futimesat])
+AC_CHECK_FUNCS([geteuid getpid getgrgid_r getgrnam_r])
+AC_CHECK_FUNCS([getpwnam_r getpwuid_r getvfsbyname gmtime_r])
+AC_CHECK_FUNCS([lchflags lchmod lchown link localtime_r lstat lutimes])
+AC_CHECK_FUNCS([mbrtowc mbsnrtowcs memmove memset])
+AC_CHECK_FUNCS([mkdir mkfifo mknod mkstemp])
+AC_CHECK_FUNCS([nl_langinfo openat pipe poll readlink readlinkat])
+AC_CHECK_FUNCS([select setenv setlocale sigaction statfs statvfs])
AC_CHECK_FUNCS([strchr strdup strerror strncpy_s strrchr symlink timegm])
AC_CHECK_FUNCS([tzset unsetenv utime utimensat utimes vfork])
-AC_CHECK_FUNCS([wcrtomb wcscmp wcscpy wcslen wctomb wmemcmp wmemcpy])
+AC_CHECK_FUNCS([wcrtomb wcscmp wcscpy wcslen wcsnrtombs wctomb wmemcmp wmemcpy])
+AC_CHECK_FUNCS([_ctime64_s _fseeki64])
+AC_CHECK_FUNCS([_get_timezone _localtime64_s _mkgmtime64])
# detects cygwin-1.7, as opposed to older versions
AC_CHECK_FUNCS([cygwin_conv_path])
+# There are several variants of readdir_r around; we only
+# accept the POSIX-compliant version.
+AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[#include <dirent.h>]],
+ [[DIR *dir; struct dirent e, *r;
+ return(readdir_r(dir, &e, &r));]])],
+ [AC_DEFINE(HAVE_READDIR_R,1,[Define to 1 if you have a POSIX compatible readdir_r])]
+)
+
# FreeBSD's nl_langinfo supports an option to specify whether the
# current locale uses month/day or day/month ordering. It makes the
# output a little prettier...
@@ -444,12 +479,14 @@ AC_ARG_ENABLE([xattr],
if test "x$enable_xattr" != "xno"; then
AC_CHECK_HEADERS([attr/xattr.h])
- AC_CHECK_HEADERS([sys/xattr.h])
+ AC_CHECK_HEADERS([sys/xattr.h sys/ea.h])
AC_CHECK_LIB(attr,setxattr)
AC_CHECK_FUNCS([extattr_get_file extattr_list_file])
AC_CHECK_FUNCS([extattr_set_fd extattr_set_file])
- AC_CHECK_FUNCS([fsetxattr getxattr])
+ AC_CHECK_FUNCS([fgetxattr flistxattr fsetxattr getxattr])
AC_CHECK_FUNCS([lgetxattr listxattr llistxattr lsetxattr])
+ AC_CHECK_FUNCS([fgetea flistea fsetea getea])
+ AC_CHECK_FUNCS([lgetea listea llistea lsetea])
AC_CHECK_DECLS([EXTATTR_NAMESPACE_USER], [], [], [#include <sys/types.h>
#include <sys/extattr.h>
])
@@ -505,4 +542,91 @@ fi
# Additional requirements
AC_SYS_LARGEFILE
+dnl NOTE: Crypto checks must run last.
+AC_DEFUN([CRYPTO_CHECK], [
+ if test "$found_$1" != yes; then
+ saved_LIBS="$LIBS"
+ saved_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive"
+ LIBS="$LIBS $mdLIBS $4"
+ touch "check_crypto_md.h"
+ AC_MSG_CHECKING([support for ARCHIVE_CRYPTO_$1_$2])
+ AC_LINK_IFELSE([AC_LANG_SOURCE([
+#define ARCHIVE_$1_COMPILE_TEST
+#define ARCHIVE_CRYPTO_$1_$2
+#define PLATFORM_CONFIG_H "check_crypto_md.h"
+
+$(cat "$srcdir/libarchive/archive_crypto.c")
+
+int
+main(int argc, char **argv)
+{
+ archive_$3_ctx ctx;
+ archive_$3_init(&ctx);
+ archive_$3_update(&ctx, *argv, argc);
+ archive_$3_final(&ctx, NULL);
+ return 0;
+}
+])],
+ [ AC_MSG_RESULT([yes])
+ found_$1=yes
+ if [[ -n "$4" ]]; then
+ # The .$4 avoids -e, which doesn't work on Solaris 10
+ # The _$mdLIBS allows .$4 to match at beginning of string <sigh>
+ test -n "$(echo _$mdLIBS | $GREP .$4)" || mdLIBS="$mdLIBS $4"
+ fi
+ AC_DEFINE(ARCHIVE_CRYPTO_$1_$2, 1, [ $1 via ARCHIVE_CRYPTO_$1_$2 supported.])
+ ],
+ [ AC_MSG_RESULT([no])])
+ LIBS="$saved_LIBS"
+ CPPFLAGS="$saved_CPPFLAGS"
+ rm "check_crypto_md.h"
+ fi
+])
+
+CRYPTO_CHECK(MD5, LIBC, md5)
+CRYPTO_CHECK(MD5, LIBSYSTEM, md5)
+CRYPTO_CHECK(RMD160, LIBC, rmd160)
+CRYPTO_CHECK(SHA1, LIBC, sha1)
+CRYPTO_CHECK(SHA1, LIBSYSTEM, sha1)
+CRYPTO_CHECK(SHA256, LIBC, sha256)
+CRYPTO_CHECK(SHA256, LIBC2, sha256)
+CRYPTO_CHECK(SHA256, LIBC3, sha256)
+CRYPTO_CHECK(SHA256, LIBSYSTEM, sha256)
+CRYPTO_CHECK(SHA384, LIBC, sha384)
+CRYPTO_CHECK(SHA384, LIBC2, sha384)
+CRYPTO_CHECK(SHA384, LIBC3, sha384)
+CRYPTO_CHECK(SHA384, LIBSYSTEM, sha384)
+CRYPTO_CHECK(SHA512, LIBC, sha512)
+CRYPTO_CHECK(SHA512, LIBC2, sha512)
+CRYPTO_CHECK(SHA512, LIBC3, sha512)
+CRYPTO_CHECK(SHA512, LIBSYSTEM, sha512)
+
+if test "x$with_nettle" != "xno"; then
+ CRYPTO_CHECK(MD5, NETTLE, md5, -lnettle)
+ CRYPTO_CHECK(RMD160, NETTLE, rmd160, -lnettle)
+ CRYPTO_CHECK(SHA1, NETTLE, sha1, -lnettle)
+ CRYPTO_CHECK(SHA256, NETTLE, sha256, -lnettle)
+ CRYPTO_CHECK(SHA384, NETTLE, sha384, -lnettle)
+ CRYPTO_CHECK(SHA512, NETTLE, sha512, -lnettle)
+fi
+if test "x$with_openssl" != "xno"; then
+ CRYPTO_CHECK(MD5, OPENSSL, md5, -lcrypto)
+ CRYPTO_CHECK(RMD160, OPENSSL, rmd160, -lcrypto)
+ CRYPTO_CHECK(SHA1, OPENSSL, sha1, -lcrypto)
+ CRYPTO_CHECK(SHA256, OPENSSL, sha256, -lcrypto)
+ CRYPTO_CHECK(SHA384, OPENSSL, sha384, -lcrypto)
+ CRYPTO_CHECK(SHA512, OPENSSL, sha512, -lcrypto)
+fi
+
+# Probe libmd AFTER OpenSSL/libcrypto.
+# The two are incompatible and OpenSSL is more complete.
+CRYPTO_CHECK(MD5, LIBMD, md5, -lmd)
+CRYPTO_CHECK(RMD160, LIBMD, rmd160, -lmd)
+CRYPTO_CHECK(SHA1, LIBMD, sha1, -lmd)
+CRYPTO_CHECK(SHA256, LIBMD, sha256, -lmd)
+CRYPTO_CHECK(SHA512, LIBMD, sha512, -lmd)
+
+LIBS="$LIBS $mdLIBS"
+
AC_OUTPUT
diff --git a/contrib/README b/contrib/README
index 2eb0114ff569..8ad352a30204 100644
--- a/contrib/README
+++ b/contrib/README
@@ -1,5 +1,6 @@
Many people have graciously sent me configuration
-files and other useful tidbits for use with libarchive.
+files, small programs that use libarchive, and other
+useful and interesting tidbits.
I do not support or use any of these; but if you can use them, enjoy!
@@ -30,3 +31,29 @@ libarchive.1aix53.spec
As above, for use on AIX5.3.
======================================================================
+
+psota-benchmark
+
+Some scripts used by Jan Psota in benchmarking
+various tar implementations.
+
+I've edited his results slightly to correctly reflect that
+bsdtar does not support a "compare" operation.
+
+======================================================================
+
+shar
+
+A simple shar program written on top of libarchive.
+
+======================================================================
+
+untar.c
+
+A very simple and very portable standalone program that can
+extract basic ustar archives.
+This does not use libarchive and so can be used to extract
+the libarchive distribution on any system that has a C compiler
+but does not have a tar program.
+
+======================================================================
diff --git a/contrib/libarchive.1aix53.spec b/contrib/libarchive.1aix53.spec
index 1c3bb7d1ed61..fe81d147e03e 100644
--- a/contrib/libarchive.1aix53.spec
+++ b/contrib/libarchive.1aix53.spec
@@ -1,4 +1,4 @@
-# $LastChangedRevision: 8 $, $LastChangedDate: 2008-05-01 00:11:33 +0200 (št , 01 máj 2008) $
+# $LastChangedRevision$, $LastChangedDate$
Summary: Library to create and read several different archive formats
Summary(pl): Biblioteka do tworzenia i odczytu ró¿nych formatów archiwów
Name: libarchive
@@ -140,7 +140,7 @@ Revision 1.6 2006/11/15 10:41:28 qboosh
Revision 1.5 2006/11/08 22:22:25 twittner
- up to 1.3.1
- added BR: e2fsprogs-devel
-- added -CVE-2006-5680.patch agains entering in infinite
+- added -CVE-2006-5680.patch against entering an infinite
loop in corrupt archives
- added bsdtar package (bsdtar is included now in libarchive
sources)
diff --git a/contrib/libarchive.spec b/contrib/libarchive.spec
index 1b81f6dc964a..b5b658a874b1 100644
--- a/contrib/libarchive.spec
+++ b/contrib/libarchive.spec
@@ -1,4 +1,4 @@
-# $LastChangedRevision: 8 $, $LastChangedDate: 2008-05-01 00:11:33 +0200 (št , 01 máj 2008) $
+# $LastChangedRevision$, $LastChangedDate$
Summary: Library to create and read several different archive formats
Summary(pl): Biblioteka do tworzenia i odczytu ró¿nych formatów archiwów
Name: libarchive
@@ -127,7 +127,7 @@ Revision 1.6 2006/11/15 10:41:28 qboosh
Revision 1.5 2006/11/08 22:22:25 twittner
- up to 1.3.1
- added BR: e2fsprogs-devel
-- added -CVE-2006-5680.patch agains entering in infinite
+- added -CVE-2006-5680.patch against entering an infinite
loop in corrupt archives
- added bsdtar package (bsdtar is included now in libarchive
sources)
diff --git a/contrib/psota-benchmark/results.txt b/contrib/psota-benchmark/results.txt
index 8197b28f7eae..2d364c5558dd 100644
--- a/contrib/psota-benchmark/results.txt
+++ b/contrib/psota-benchmark/results.txt
@@ -1,4 +1,4 @@
-ODP: [Bug-tar] GNU tar, star and BSD tar speed comparision +new script
+ODP: [Bug-tar] GNU tar, star and BSD tar speed comparison +new script
Jan Psota
Thu, 25 Oct 2007 06:51:13 -0700
@@ -120,3 +120,17 @@ star extract 100.814 0.400 39.906 39.98 20849 KB/s
bsdtar compare 0.003 0.000 0.004 100.00 700657000 KB/s
gnutar compare 80.174 3.932 20.365 30.30 26217 KB/s
star compare 73.911 8.341 27.670 48.72 28439 KB/s
+
+=============================================================
+
+Note by Tim Kientzle: The "bsdtar compare" results here are
+invalid since bsdtar does not support that operation.
+For the list numbers, note that libarchive automatically optimizes
+list operations on uncompressed tar archives on disk by using lseek()
+to skip over the bodies of entries. GNU tar added an option to
+provide the same feature.
+
+The biggest problem with these tests is that they only
+cover uncompressed archives stored on disk. The results for
+compressed archives and/or archives stored on tape are
+likely quite different.
diff --git a/contrib/psota-benchmark/tcp.sh b/contrib/psota-benchmark/tcp.sh
index 6c0e4b5e92e5..3f630732be7c 100644
--- a/contrib/psota-benchmark/tcp.sh
+++ b/contrib/psota-benchmark/tcp.sh
@@ -1,9 +1,9 @@
#!/bin/sh
-# tar comparision program
+# tar comparison program
# 2007-10-25 Jan Psota
n=3 # number of repetitions
-TAR=(bsdtar gnutar star) # TApeArchivers to compare
+TAR="bsdtar gnutar star" # Tape archivers to compare
OPT=("" "--seek" "-no-fsync")
pax="--format=pax" # comment out for defaults
OPN=(create list extract compare) # operations
@@ -16,9 +16,9 @@ test $# -ge 2 || {
[where_to_extract_it]
TCP, version $version
-TCP stands for Tar Comparision Program here.
+TCP stands for Tar Comparison Program here.
It currently compares: BSD tar (bsdtar), GNU tar (gnutar) and star in archive
-creation, listing, extraction and archive-to-extracted comparision.
+creation, listing, extraction and archive-to-extracted comparison.
Tcp prints out best time of n=$n repetitions.
Tcp creates temporary archive named tcp.tar with $pax and some native
@@ -60,15 +60,21 @@ test -e /etc/gentoo-release \
&& gcc --version | head -1 && grep ^CFLAGS /etc/make.conf
# tar versions
+t=
echo
-for tar in [EMAIL PROTECTED]; do echo -ne "$tar:\t"; $tar --version | head -1;
+for tar in $TAR; do
+ if which $tar &> /dev/null; then
+ t="$t $tar";
+ echo -ne "$tar:\t"; $tar --version | head -1;
+ fi
done
+TAR="$t"
+
echo -e "\nbest time of $n repetitions,\n"\
" src=$src, "\
`du -sh $src | awk '{print $1}'`" in "`find $src | wc -l`" files, "\
-"avg "$((`du -sk $src | awk '{print $1}'`/`find $src -type f | wc
--l`))"KB/file,\n"\
+"avg "$((`du -sk $src | awk '{print $1}'`/`find $src -type f | wc -l`))"KB/file,\n"\
" archive=$dst, extract to $dst_path"
echo -e "program\toperation\treal\tuser\tsystem\t%CPU\t speed"
@@ -77,7 +83,7 @@ let op_num=0
for op in "cf $dst $pax -C $src ." "tf $dst" "xf $dst -C $dst_path" \
"f $dst -C $dst_path --diff"; do
let tar_num=0
- for tar in [EMAIL PROTECTED]; do
+ for tar in $TAR; do
echo -en "$tar\t${OPN[op_num]}\t"
for ((i=1; i<=$n; i++)); do
echo $op | grep -q ^cf && rm -f $dst
diff --git a/contrib/shar/shar.c b/contrib/shar/shar.c
index 12c84255309f..6d5c206e2a51 100644
--- a/contrib/shar/shar.c
+++ b/contrib/shar/shar.c
@@ -269,7 +269,7 @@ shar_write(char **fn, size_t nfn)
}
}
- if (archive_write_finish(a) != ARCHIVE_OK)
+ if (archive_write_free(a) != ARCHIVE_OK)
errx(EXIT_FAILURE, "%s", archive_error_string(a));
if (error != 0)
diff --git a/contrib/untar.c b/contrib/untar.c
index dc092d325e02..c4cc2bf9bea2 100644
--- a/contrib/untar.c
+++ b/contrib/untar.c
@@ -38,7 +38,7 @@ parseoct(const char *p, size_t n)
{
int i = 0;
- while (*p < '0' || *p > '7') {
+ while ((*p < '0' || *p > '7') && n > 0) {
++p;
--n;
}
@@ -140,7 +140,7 @@ untar(FILE *a, const char *path)
if (bytes_read < 512) {
fprintf(stderr,
"Short read on %s: expected 512, got %d\n",
- path, bytes_read);
+ path, (int)bytes_read);
return;
}
if (is_end_of_archive(buff)) {
@@ -183,7 +183,7 @@ untar(FILE *a, const char *path)
if (bytes_read < 512) {
fprintf(stderr,
"Short read on %s: Expected 512, got %d\n",
- path, bytes_read);
+ path, (int)bytes_read);
return;
}
if (filesize < 512)
diff --git a/cpio/bsdcpio.1 b/cpio/bsdcpio.1
index 789ce74e1c48..1355130c5911 100644
--- a/cpio/bsdcpio.1
+++ b/cpio/bsdcpio.1
@@ -24,8 +24,8 @@
.\"
.\" $FreeBSD$
.\"
-.Dd September 5, 2010
-.Dt BSDCPIO 1
+.Dd December 21, 2007
+.Dt CPIO 1
.Os
.Sh NAME
.Nm cpio
@@ -59,7 +59,7 @@ is a mode indicator from the following list:
.Bl -tag -compact -width indent
.It Fl i
Input.
-Read an archive from standard input (unless overriden) and extract the
+Read an archive from standard input (unless overridden) and extract the
contents to disk or (if the
.Fl t
option is specified)
@@ -69,7 +69,7 @@ one of the patterns will be extracted.
.It Fl o
Output.
Read a list of filenames from standard input and produce a new archive
-on standard output (unless overriden) containing the specified items.
+on standard output (unless overridden) containing the specified items.
.It Fl p
Pass-through.
Read a list of filenames from standard input and copy the files to the
@@ -80,7 +80,7 @@ specified directory.
Unless specifically stated otherwise, options are applicable in
all operating modes.
.Bl -tag -width indent
-.It Fl 0
+.It Fl 0 , Fl Fl null
Read filenames separated by NUL characters instead of newlines.
This is necessary if any of the filenames being read might contain newlines.
.It Fl A
@@ -102,8 +102,8 @@ bytes.
(o mode only)
Use the old POSIX portable character format.
Equivalent to
-.Fl -format Ar odc .
-.It Fl d
+.Fl Fl format Ar odc .
+.It Fl d , Fl Fl make-directories
(i and p modes)
Create directories as necessary.
.It Fl E Ar file
@@ -111,14 +111,14 @@ Create directories as necessary.
Read list of file name patterns from
.Ar file
to list and extract.
-.It Fl F Ar file
+.It Fl F Ar file , Fl Fl file Ar file
Read archive from or write archive to
.Ar file .
.It Fl f Ar pattern
(i mode only)
Ignore files that match
.Ar pattern .
-.It Fl -format Ar format
+.It Fl H Ar format , Fl Fl format Ar format
(o mode only)
Produce the output archive in the specified format.
Supported formats include:
@@ -145,24 +145,21 @@ for more complete information about the
formats currently supported by the underlying
.Xr libarchive 3
library.
-.It Fl H Ar format
-Synonym for
-.Fl -format .
-.It Fl h , Fl -help
+.It Fl h , Fl Fl help
Print usage information.
.It Fl I Ar file
Read archive from
.Ar file .
-.It Fl i
+.It Fl i , Fl Fl extract
Input mode.
See above for description.
-.It Fl -insecure
+.It Fl Fl insecure
(i and p mode only)
Disable security checks during extraction or copying.
This allows extraction via symbolic links and path names containing
.Sq ..
in the name.
-.It Fl J
+.It Fl J , Fl Fl xz
(o mode only)
Compress the file with xz-compatible compression before writing it.
In input mode, this option is ignored; xz compression is recognized
@@ -175,20 +172,20 @@ Synonym for
All symbolic links will be followed.
Normally, symbolic links are archived and copied as symbolic links.
With this option, the target of the link will be archived or copied instead.
-.It Fl l
+.It Fl l , Fl Fl link
(p mode only)
Create links from the target directory to the original files,
instead of copying.
-.It Fl lzma
+.It Fl Fl lzma
(o mode only)
Compress the file with lzma-compatible compression before writing it.
In input mode, this option is ignored; lzma compression is recognized
automatically on input.
-.It Fl m
+.It Fl m , Fl Fl preserve-modification-time
(i and p modes)
Set file modification time on created files to match
those in the source.
-.It Fl n
+.It Fl n , Fl Fl numeric-uid-gid
(i mode, only with
.Fl t )
Display numeric uid and gid.
@@ -197,26 +194,26 @@ By default,
displays the user and group names when they are provided in the
archive, or looks up the user and group names in the system
password database.
-.It Fl no-preserve-owner
+.It Fl Fl no-preserve-owner
(i mode only)
Do not attempt to restore file ownership.
This is the default when run by non-root users.
.It Fl O Ar file
Write archive to
.Ar file .
-.It Fl o
+.It Fl o , Fl Fl create
Output mode.
See above for description.
-.It Fl p
+.It Fl p , Fl Fl pass-through
Pass-through mode.
See above for description.
-.It Fl preserve-owner
+.It Fl Fl preserve-owner
(i mode only)
Restore file ownership.
This is the default when run by the root user.
-.It Fl -quiet
+.It Fl Fl quiet
Suppress unnecessary messages.
-.It Fl R Oo user Oc Ns Oo : Oc Ns Oo group Oc
+.It Fl R Oo user Oc Ns Oo : Oc Ns Oo group Oc , Fl Fl owner Oo user Oc Ns Oo : Oc Ns Oo group Oc
Set the owner and/or group on files in the output.
If group is specified with no user
(for example,
@@ -244,20 +241,24 @@ containing the name of the file and a line is read from
If the line read is blank, the file is skipped.
If the line contains a single period, the file is processed normally.
Otherwise, the line is taken to be the new name of the file.
-.It Fl t
+.It Fl t , Fl Fl list
(i mode only)
List the contents of the archive to stdout;
do not restore the contents to disk.
-.It Fl u
+.It Fl u , Fl Fl unconditional
(i and p modes)
Unconditionally overwrite existing files.
Ordinarily, an older file will not overwrite a newer file on disk.
-.It Fl v
+.It Fl V , Fl Fl dot
+Print a dot to stderr for each file as it is processed.
+Superseded by
+.Fl v .
+.It Fl v , Fl Fl verbose
Print the name of each file to stderr as it is processed.
With
.Fl t ,
provide a detailed listing of each file.
-.It Fl -version
+.It Fl Fl version
Print the program version information and exit.
.It Fl y
(o mode only)
@@ -275,6 +276,8 @@ Compress the archive with gzip-compatible compression before writing it.
In input mode, this option is ignored;
gzip compression is recognized automatically on input.
.El
+.Sh EXIT STATUS
+.Ex -std
.Sh ENVIRONMENT
The following environment variables affect the execution of
.Nm :
@@ -290,8 +293,6 @@ See
.Xr environ 7
for more information.
.El
-.Sh EXIT STATUS
-.Ex -std
.Sh EXAMPLES
The
.Nm
diff --git a/cpio/cmdline.c b/cpio/cmdline.c
index ada549953ddf..390aebc8fb85 100644
--- a/cpio/cmdline.c
+++ b/cpio/cmdline.c
@@ -51,7 +51,7 @@ __FBSDID("$FreeBSD: src/usr.bin/cpio/cmdline.c,v 1.5 2008/12/06 07:30:40 kientzl
/*
* Short options for cpio. Please keep this sorted.
*/
-static const char *short_options = "0AaBC:cdE:F:f:H:hI:iJjLlmnO:opR:rtuvW:yZz";
+static const char *short_options = "0AaBC:cdE:F:f:H:hI:iJjLlmnO:opR:rtuVvW:yZz";
/*
* Long options for cpio. Please keep this sorted.
@@ -62,6 +62,7 @@ static const struct option {
int equivalent; /* Equivalent short option. */
} cpio_longopts[] = {
{ "create", 0, 'o' },
+ { "dot", 0, 'V' },
{ "extract", 0, 'i' },
{ "file", 1, 'F' },
{ "format", 1, 'H' },
@@ -109,7 +110,7 @@ cpio_getopt(struct cpio *cpio)
int opt = '?';
int required = 0;
- cpio->optarg = NULL;
+ cpio->argument = NULL;
/* First time through, initialize everything. */
if (state == state_start) {
@@ -188,7 +189,7 @@ cpio_getopt(struct cpio *cpio)
long_prefix = "-W "; /* For clearer errors. */
} else {
state = state_next_word;
- cpio->optarg = opt_word;
+ cpio->argument = opt_word;
}
}
}
@@ -202,7 +203,7 @@ cpio_getopt(struct cpio *cpio)
p = strchr(opt_word, '=');
if (p != NULL) {
optlength = (size_t)(p - opt_word);
- cpio->optarg = (char *)(uintptr_t)(p + 1);
+ cpio->argument = (char *)(uintptr_t)(p + 1);
} else {
optlength = strlen(opt_word);
}
@@ -241,9 +242,9 @@ cpio_getopt(struct cpio *cpio)
/* We've found a unique match; does it need an argument? */
if (match->required) {
/* Argument required: get next word if necessary. */
- if (cpio->optarg == NULL) {
- cpio->optarg = *cpio->argv;
- if (cpio->optarg == NULL) {
+ if (cpio->argument == NULL) {
+ cpio->argument = *cpio->argv;
+ if (cpio->argument == NULL) {
lafe_warnc(0,
"Option %s%s requires an argument",
long_prefix, match->name);
@@ -254,7 +255,7 @@ cpio_getopt(struct cpio *cpio)
}
} else {
/* Argument forbidden: fail if there is one. */
- if (cpio->optarg != NULL) {
+ if (cpio->argument != NULL) {
lafe_warnc(0,
"Option %s%s does not allow an argument",
long_prefix, match->name);
@@ -340,7 +341,7 @@ owner_parse(const char *spec, int *uid, int *gid)
} else {
char *end;
errno = 0;
- *uid = strtoul(user, &end, 10);
+ *uid = (int)strtoul(user, &end, 10);
if (errno || *end != '\0') {
snprintf(errbuff, sizeof(errbuff),
"Couldn't lookup user ``%s''", user);
@@ -358,7 +359,7 @@ owner_parse(const char *spec, int *uid, int *gid)
} else {
char *end;
errno = 0;
- *gid = strtoul(g, &end, 10);
+ *gid = (int)strtoul(g, &end, 10);
if (errno || *end != '\0') {
snprintf(errbuff, sizeof(errbuff),
"Couldn't lookup group ``%s''", g);
diff --git a/cpio/cpio.c b/cpio/cpio.c
index 29f405c091ee..025c50cfafd2 100644
--- a/cpio/cpio.c
+++ b/cpio/cpio.c
@@ -50,9 +50,15 @@ __FBSDID("$FreeBSD: src/usr.bin/cpio/cpio.c,v 1.15 2008/12/06 07:30:40 kientzle
#ifdef HAVE_GRP_H
#include <grp.h>
#endif
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#endif
#ifdef HAVE_PWD_H
#include <pwd.h>
#endif
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
#ifdef HAVE_STDARG_H
#include <stdarg.h>
#endif
@@ -69,9 +75,6 @@ __FBSDID("$FreeBSD: src/usr.bin/cpio/cpio.c,v 1.15 2008/12/06 07:30:40 kientzle
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
#ifdef HAVE_TIME_H
#include <time.h>
#endif
@@ -136,6 +139,16 @@ main(int argc, char *argv[])
cpio->buff = buff;
cpio->buff_size = sizeof(buff);
+#if defined(HAVE_SIGACTION) && defined(SIGPIPE)
+ { /* Ignore SIGPIPE signals. */
+ struct sigaction sa;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ sa.sa_handler = SIG_IGN;
+ sigaction(SIGPIPE, &sa, NULL);
+ }
+#endif
+
/* Need lafe_progname before calling lafe_warnc. */
if (*argv == NULL)
lafe_progname = "bsdcpio";
@@ -150,6 +163,10 @@ main(int argc, char *argv[])
else
lafe_progname = *argv;
}
+#if HAVE_SETLOCALE
+ if (setlocale(LC_ALL, "") == NULL)
+ lafe_warnc(0, "Failed to set default locale");
+#endif
cpio->uid_override = -1;
cpio->gid_override = -1;
@@ -187,9 +204,9 @@ main(int argc, char *argv[])
cpio->bytes_per_block = 5120;
break;
case 'C': /* NetBSD/OpenBSD */
- cpio->bytes_per_block = atoi(cpio->optarg);
+ cpio->bytes_per_block = atoi(cpio->argument);
if (cpio->bytes_per_block <= 0)
- lafe_errc(1, 0, "Invalid blocksize %s", cpio->optarg);
+ lafe_errc(1, 0, "Invalid blocksize %s", cpio->argument);
break;
case 'c': /* POSIX 1997 */
cpio->format = "odc";
@@ -199,22 +216,22 @@ main(int argc, char *argv[])
break;
case 'E': /* NetBSD/OpenBSD */
lafe_include_from_file(&cpio->matching,
- cpio->optarg, cpio->option_null);
+ cpio->argument, cpio->option_null);
break;
case 'F': /* NetBSD/OpenBSD/GNU cpio */
- cpio->filename = cpio->optarg;
+ cpio->filename = cpio->argument;
break;
case 'f': /* POSIX 1997 */
- lafe_exclude(&cpio->matching, cpio->optarg);
+ lafe_exclude(&cpio->matching, cpio->argument);
break;
case 'H': /* GNU cpio (also --format) */
- cpio->format = cpio->optarg;
+ cpio->format = cpio->argument;
break;
case 'h':
long_help();
break;
case 'I': /* NetBSD/OpenBSD */
- cpio->filename = cpio->optarg;
+ cpio->filename = cpio->argument;
break;
case 'i': /* POSIX 1997 */
if (cpio->mode != '\0')
@@ -251,7 +268,7 @@ main(int argc, char *argv[])
cpio->extract_flags &= ~ARCHIVE_EXTRACT_OWNER;
break;
case 'O': /* GNU cpio */
- cpio->filename = cpio->optarg;
+ cpio->filename = cpio->argument;
break;
case 'o': /* POSIX 1997 */
if (cpio->mode != '\0')
@@ -275,7 +292,7 @@ main(int argc, char *argv[])
case 'R': /* GNU cpio, also --owner */
/* TODO: owner_parse should return uname/gname
* also; use that to set [ug]name_override. */
- errmsg = owner_parse(cpio->optarg, &uid, &gid);
+ errmsg = owner_parse(cpio->argument, &uid, &gid);
if (errmsg) {
lafe_warnc(-1, "%s", errmsg);
usage();
@@ -302,6 +319,9 @@ main(int argc, char *argv[])
case 'v': /* POSIX 1997 */
cpio->verbose++;
break;
+ case 'V': /* GNU cpio */
+ cpio->dot++;
+ break;
case OPTION_VERSION: /* GNU convention */
version();
break;
@@ -345,6 +365,12 @@ main(int argc, char *argv[])
/* -l requires -p */
if (cpio->option_link && cpio->mode != 'p')
lafe_errc(1, 0, "Option -l requires -p");
+ /* -v overrides -V */
+ if (cpio->dot && cpio->verbose)
+ cpio->dot = 0;
+ /* -v overrides -V */
+ if (cpio->dot && cpio->verbose)
+ cpio->dot = 0;
/* TODO: Flag other nonsensical combinations. */
switch (cpio->mode) {
@@ -402,7 +428,7 @@ static const char *long_help_msg =
"First option must be a mode specifier:\n"
" -i Input -o Output -p Pass\n"
"Common Options:\n"
- " -v Verbose\n"
+ " -v Verbose filenames -V one dot per file\n"
"Create: %p -o [options] < [list of files] > [archive]\n"
" -J,-y,-z,--lzma Compress archive with xz/bzip2/gzip/lzma\n"
" --format {odc|newc|ustar} Select archive format\n"
@@ -451,7 +477,7 @@ version(void)
{
fprintf(stdout,"bsdcpio %s -- %s\n",
BSDCPIO_VERSION_STRING,
- archive_version());
+ archive_version_string());
exit(0);
}
@@ -533,6 +559,8 @@ mode_out(struct cpio *cpio)
}
r = archive_write_close(cpio->archive);
+ if (cpio->dot)
+ fprintf(stderr, "\n");
if (r != ARCHIVE_OK)
lafe_errc(1, 0, "%s", archive_error_string(cpio->archive));
@@ -543,7 +571,7 @@ mode_out(struct cpio *cpio)
fprintf(stderr, "%lu %s\n", (unsigned long)blocks,
blocks == 1 ? "block" : "blocks");
}
- archive_write_finish(cpio->archive);
+ archive_write_free(cpio->archive);
}
/*
@@ -656,6 +684,8 @@ entry_to_archive(struct cpio *cpio, struct archive_entry *entry)
/* Print out the destination name to the user. */
if (cpio->verbose)
fprintf(stderr,"%s", destpath);
+ if (cpio->dot)
+ fprintf(stderr, ".");
/*
* Option_link only makes sense in pass mode and for
@@ -725,7 +755,7 @@ entry_to_archive(struct cpio *cpio, struct archive_entry *entry)
if (r == ARCHIVE_FATAL)
exit(1);
- if (r >= ARCHIVE_WARN && fd >= 0) {
+ if (r >= ARCHIVE_WARN && archive_entry_size(entry) > 0 && fd >= 0) {
bytes_read = read(fd, cpio->buff, cpio->buff_size);
while (bytes_read > 0) {
r = archive_write_data(cpio->archive,
@@ -825,7 +855,7 @@ mode_in(struct cpio *cpio)
a = archive_read_new();
if (a == NULL)
lafe_errc(1, 0, "Couldn't allocate archive object");
- archive_read_support_compression_all(a);
+ archive_read_support_filter_all(a);
archive_read_support_format_all(a);
if (archive_read_open_file(a, cpio->filename, cpio->bytes_per_block))
@@ -849,7 +879,9 @@ mode_in(struct cpio *cpio)
if (destpath == NULL)
continue;
if (cpio->verbose)
- fprintf(stdout, "%s\n", destpath);
+ fprintf(stderr, "%s\n", destpath);
+ if (cpio->dot)
+ fprintf(stderr, ".");
if (cpio->uid_override >= 0)
archive_entry_set_uid(entry, cpio->uid_override);
if (cpio->gid_override >= 0)
@@ -859,13 +891,16 @@ mode_in(struct cpio *cpio)
fprintf(stderr, "%s: %s\n",
archive_entry_pathname(entry),
archive_error_string(ext));
- } else if (archive_entry_size(entry) > 0) {
+ } else if (!archive_entry_size_is_set(entry)
+ || archive_entry_size(entry) > 0) {
r = extract_data(a, ext);
if (r != ARCHIVE_OK)
cpio->return_value = 1;
}
}
r = archive_read_close(a);
+ if (cpio->dot)
+ fprintf(stderr, "\n");
if (r != ARCHIVE_OK)
lafe_errc(1, 0, "%s", archive_error_string(a));
r = archive_write_close(ext);
@@ -877,8 +912,8 @@ mode_in(struct cpio *cpio)
fprintf(stderr, "%lu %s\n", (unsigned long)blocks,
blocks == 1 ? "block" : "blocks");
}
- archive_read_finish(a);
- archive_write_finish(ext);
+ archive_read_free(a);
+ archive_write_free(ext);
exit(cpio->return_value);
}
@@ -892,7 +927,7 @@ extract_data(struct archive *ar, struct archive *aw)
int r;
size_t size;
const void *block;
- off_t offset;
+ int64_t offset;
for (;;) {
r = archive_read_data_block(ar, &block, &size, &offset);
@@ -922,7 +957,7 @@ mode_list(struct cpio *cpio)
a = archive_read_new();
if (a == NULL)
lafe_errc(1, 0, "Couldn't allocate archive object");
- archive_read_support_compression_all(a);
+ archive_read_support_filter_all(a);
archive_read_support_format_all(a);
if (archive_read_open_file(a, cpio->filename, cpio->bytes_per_block))
@@ -952,7 +987,7 @@ mode_list(struct cpio *cpio)
fprintf(stderr, "%lu %s\n", (unsigned long)blocks,
blocks == 1 ? "block" : "blocks");
}
- archive_read_finish(a);
+ archive_read_free(a);
exit(0);
}
@@ -989,11 +1024,11 @@ list_item_verbose(struct cpio *cpio, struct archive_entry *entry)
/* Use uname if it's present, else lookup name from uid. */
uname = archive_entry_uname(entry);
if (uname == NULL)
- uname = lookup_uname(cpio, archive_entry_uid(entry));
+ uname = lookup_uname(cpio, (uid_t)archive_entry_uid(entry));
/* Use gname if it's present, else lookup name from gid. */
gname = archive_entry_gname(entry);
if (gname == NULL)
- gname = lookup_gname(cpio, archive_entry_gid(entry));
+ gname = lookup_gname(cpio, (uid_t)archive_entry_gid(entry));
}
/* Print device number or file size. */
@@ -1075,6 +1110,8 @@ mode_pass(struct cpio *cpio, const char *destdir)
archive_entry_linkresolver_free(cpio->linkresolver);
r = archive_write_close(cpio->archive);
+ if (cpio->dot)
+ fprintf(stderr, "\n");
if (r != ARCHIVE_OK)
lafe_errc(1, 0, "%s", archive_error_string(cpio->archive));
@@ -1086,7 +1123,7 @@ mode_pass(struct cpio *cpio, const char *destdir)
blocks == 1 ? "block" : "blocks");
}
- archive_write_finish(cpio->archive);
+ archive_write_free(cpio->archive);
}
/*
@@ -1260,8 +1297,9 @@ lookup_gname_helper(struct cpio *cpio, const char **name, id_t id)
const char *
cpio_i64toa(int64_t n0)
{
- // 2^64 =~ 1.8 * 10^19, so 20 decimal digits suffice.
- // We also need 1 byte for '-' and 1 for '\0'.
+ /* 2^64 =~ 1.8 * 10^19, so 20 decimal digits suffice.
+ * We also need 1 byte for '-' and 1 for '\0'.
+ */
static char buff[22];
int64_t n = n0 < 0 ? -n0 : n0;
char *p = buff + sizeof(buff);
diff --git a/cpio/cpio.h b/cpio/cpio.h
index a86e924a7a77..dc68e66a6fed 100644
--- a/cpio/cpio.h
+++ b/cpio/cpio.h
@@ -43,18 +43,18 @@
*/
struct cpio {
/* Option parsing */
- const char *optarg;
+ const char *argument;
/* Options */
const char *filename;
- char mode; /* -i -o -p */
- char compress; /* -j, -y, or -z */
+ int mode; /* -i -o -p */
+ int compress; /* -j, -y, or -z */
const char *format; /* -H format */
int bytes_per_block; /* -b block_size */
int verbose; /* -v */
+ int dot; /* -V */
int quiet; /* --quiet */
int extract_flags; /* Flags for extract operation */
- char symlink_mode; /* H or L, per BSD conventions */
const char *compress_program;
int option_append; /* -A, only relevant for -o */
int option_atime_restore; /* -a */
diff --git a/cpio/test/CMakeLists.txt b/cpio/test/CMakeLists.txt
index a822bcdfba5b..2196c19aed0d 100644
--- a/cpio/test/CMakeLists.txt
+++ b/cpio/test/CMakeLists.txt
@@ -15,6 +15,7 @@ IF(ENABLE_CPIO AND ENABLE_TEST)
test_cmdline.c
test_format_newc.c
test_gcpio_compat.c
+ test_option_0.c
test_option_B_upper.c
test_option_C_upper.c
test_option_J_upper.c
@@ -38,9 +39,6 @@ IF(ENABLE_CPIO AND ENABLE_TEST)
test_passthrough_reverse.c
test_pathmatch.c
)
- IF(WIN32 AND NOT CYGWIN)
- LIST(APPEND bsdcpio_test_SOURCES ../cpio_windows.h)
- ENDIF(WIN32 AND NOT CYGWIN)
#
# Register target
@@ -60,7 +58,7 @@ IF(ENABLE_CPIO AND ENABLE_TEST)
# test. We can use that to define the tests for cmake by
# defining a DEFINE_TEST macro and reading list.h in.
MACRO (DEFINE_TEST _testname)
- ADD_TEST_28(
+ ADD_TEST(
NAME bsdcpio_${_testname}
COMMAND bsdcpio_test -vv
-p $<TARGET_FILE:bsdcpio>
diff --git a/cpio/test/main.c b/cpio/test/main.c
index 90336a9e630d..d9e6c302bbb7 100644
--- a/cpio/test/main.c
+++ b/cpio/test/main.c
@@ -24,8 +24,18 @@
*/
#include "test.h"
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
#include <errno.h>
+#ifdef HAVE_ICONV_H
+#include <iconv.h>
+#endif
+#include <limits.h>
#include <locale.h>
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
#include <stdarg.h>
#include <time.h>
@@ -40,8 +50,10 @@ __FBSDID("$FreeBSD: src/usr.bin/cpio/test/main.c,v 1.3 2008/08/24 04:58:22 kient
#define KNOWNREF "test_option_f.cpio.uu"
#define ENVBASE "BSDCPIO" /* Prefix for environment variables. */
#define PROGRAM "bsdcpio" /* Name of program being tested. */
-#undef LIBRARY /* Not testing a library. */
-#undef EXTRA_DUMP /* How to dump extra data */
+#define PROGRAM_ALIAS "cpio" /* Generic alias for program */
+#undef LIBRARY /* Not testing a library. */
+#undef EXTRA_DUMP /* How to dump extra data */
+#undef EXTRA_ERRNO /* How to dump errno */
/* How to generate extra version info. */
#define EXTRA_VERSION (systemf("%s --version", testprog) ? "" : "")
@@ -78,6 +90,7 @@ __FBSDID("$FreeBSD: src/usr.bin/cpio/test/main.c,v 1.3 2008/08/24 04:58:22 kient
#endif
#if !defined(__BORLANDC__)
#define access _access
+#undef chdir
#define chdir _chdir
#endif
#ifndef fileno
@@ -150,7 +163,7 @@ my_GetFileInformationByName(const char *path, BY_HANDLE_FILE_INFORMATION *bhfi)
memset(bhfi, 0, sizeof(*bhfi));
h = CreateFile(path, FILE_READ_ATTRIBUTES, 0, NULL,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (h == INVALID_HANDLE_VALUE)
return (0);
r = GetFileInformationByHandle(h, bhfi);
@@ -179,6 +192,8 @@ invalid_parameter_handler(const wchar_t * expression,
static int dump_on_failure = 0;
/* Default is to remove temp dirs and log data for successful tests. */
static int keep_temp_files = 0;
+/* Default is to run the specified tests once and report errors. */
+static int until_failure = 0;
/* Default is to just report pass/fail for each test. */
static int verbosity = 0;
#define VERBOSITY_SUMMARY_ONLY -1 /* -q */
@@ -236,10 +251,14 @@ void
failure(const char *fmt, ...)
{
va_list ap;
- va_start(ap, fmt);
- vsprintf(msgbuff, fmt, ap);
- va_end(ap);
- nextmsg = msgbuff;
+ if (fmt == NULL) {
+ nextmsg = NULL;
+ } else {
+ va_start(ap, fmt);
+ vsprintf(msgbuff, fmt, ap);
+ va_end(ap);
+ nextmsg = msgbuff;
+ }
}
/*
@@ -251,15 +270,14 @@ failure(const char *fmt, ...)
* pass __FILE__, __LINE__ directly into the function instead of using
* this hook. I suspect this machinery is used so rarely that we
* would be better off just removing it entirely. That would simplify
- * the code here noticably.
+ * the code here noticeably.
*/
-static const char *test_filename;
-static int test_line;
-static void *test_extra;
-void assertion_setup(const char *filename, int line)
+static const char *skipping_filename;
+static int skipping_line;
+void skipping_setup(const char *filename, int line)
{
- test_filename = filename;
- test_line = line;
+ skipping_filename = filename;
+ skipping_line = line;
}
/* Called at the beginning of each assert() function. */
@@ -286,6 +304,7 @@ static struct line {
int count;
int skip;
} failed_lines[10000];
+const char *failed_filename;
/* Count this failure, setup up log destination and handle initial report. */
static void
@@ -295,19 +314,16 @@ failure_start(const char *filename, int line, const char *fmt, ...)
/* Record another failure for this line. */
++failures;
- /* test_filename = filename; */
+ failed_filename = filename;
failed_lines[line].count++;
/* Determine whether to log header to console. */
switch (verbosity) {
- case VERBOSITY_FULL:
- log_console = 1;
- break;
case VERBOSITY_LIGHT_REPORT:
log_console = (failed_lines[line].count < 2);
break;
default:
- log_console = 0;
+ log_console = (verbosity >= VERBOSITY_FULL);
}
/* Log file:line header for this failure */
@@ -343,14 +359,16 @@ failure_finish(void *extra)
{
(void)extra; /* UNUSED (maybe) */
#ifdef EXTRA_DUMP
- if (extra != NULL)
+ if (extra != NULL) {
+ logprintf(" errno: %d\n", EXTRA_ERRNO(extra));
logprintf(" detail: %s\n", EXTRA_DUMP(extra));
+ }
#endif
if (dump_on_failure) {
fprintf(stderr,
" *** forcing core dump so failure can be debugged ***\n");
- *(char *)(NULL) = 0;
+ abort();
exit(1);
}
}
@@ -365,12 +383,15 @@ test_skipping(const char *fmt, ...)
va_start(ap, fmt);
vsprintf(buff, fmt, ap);
va_end(ap);
+ /* Use failure() message if set. */
+ msg = nextmsg;
+ nextmsg = NULL;
/* failure_start() isn't quite right, but is awfully convenient. */
- failure_start(test_filename, test_line, "SKIPPING: %s", buff);
+ failure_start(skipping_filename, skipping_line, "SKIPPING: %s", buff);
--failures; /* Undo failures++ in failure_start() */
/* Don't failure_finish() here. */
/* Mark as skip, so doesn't count as failed test. */
- failed_lines[test_line].skip = 1;
+ failed_lines[skipping_line].skip = 1;
++skips;
}
@@ -421,13 +442,102 @@ assertion_equal_int(const char *file, int line,
return (0);
}
-static void strdump(const char *e, const char *p)
+/*
+ * Utility to convert a single UTF-8 sequence.
+ */
+static int
+_utf8_to_unicode(uint32_t *pwc, const char *s, size_t n)
+{
+ static const char utf8_count[256] = {
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 00 - 0F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 10 - 1F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 20 - 2F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 30 - 3F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40 - 4F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 50 - 5F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 60 - 6F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 70 - 7F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 80 - 8F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 90 - 9F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* A0 - AF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* B0 - BF */
+ 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,/* C0 - CF */
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,/* D0 - DF */
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,/* E0 - EF */
+ 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* F0 - FF */
+ };
+ int ch;
+ int cnt;
+ uint32_t wc;
+
+ *pwc = 0;
+
+ /* Sanity check. */
+ if (n == 0)
+ return (0);
+ /*
+ * Decode 1-4 bytes depending on the value of the first byte.
+ */
+ ch = (unsigned char)*s;
+ if (ch == 0)
+ return (0); /* Standard: return 0 for end-of-string. */
+ cnt = utf8_count[ch];
+
+ /* Invalide sequence or there are not plenty bytes. */
+ if (n < (size_t)cnt)
+ return (-1);
+
+ /* Make a Unicode code point from a single UTF-8 sequence. */
+ switch (cnt) {
+ case 1: /* 1 byte sequence. */
+ *pwc = ch & 0x7f;
+ return (cnt);
+ case 2: /* 2 bytes sequence. */
+ if ((s[1] & 0xc0) != 0x80) return (-1);
+ *pwc = ((ch & 0x1f) << 6) | (s[1] & 0x3f);
+ return (cnt);
+ case 3: /* 3 bytes sequence. */
+ if ((s[1] & 0xc0) != 0x80) return (-1);
+ if ((s[2] & 0xc0) != 0x80) return (-1);
+ wc = ((ch & 0x0f) << 12)
+ | ((s[1] & 0x3f) << 6)
+ | (s[2] & 0x3f);
+ if (wc < 0x800)
+ return (-1);/* Overlong sequence. */
+ break;
+ case 4: /* 4 bytes sequence. */
+ if (n < 4)
+ return (-1);
+ if ((s[1] & 0xc0) != 0x80) return (-1);
+ if ((s[2] & 0xc0) != 0x80) return (-1);
+ if ((s[3] & 0xc0) != 0x80) return (-1);
+ wc = ((ch & 0x07) << 18)
+ | ((s[1] & 0x3f) << 12)
+ | ((s[2] & 0x3f) << 6)
+ | (s[3] & 0x3f);
+ if (wc < 0x10000)
+ return (-1);/* Overlong sequence. */
+ break;
+ default:
+ return (-1);
+ }
+
+ /* The code point larger than 0x10FFFF is not leagal
+ * Unicode values. */
+ if (wc > 0x10FFFF)
+ return (-1);
+ /* Correctly gets a Unicode, returns used bytes. */
+ *pwc = wc;
+ return (cnt);
+}
+
+static void strdump(const char *e, const char *p, int ewidth, int utf8)
{
const char *q = p;
- logprintf(" %s = ", e);
+ logprintf(" %*s = ", ewidth, e);
if (p == NULL) {
- logprintf("NULL");
+ logprintf("NULL\n");
return;
}
logprintf("\"");
@@ -446,7 +556,37 @@ static void strdump(const char *e, const char *p)
}
}
logprintf("\"");
- logprintf(" (length %d)\n", q == NULL ? -1 : (int)strlen(q));
+ logprintf(" (length %d)", q == NULL ? -1 : (int)strlen(q));
+
+ /*
+ * If the current string is UTF-8, dump its code points.
+ */
+ if (utf8) {
+ size_t len;
+ uint32_t uc;
+ int n;
+ int cnt = 0;
+
+ p = q;
+ len = strlen(p);
+ logprintf(" [");
+ while ((n = _utf8_to_unicode(&uc, p, len)) > 0) {
+ if (p != q)
+ logprintf(" ");
+ logprintf("%04X", uc);
+ p += n;
+ len -= n;
+ cnt++;
+ }
+ logprintf("]");
+ logprintf(" (count %d", cnt);
+ if (n < 0) {
+ logprintf(",unknown %d bytes", len);
+ }
+ logprintf(")");
+
+ }
+ logprintf("\n");
}
/* Verify two strings are equal, dump them if not. */
@@ -454,14 +594,20 @@ int
assertion_equal_string(const char *file, int line,
const char *v1, const char *e1,
const char *v2, const char *e2,
- void *extra)
+ void *extra, int utf8)
{
+ int l1, l2;
+
assertion_count(file, line);
if (v1 == v2 || (v1 != NULL && v2 != NULL && strcmp(v1, v2) == 0))
return (1);
failure_start(file, line, "%s != %s", e1, e2);
- strdump(e1, v1);
- strdump(e2, v2);
+ l1 = strlen(e1);
+ l2 = strlen(e2);
+ if (l1 < l2)
+ l1 = l2;
+ strdump(e1, v1, l1, utf8);
+ strdump(e2, v2, l1, utf8);
failure_finish(extra);
return (0);
}
@@ -513,7 +659,9 @@ assertion_equal_wstring(const char *file, int line,
void *extra)
{
assertion_count(file, line);
- if (v1 == v2 || wcscmp(v1, v2) == 0)
+ if (v1 == v2)
+ return (1);
+ if (v1 != NULL && v2 != NULL && wcscmp(v1, v2) == 0)
return (1);
failure_start(file, line, "%s != %s", e1, e2);
wcsdump(e1, v1);
@@ -592,9 +740,9 @@ assertion_equal_mem(const char *file, int line,
offset += 16;
}
logprintf(" Dump of %s\n", e1);
- hexdump(v1, v2, l < 64 ? l : 64, offset);
+ hexdump(v1, v2, l < 128 ? l : 128, offset);
logprintf(" Dump of %s\n", e2);
- hexdump(v2, v1, l < 64 ? l : 64, offset);
+ hexdump(v2, v1, l < 128 ? l : 128, offset);
logprintf("\n");
failure_finish(extra);
return (0);
@@ -602,29 +750,24 @@ assertion_equal_mem(const char *file, int line,
/* Verify that the named file exists and is empty. */
int
-assertion_empty_file(const char *f1fmt, ...)
+assertion_empty_file(const char *filename, int line, const char *f1)
{
char buff[1024];
- char f1[1024];
struct stat st;
- va_list ap;
ssize_t s;
FILE *f;
- assertion_count(test_filename, test_line);
- va_start(ap, f1fmt);
- vsprintf(f1, f1fmt, ap);
- va_end(ap);
+ assertion_count(filename, line);
if (stat(f1, &st) != 0) {
- failure_start(test_filename, test_line, "Stat failed: %s", f1);
+ failure_start(filename, line, "Stat failed: %s", f1);
failure_finish(NULL);
return (0);
}
if (st.st_size == 0)
return (1);
- failure_start(test_filename, test_line, "File should be empty: %s", f1);
+ failure_start(filename, line, "File should be empty: %s", f1);
logprintf(" File size: %d\n", (int)st.st_size);
logprintf(" Contents:\n");
f = fopen(f1, "rb");
@@ -643,24 +786,19 @@ assertion_empty_file(const char *f1fmt, ...)
/* Verify that the named file exists and is not empty. */
int
-assertion_non_empty_file(const char *f1fmt, ...)
+assertion_non_empty_file(const char *filename, int line, const char *f1)
{
- char f1[1024];
struct stat st;
- va_list ap;
- assertion_count(test_filename, test_line);
- va_start(ap, f1fmt);
- vsprintf(f1, f1fmt, ap);
- va_end(ap);
+ assertion_count(filename, line);
if (stat(f1, &st) != 0) {
- failure_start(test_filename, test_line, "Stat failed: %s", f1);
+ failure_start(filename, line, "Stat failed: %s", f1);
failure_finish(NULL);
return (0);
}
if (st.st_size == 0) {
- failure_start(test_filename, test_line, "File empty: %s", f1);
+ failure_start(filename, line, "File empty: %s", f1);
failure_finish(NULL);
return (0);
}
@@ -670,19 +808,14 @@ assertion_non_empty_file(const char *f1fmt, ...)
/* Verify that two files have the same contents. */
/* TODO: hexdump the first bytes that actually differ. */
int
-assertion_equal_file(const char *fn1, const char *f2pattern, ...)
+assertion_equal_file(const char *filename, int line, const char *fn1, const char *fn2)
{
- char fn2[1024];
- va_list ap;
char buff1[1024];
char buff2[1024];
FILE *f1, *f2;
int n1, n2;
- assertion_count(test_filename, test_line);
- va_start(ap, f2pattern);
- vsprintf(fn2, f2pattern, ap);
- va_end(ap);
+ assertion_count(filename, line);
f1 = fopen(fn1, "rb");
f2 = fopen(fn2, "rb");
@@ -701,24 +834,18 @@ assertion_equal_file(const char *fn1, const char *f2pattern, ...)
}
fclose(f1);
fclose(f2);
- failure_start(test_filename, test_line, "Files not identical");
+ failure_start(filename, line, "Files not identical");
logprintf(" file1=\"%s\"\n", fn1);
logprintf(" file2=\"%s\"\n", fn2);
- failure_finish(test_extra);
+ failure_finish(NULL);
return (0);
}
/* Verify that the named file does exist. */
int
-assertion_file_exists(const char *fpattern, ...)
+assertion_file_exists(const char *filename, int line, const char *f)
{
- char f[1024];
- va_list ap;
-
- assertion_count(test_filename, test_line);
- va_start(ap, fpattern);
- vsprintf(f, fpattern, ap);
- va_end(ap);
+ assertion_count(filename, line);
#if defined(_WIN32) && !defined(__CYGWIN__)
if (!_access(f, 0))
@@ -727,22 +854,16 @@ assertion_file_exists(const char *fpattern, ...)
if (!access(f, F_OK))
return (1);
#endif
- failure_start(test_filename, test_line, "File should exist: %s", f);
- failure_finish(test_extra);
+ failure_start(filename, line, "File should exist: %s", f);
+ failure_finish(NULL);
return (0);
}
/* Verify that the named file doesn't exist. */
int
-assertion_file_not_exists(const char *fpattern, ...)
+assertion_file_not_exists(const char *filename, int line, const char *f)
{
- char f[1024];
- va_list ap;
-
- assertion_count(test_filename, test_line);
- va_start(ap, fpattern);
- vsprintf(f, fpattern, ap);
- va_end(ap);
+ assertion_count(filename, line);
#if defined(_WIN32) && !defined(__CYGWIN__)
if (_access(f, 0))
@@ -751,31 +872,26 @@ assertion_file_not_exists(const char *fpattern, ...)
if (access(f, F_OK))
return (1);
#endif
- failure_start(test_filename, test_line, "File should not exist: %s", f);
- failure_finish(test_extra);
+ failure_start(filename, line, "File should not exist: %s", f);
+ failure_finish(NULL);
return (0);
}
/* Compare the contents of a file to a block of memory. */
int
-assertion_file_contents(const void *buff, int s, const char *fpattern, ...)
+assertion_file_contents(const char *filename, int line, const void *buff, int s, const char *fn)
{
- char fn[1024];
- va_list ap;
char *contents;
FILE *f;
int n;
- assertion_count(test_filename, test_line);
- va_start(ap, fpattern);
- vsprintf(fn, fpattern, ap);
- va_end(ap);
+ assertion_count(filename, line);
f = fopen(fn, "rb");
if (f == NULL) {
- failure_start(test_filename, test_line,
+ failure_start(filename, line,
"File should exist: %s", fn);
- failure_finish(test_extra);
+ failure_finish(NULL);
return (0);
}
contents = malloc(s * 2);
@@ -785,34 +901,34 @@ assertion_file_contents(const void *buff, int s, const char *fpattern, ...)
free(contents);
return (1);
}
- failure_start(test_filename, test_line, "File contents don't match");
+ failure_start(filename, line, "File contents don't match");
logprintf(" file=\"%s\"\n", fn);
if (n > 0)
hexdump(contents, buff, n > 512 ? 512 : n, 0);
else {
logprintf(" File empty, contents should be:\n");
- hexdump(buff, NULL, s > 512 ? 512 : n, 0);
+ hexdump(buff, NULL, s > 512 ? 512 : s, 0);
}
- failure_finish(test_extra);
+ failure_finish(NULL);
free(contents);
return (0);
}
/* Check the contents of a text file, being tolerant of line endings. */
int
-assertion_text_file_contents(const char *buff, const char *fn)
+assertion_text_file_contents(const char *filename, int line, const char *buff, const char *fn)
{
char *contents;
const char *btxt, *ftxt;
FILE *f;
int n, s;
- assertion_count(test_filename, test_line);
+ assertion_count(filename, line);
f = fopen(fn, "r");
if (f == NULL) {
- failure_start(test_filename, test_line,
+ failure_start(filename, line,
"File doesn't exist: %s", fn);
- failure_finish(test_extra);
+ failure_finish(NULL);
return (0);
}
s = strlen(buff);
@@ -842,19 +958,122 @@ assertion_text_file_contents(const char *buff, const char *fn)
free(contents);
return (1);
}
- failure_start(test_filename, test_line, "Contents don't match");
+ failure_start(filename, line, "Contents don't match");
logprintf(" file=\"%s\"\n", fn);
- if (n > 0)
+ if (n > 0) {
hexdump(contents, buff, n, 0);
- else {
+ logprintf(" expected\n", fn);
+ hexdump(buff, contents, s, 0);
+ } else {
logprintf(" File empty, contents should be:\n");
hexdump(buff, NULL, s, 0);
}
- failure_finish(test_extra);
+ failure_finish(NULL);
free(contents);
return (0);
}
+/* Verify that a text file contains the specified lines, regardless of order */
+/* This could be more efficient if we sorted both sets of lines, etc, but
+ * since this is used only for testing and only ever deals with a dozen or so
+ * lines at a time, this relatively crude approach is just fine. */
+int
+assertion_file_contains_lines_any_order(const char *file, int line,
+ const char *pathname, const char *lines[])
+{
+ char *buff;
+ size_t buff_size;
+ size_t expected_count, actual_count, i, j;
+ char **expected;
+ char *p, **actual;
+ char c;
+ int expected_failure = 0, actual_failure = 0;
+
+ assertion_count(file, line);
+
+ buff = slurpfile(&buff_size, "%s", pathname);
+ if (buff == NULL) {
+ failure_start(pathname, line, "Can't read file: %s", pathname);
+ failure_finish(NULL);
+ return (0);
+ }
+
+ /* Make a copy of the provided lines and count up the expected file size. */
+ expected_count = 0;
+ for (i = 0; lines[i] != NULL; ++i) {
+ }
+ expected_count = i;
+ expected = malloc(sizeof(char *) * expected_count);
+ for (i = 0; lines[i] != NULL; ++i) {
+ expected[i] = strdup(lines[i]);
+ }
+
+ /* Break the file into lines */
+ actual_count = 0;
+ for (c = '\0', p = buff; p < buff + buff_size; ++p) {
+ if (*p == '\x0d' || *p == '\x0a')
+ *p = '\0';
+ if (c == '\0' && *p != '\0')
+ ++actual_count;
+ c = *p;
+ }
+ actual = malloc(sizeof(char *) * actual_count);
+ for (j = 0, p = buff; p < buff + buff_size; p += 1 + strlen(p)) {
+ if (*p != '\0') {
+ actual[j] = p;
+ ++j;
+ }
+ }
+
+ /* Erase matching lines from both lists */
+ for (i = 0; i < expected_count; ++i) {
+ if (expected[i] == NULL)
+ continue;
+ for (j = 0; j < actual_count; ++j) {
+ if (actual[j] == NULL)
+ continue;
+ if (strcmp(expected[i], actual[j]) == 0) {
+ free(expected[i]);
+ expected[i] = NULL;
+ actual[j] = NULL;
+ break;
+ }
+ }
+ }
+
+ /* If there's anything left, it's a failure */
+ for (i = 0; i < expected_count; ++i) {
+ if (expected[i] != NULL)
+ ++expected_failure;
+ }
+ for (j = 0; j < actual_count; ++j) {
+ if (actual[j] != NULL)
+ ++actual_failure;
+ }
+ if (expected_failure == 0 && actual_failure == 0) {
+ free(buff);
+ free(expected);
+ free(actual);
+ return (1);
+ }
+ failure_start(file, line, "File doesn't match: %s", pathname);
+ for (i = 0; i < expected_count; ++i) {
+ if (expected[i] != NULL) {
+ logprintf(" Expected but not present: %s\n", expected[i]);
+ free(expected[i]);
+ }
+ }
+ for (j = 0; j < actual_count; ++j) {
+ if (actual[j] != NULL)
+ logprintf(" Present but not expected: %s\n", actual[j]);
+ }
+ failure_finish(NULL);
+ free(buff);
+ free(expected);
+ free(actual);
+ return (0);
+}
+
/* Test that two paths point to the same file. */
/* As a side-effect, asserts that both files exist. */
static int
@@ -944,8 +1163,11 @@ assertion_file_time(const char *file, int line,
ftime.dwHighDateTime = 0;
assertion_count(file, line);
+ /* Note: FILE_FLAG_BACKUP_SEMANTICS applies to open
+ * a directory file. If not, CreateFile() will fail when
+ * the pathname is a directory. */
h = CreateFile(pathname, FILE_READ_ATTRIBUTES, 0, NULL,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (h == INVALID_HANDLE_VALUE) {
failure_start(file, line, "Can't access %s\n", pathname);
failure_finish(NULL);
@@ -1010,14 +1232,14 @@ assertion_file_time(const char *file, int line,
time_t now = time(NULL);
if (filet < now - 10 || filet > now + 1) {
failure_start(file, line,
- "File %s has %ctime %ld, %ld seconds ago\n",
+ "File %s has %ctime %lld, %lld seconds ago\n",
pathname, type, filet, now - filet);
failure_finish(NULL);
return (0);
}
} else if (filet != t || filet_nsec != nsec) {
failure_start(file, line,
- "File %s has %ctime %ld.%09ld, expected %ld.%09ld",
+ "File %s has %ctime %lld.%09lld, expected %lld.%09lld",
pathname, type, filet, filet_nsec, t, nsec);
failure_finish(NULL);
return (0);
@@ -1390,6 +1612,110 @@ assertion_umask(const char *file, int line, int mask)
return (1);
}
+/* Set times, report failures. */
+int
+assertion_utimes(const char *file, int line,
+ const char *pathname, long at, long at_nsec, long mt, long mt_nsec)
+{
+ int r;
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#define WINTIME(sec, nsec) ((Int32x32To64(sec, 10000000) + EPOC_TIME)\
+ + (((nsec)/1000)*10))
+ HANDLE h;
+ ULARGE_INTEGER wintm;
+ FILETIME fatime, fmtime;
+ FILETIME *pat, *pmt;
+
+ assertion_count(file, line);
+ h = CreateFileA(pathname,GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (h == INVALID_HANDLE_VALUE) {
+ failure_start(file, line, "Can't access %s\n", pathname);
+ failure_finish(NULL);
+ return (0);
+ }
+
+ if (at > 0 || at_nsec > 0) {
+ wintm.QuadPart = WINTIME(at, at_nsec);
+ fatime.dwLowDateTime = wintm.LowPart;
+ fatime.dwHighDateTime = wintm.HighPart;
+ pat = &fatime;
+ } else
+ pat = NULL;
+ if (mt > 0 || mt_nsec > 0) {
+ wintm.QuadPart = WINTIME(mt, mt_nsec);
+ fmtime.dwLowDateTime = wintm.LowPart;
+ fmtime.dwHighDateTime = wintm.HighPart;
+ pmt = &fmtime;
+ } else
+ pmt = NULL;
+ if (pat != NULL || pmt != NULL)
+ r = SetFileTime(h, NULL, pat, pmt);
+ else
+ r = 1;
+ CloseHandle(h);
+ if (r == 0) {
+ failure_start(file, line, "Can't SetFileTime %s\n", pathname);
+ failure_finish(NULL);
+ return (0);
+ }
+ return (1);
+#else /* defined(_WIN32) && !defined(__CYGWIN__) */
+ struct stat st;
+ struct timeval times[2];
+
+#if !defined(__FreeBSD__)
+ mt_nsec = at_nsec = 0; /* Generic POSIX only has whole seconds. */
+#endif
+ if (mt == 0 && mt_nsec == 0 && at == 0 && at_nsec == 0)
+ return (1);
+
+ r = lstat(pathname, &st);
+ if (r < 0) {
+ failure_start(file, line, "Can't stat %s\n", pathname);
+ failure_finish(NULL);
+ return (0);
+ }
+
+ if (mt == 0 && mt_nsec == 0) {
+ mt = st.st_mtime;
+#if defined(__FreeBSD__)
+ mt_nsec = st.st_mtimespec.tv_nsec;
+ /* FreeBSD generally only stores to microsecond res, so round. */
+ mt_nsec = (mt_nsec / 1000) * 1000;
+#endif
+ }
+ if (at == 0 && at_nsec == 0) {
+ at = st.st_atime;
+#if defined(__FreeBSD__)
+ at_nsec = st.st_atimespec.tv_nsec;
+ /* FreeBSD generally only stores to microsecond res, so round. */
+ at_nsec = (at_nsec / 1000) * 1000;
+#endif
+ }
+
+ times[1].tv_sec = mt;
+ times[1].tv_usec = mt_nsec / 1000;
+
+ times[0].tv_sec = at;
+ times[0].tv_usec = at_nsec / 1000;
+
+#ifdef HAVE_LUTIMES
+ r = lutimes(pathname, times);
+#else
+ r = utimes(pathname, times);
+#endif
+ if (r < 0) {
+ failure_start(file, line, "Can't utimes %s\n", pathname);
+ failure_finish(NULL);
+ return (0);
+ }
+ return (1);
+#endif /* defined(_WIN32) && !defined(__CYGWIN__) */
+}
+
/*
*
* UTILITIES for use by tests.
@@ -1615,6 +1941,27 @@ extract_reference_file(const char *name)
fclose(in);
}
+int
+is_LargeInode(const char *file)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ BY_HANDLE_FILE_INFORMATION bhfi;
+ int r;
+
+ r = my_GetFileInformationByName(file, &bhfi);
+ if (r != 0)
+ return (0);
+ return (bhfi.nFileIndexHigh & 0x0000FFFFUL);
+#else
+ struct stat st;
+ int64_t ino;
+
+ if (stat(file, &st) < 0)
+ return (0);
+ ino = (int64_t)st.st_ino;
+ return (ino > 0xffffffff);
+#endif
+}
/*
*
* TEST management
@@ -1644,7 +1991,7 @@ struct { void (*func)(void); const char *name; int failures; } tests[] = {
* Summarize repeated failures in the just-completed test.
*/
static void
-test_summarize(const char *filename, int failed)
+test_summarize(int failed)
{
unsigned int i;
@@ -1663,9 +2010,10 @@ test_summarize(const char *filename, int failed)
for (i = 0; i < sizeof(failed_lines)/sizeof(failed_lines[0]); i++) {
if (failed_lines[i].count > 1 && !failed_lines[i].skip)
logprintf("%s:%d: Summary: Failed %d times\n",
- filename, i, failed_lines[i].count);
+ failed_filename, i, failed_lines[i].count);
}
/* Clear the failure history for the next file. */
+ failed_filename = NULL;
memset(failed_lines, 0, sizeof(failed_lines));
}
@@ -1675,6 +2023,7 @@ test_summarize(const char *filename, int failed)
static int
test_run(int i, const char *tmpdir)
{
+ char workdir[1024];
char logfilename[64];
int failures_before = failures;
int oldumask;
@@ -1701,11 +2050,12 @@ test_run(int i, const char *tmpdir)
logfile = fopen(logfilename, "w");
fprintf(logfile, "%s\n\n", tests[i].name);
/* Chdir() to a work dir for this specific test. */
- if (!assertMakeDir(tests[i].name, 0755)
- || !assertChdir(tests[i].name)) {
+ snprintf(workdir, sizeof(workdir), "%s/%s", tmpdir, tests[i].name);
+ testworkdir = workdir;
+ if (!assertMakeDir(testworkdir, 0755)
+ || !assertChdir(testworkdir)) {
fprintf(stderr,
- "ERROR: Can't chdir to work dir %s/%s\n",
- tmpdir, tests[i].name);
+ "ERROR: Can't chdir to work dir %s\n", testworkdir);
exit(1);
}
/* Explicitly reset the locale before each test. */
@@ -1719,6 +2069,7 @@ test_run(int i, const char *tmpdir)
/*
* Clean up and report afterwards.
*/
+ testworkdir = NULL;
/* Restore umask */
umask(oldumask);
/* Reset locale. */
@@ -1731,7 +2082,7 @@ test_run(int i, const char *tmpdir)
}
/* Report per-test summaries. */
tests[i].failures = failures - failures_before;
- test_summarize(test_filename, tests[i].failures);
+ test_summarize(tests[i].failures);
/* Close the per-test log file. */
fclose(logfile);
logfile = NULL;
@@ -1791,6 +2142,7 @@ usage(const char *program)
printf(" -q Quiet.\n");
printf(" -r <dir> Path to dir containing reference files.\n");
printf(" Default: Current directory.\n");
+ printf(" -u Keep running specifies tests until one fails.\n");
printf(" -v Verbose.\n");
printf("Available tests:\n");
for (i = 0; i < limit; i++)
@@ -1817,7 +2169,11 @@ get_refdir(const char *d)
}
/* Get the current dir. */
+#ifdef PATH_MAX
+ pwd = getcwd(NULL, PATH_MAX);/* Solaris getcwd needs the size. */
+#else
pwd = getcwd(NULL, 0);
+#endif
while (pwd[strlen(pwd) - 1] == '\n')
pwd[strlen(pwd) - 1] = '\0';
@@ -1844,6 +2200,14 @@ get_refdir(const char *d)
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
+#if defined(PROGRAM_ALIAS)
+ snprintf(buff, sizeof(buff), "%s/%s/test", pwd, PROGRAM_ALIAS);
+ p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
+ if (p != NULL) goto success;
+ strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
+ strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
+#endif
+
if (memcmp(pwd, "/usr/obj", 8) == 0) {
snprintf(buff, sizeof(buff), "%s", pwd + 8);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
@@ -1876,16 +2240,26 @@ int
main(int argc, char **argv)
{
static const int limit = sizeof(tests) / sizeof(tests[0]);
- int i, tests_run = 0, tests_failed = 0, option;
+ int i = 0, j = 0, start, end, tests_run = 0, tests_failed = 0, option;
time_t now;
char *refdir_alloc = NULL;
const char *progname;
+ char **saved_argv;
const char *tmp, *option_arg, *p;
- char tmpdir[256];
+ char tmpdir[256], *pwd, *testprogdir, *tmp2 = NULL;
char tmpdir_timestamp[256];
(void)argc; /* UNUSED */
+ /* Get the current dir. */
+#ifdef PATH_MAX
+ pwd = getcwd(NULL, PATH_MAX);/* Solaris getcwd needs the size. */
+#else
+ pwd = getcwd(NULL, 0);
+#endif
+ while (pwd[strlen(pwd) - 1] == '\n')
+ pwd[strlen(pwd) - 1] = '\0';
+
#if defined(HAVE__CrtSetReportMode)
/* To stop to run the default invalid parameter handler. */
_set_invalid_parameter_handler(invalid_parameter_handler);
@@ -1898,11 +2272,35 @@ main(int argc, char **argv)
* tree.
*/
progname = p = argv[0];
+ if ((testprogdir = (char *)malloc(strlen(progname) + 1)) == NULL)
+ {
+ fprintf(stderr, "ERROR: Out of memory.");
+ exit(1);
+ }
+ strcpy(testprogdir, progname);
while (*p != '\0') {
/* Support \ or / dir separators for Windows compat. */
if (*p == '/' || *p == '\\')
+ {
progname = p + 1;
+ i = j;
+ }
++p;
+ j++;
+ }
+ testprogdir[i] = '\0';
+ if (testprogdir[0] != '/')
+ {
+ /* Fixup path for relative directories. */
+ if ((testprogdir = (char *)realloc(testprogdir,
+ strlen(pwd) + 1 + strlen(testprogdir) + 1)) == NULL)
+ {
+ fprintf(stderr, "ERROR: Out of memory.");
+ exit(1);
+ }
+ strcpy(testprogdir + strlen(pwd) + 1, testprogdir);
+ strcpy(testprogdir, pwd);
+ testprogdir[strlen(pwd)] = '/';
}
#ifdef PROGRAM
@@ -1967,6 +2365,7 @@ main(int argc, char **argv)
#ifdef PROGRAM
testprogfile = option_arg;
#else
+ fprintf(stderr, "-p option not permitted\n");
usage(progname);
#endif
break;
@@ -1976,10 +2375,15 @@ main(int argc, char **argv)
case 'r':
refdir = option_arg;
break;
+ case 'u':
+ until_failure++;
+ break;
case 'v':
verbosity++;
break;
default:
+ fprintf(stderr, "Unrecognized option '%c'\n",
+ option);
usage(progname);
}
}
@@ -1990,7 +2394,19 @@ main(int argc, char **argv)
*/
#ifdef PROGRAM
if (testprogfile == NULL)
- usage(progname);
+ {
+ if ((tmp2 = (char *)malloc(strlen(testprogdir) + 1 +
+ strlen(PROGRAM) + 1)) == NULL)
+ {
+ fprintf(stderr, "ERROR: Out of memory.");
+ exit(1);
+ }
+ strcpy(tmp2, testprogdir);
+ strcat(tmp2, "/");
+ strcat(tmp2, PROGRAM);
+ testprogfile = tmp2;
+ }
+
{
char *testprg;
#if defined(_WIN32) && !defined(__CYGWIN__)
@@ -2011,6 +2427,16 @@ main(int argc, char **argv)
}
#endif
+#if !defined(_WIN32) && defined(SIGPIPE)
+ { /* Ignore SIGPIPE signals */
+ struct sigaction sa;
+ sa.sa_handler = SIG_IGN;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ sigaction(SIGPIPE, &sa, NULL);
+ }
+#endif
+
/*
* Create a temp directory for the following tests.
* Include the time the tests started as part of the name,
@@ -2063,42 +2489,88 @@ main(int argc, char **argv)
/*
* Run some or all of the individual tests.
*/
- if (*argv == NULL) {
- /* Default: Run all tests. */
- for (i = 0; i < limit; i++) {
- if (test_run(i, tmpdir))
- tests_failed++;
- tests_run++;
- }
- } else {
- while (*(argv) != NULL) {
- if (**argv >= '0' && **argv <= '9') {
- i = atoi(*argv);
- if (i < 0 || i >= limit) {
- printf("*** INVALID Test %s\n", *argv);
- free(refdir_alloc);
- usage(progname);
- /* usage() never returns */
+ saved_argv = argv;
+ do {
+ argv = saved_argv;
+ if (*argv == NULL) {
+ /* Default: Run all tests. */
+ for (i = 0; i < limit; i++) {
+ tests_run++;
+ if (test_run(i, tmpdir)) {
+ tests_failed++;
+ if (until_failure)
+ goto finish;
}
- } else {
- for (i = 0; i < limit; ++i) {
- if (strcmp(*argv, tests[i].name) == 0)
- break;
+ }
+ } else {
+ while (*(argv) != NULL) {
+ if (**argv >= '0' && **argv <= '9') {
+ char *p = *argv;
+ start = 0;
+ while (*p >= '0' && *p <= '9') {
+ start *= 10;
+ start += *p - '0';
+ ++p;
+ }
+ if (*p == '\0') {
+ end = start;
+ } else if (*p == '-') {
+ ++p;
+ if (*p == '\0') {
+ end = limit - 1;
+ } else {
+ end = 0;
+ while (*p >= '0' && *p <= '9') {
+ end *= 10;
+ end += *p - '0';
+ ++p;
+ }
+ }
+ } else {
+ printf("*** INVALID Test %s\n", *argv);
+ free(refdir_alloc);
+ usage(progname);
+ return (1);
+ }
+ if (start < 0 || end >= limit || start > end) {
+ printf("*** INVALID Test %s\n", *argv);
+ free(refdir_alloc);
+ usage(progname);
+ return (1);
+ }
+ } else {
+ for (start = 0; start < limit; ++start) {
+ if (strcmp(*argv, tests[start].name) == 0)
+ break;
+ }
+ end = start;
+ if (start >= limit) {
+ printf("*** INVALID Test ``%s''\n",
+ *argv);
+ free(refdir_alloc);
+ usage(progname);
+ /* usage() never returns */
+ }
}
- if (i >= limit) {
- printf("*** INVALID Test ``%s''\n",
- *argv);
- free(refdir_alloc);
- usage(progname);
- /* usage() never returns */
+ while (start <= end) {
+ tests_run++;
+ if (test_run(start, tmpdir)) {
+ tests_failed++;
+ if (until_failure)
+ goto finish;
+ }
+ ++start;
}
+ argv++;
}
- if (test_run(i, tmpdir))
- tests_failed++;
- tests_run++;
- argv++;
}
- }
+ } while (until_failure);
+
+finish:
+ /* Must be freed after all tests run */
+ free(tmp2);
+ free(testprogdir);
+ free(pwd);
/*
* Report summary statistics.
diff --git a/cpio/test/test.h b/cpio/test/test.h
index 2d68f3104d14..46124f84b20e 100644
--- a/cpio/test/test.h
+++ b/cpio/test/test.h
@@ -48,9 +48,6 @@
#include <sys/types.h> /* Windows requires this before sys/stat.h */
#include <sys/stat.h>
-#ifdef USE_DMALLOC
-#include <dmalloc.h>
-#endif
#if HAVE_DIRENT_H
#include <dirent.h>
#endif
@@ -63,6 +60,9 @@
#ifdef HAVE_IO_H
#include <io.h>
#endif
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -83,13 +83,9 @@
/* Windows (including Visual Studio and MinGW but not Cygwin) */
#if defined(_WIN32) && !defined(__CYGWIN__)
-#include "../cpio_windows.h"
#if !defined(__BORLANDC__)
#define strdup _strdup
#endif
-#define LOCALE_DE "deu"
-#else
-#define LOCALE_DE "de_DE.UTF-8"
#endif
/* Visual Studio */
@@ -97,13 +93,11 @@
#define snprintf sprintf_s
#endif
-/* Cygwin */
-#if defined(__CYGWIN__)
-/* Cygwin-1.7.x is lazy about populating nlinks, so don't
- * expect it to be accurate. */
-# define NLINKS_INACCURATE_FOR_DIRS
+#if defined(__BORLANDC__)
+#pragma warn -8068 /* Constant out of range in comparison. */
#endif
+/* Haiku OS and QNX */
#if defined(__HAIKU__) || defined(__QNXNTO__)
/* Haiku and QNX have typedefs in stdint.h (needed for int64_t) */
#include <stdint.h>
@@ -139,24 +133,24 @@
assertion_equal_int(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
/* Assert two strings are the same. Reports value of each one if not. */
#define assertEqualString(v1,v2) \
- assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
+ assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL, 0)
+#define assertEqualUTF8String(v1,v2) \
+ assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL, 1)
/* As above, but v1 and v2 are wchar_t * */
#define assertEqualWString(v1,v2) \
assertion_equal_wstring(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
/* As above, but raw blocks of bytes. */
#define assertEqualMem(v1, v2, l) \
assertion_equal_mem(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (l), #l, NULL)
-/* Assert two files are the same; allow printf-style expansion of second name.
- * See below for comments about variable arguments here...
- */
-#define assertEqualFile \
- assertion_setup(__FILE__, __LINE__);assertion_equal_file
-/* Assert that a file is empty; supports printf-style arguments. */
-#define assertEmptyFile \
- assertion_setup(__FILE__, __LINE__);assertion_empty_file
-/* Assert that a file is not empty; supports printf-style arguments. */
-#define assertNonEmptyFile \
- assertion_setup(__FILE__, __LINE__);assertion_non_empty_file
+/* Assert two files are the same. */
+#define assertEqualFile(f1, f2) \
+ assertion_equal_file(__FILE__, __LINE__, (f1), (f2))
+/* Assert that a file is empty. */
+#define assertEmptyFile(pathname) \
+ assertion_empty_file(__FILE__, __LINE__, (pathname))
+/* Assert that a file is not empty. */
+#define assertNonEmptyFile(pathname) \
+ assertion_non_empty_file(__FILE__, __LINE__, (pathname))
#define assertFileAtime(pathname, sec, nsec) \
assertion_file_atime(__FILE__, __LINE__, pathname, sec, nsec)
#define assertFileAtimeRecent(pathname) \
@@ -166,14 +160,14 @@
#define assertFileBirthtimeRecent(pathname) \
assertion_file_birthtime_recent(__FILE__, __LINE__, pathname)
/* Assert that a file exists; supports printf-style arguments. */
-#define assertFileExists \
- assertion_setup(__FILE__, __LINE__);assertion_file_exists
-/* Assert that a file exists; supports printf-style arguments. */
-#define assertFileNotExists \
- assertion_setup(__FILE__, __LINE__);assertion_file_not_exists
-/* Assert that file contents match a string; supports printf-style arguments. */
-#define assertFileContents \
- assertion_setup(__FILE__, __LINE__);assertion_file_contents
+#define assertFileExists(pathname) \
+ assertion_file_exists(__FILE__, __LINE__, pathname)
+/* Assert that a file exists. */
+#define assertFileNotExists(pathname) \
+ assertion_file_not_exists(__FILE__, __LINE__, pathname)
+/* Assert that file contents match a string. */
+#define assertFileContents(data, data_size, pathname) \
+ assertion_file_contents(__FILE__, __LINE__, data, data_size, pathname)
#define assertFileMtime(pathname, sec, nsec) \
assertion_file_mtime(__FILE__, __LINE__, pathname, sec, nsec)
#define assertFileMtimeRecent(pathname) \
@@ -182,8 +176,10 @@
assertion_file_nlinks(__FILE__, __LINE__, pathname, nlinks)
#define assertFileSize(pathname, size) \
assertion_file_size(__FILE__, __LINE__, pathname, size)
-#define assertTextFileContents \
- assertion_setup(__FILE__, __LINE__);assertion_text_file_contents
+#define assertTextFileContents(text, pathname) \
+ assertion_text_file_contents(__FILE__, __LINE__, text, pathname)
+#define assertFileContainsLinesAnyOrder(pathname, lines) \
+ assertion_file_contains_lines_any_order(__FILE__, __LINE__, pathname, lines)
#define assertIsDir(pathname, mode) \
assertion_is_dir(__FILE__, __LINE__, pathname, mode)
#define assertIsHardlink(path1, path2) \
@@ -205,6 +201,8 @@
assertion_make_symlink(__FILE__, __LINE__, newfile, linkto)
#define assertUmask(mask) \
assertion_umask(__FILE__, __LINE__, mask)
+#define assertUtimes(pathname, atime, atime_nsec, mtime, mtime_nsec) \
+ assertion_utimes(__FILE__, __LINE__, pathname, atime, atime_nsec, mtime, mtime_nsec)
/*
* This would be simple with C99 variadic macros, but I don't want to
@@ -213,28 +211,29 @@
* but effective.
*/
#define skipping \
- assertion_setup(__FILE__, __LINE__);test_skipping
+ skipping_setup(__FILE__, __LINE__);test_skipping
/* Function declarations. These are defined in test_utility.c. */
void failure(const char *fmt, ...);
int assertion_assert(const char *, int, int, const char *, void *);
int assertion_chdir(const char *, int, const char *);
-int assertion_empty_file(const char *, ...);
-int assertion_equal_file(const char *, const char *, ...);
+int assertion_empty_file(const char *, int, const char *);
+int assertion_equal_file(const char *, int, const char *, const char *);
int assertion_equal_int(const char *, int, long long, const char *, long long, const char *, void *);
int assertion_equal_mem(const char *, int, const void *, const char *, const void *, const char *, size_t, const char *, void *);
-int assertion_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *);
+int assertion_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *, int);
int assertion_equal_wstring(const char *, int, const wchar_t *v1, const char *, const wchar_t *v2, const char *, void *);
int assertion_file_atime(const char *, int, const char *, long, long);
int assertion_file_atime_recent(const char *, int, const char *);
int assertion_file_birthtime(const char *, int, const char *, long, long);
int assertion_file_birthtime_recent(const char *, int, const char *);
-int assertion_file_contents(const void *, int, const char *, ...);
-int assertion_file_exists(const char *, ...);
+int assertion_file_contains_lines_any_order(const char *, int, const char *, const char **);
+int assertion_file_contents(const char *, int, const void *, int, const char *);
+int assertion_file_exists(const char *, int, const char *);
int assertion_file_mtime(const char *, int, const char *, long, long);
int assertion_file_mtime_recent(const char *, int, const char *);
int assertion_file_nlinks(const char *, int, const char *, int);
-int assertion_file_not_exists(const char *, ...);
+int assertion_file_not_exists(const char *, int, const char *);
int assertion_file_size(const char *, int, const char *, long);
int assertion_is_dir(const char *, int, const char *, int);
int assertion_is_hardlink(const char *, int, const char *, const char *);
@@ -245,11 +244,12 @@ int assertion_make_dir(const char *, int, const char *, int);
int assertion_make_file(const char *, int, const char *, int, const char *);
int assertion_make_hardlink(const char *, int, const char *newpath, const char *);
int assertion_make_symlink(const char *, int, const char *newpath, const char *);
-int assertion_non_empty_file(const char *, ...);
-int assertion_text_file_contents(const char *buff, const char *f);
+int assertion_non_empty_file(const char *, int, const char *);
+int assertion_text_file_contents(const char *, int, const char *buff, const char *f);
int assertion_umask(const char *, int, int);
-void assertion_setup(const char *, int);
+int assertion_utimes(const char *, int, const char *, long, long, long, long );
+void skipping_setup(const char *, int);
void test_skipping(const char *fmt, ...);
/* Like sprintf, then system() */
@@ -267,6 +267,9 @@ int canGzip(void);
/* Return true if this platform can run the "gunzip" program. */
int canGunzip(void);
+/* Return true if the file has large i-node number(>0xffffffff). */
+int is_LargeInode(const char *);
+
/* Suck file into string allocated via malloc(). Call free() when done. */
/* Supports printf-style args: slurpfile(NULL, "%s/myfile", refdir); */
char *slurpfile(size_t *, const char *fmt, ...);
@@ -274,6 +277,9 @@ char *slurpfile(size_t *, const char *fmt, ...);
/* Extracts named reference file to the current directory. */
void extract_reference_file(const char *);
+/* Path to working directory for current test */
+const char *testworkdir;
+
/*
* Special interfaces for program test harness.
*/
@@ -283,3 +289,7 @@ const char *testprogfile;
/* Name of exe to use in printf-formatted command strings. */
/* On Windows, this includes leading/trailing quotes. */
const char *testprog;
+
+#ifdef USE_DMALLOC
+#include <dmalloc.h>
+#endif
diff --git a/cpio/test/test_0.c b/cpio/test/test_0.c
index 75a1437fd70e..fa52def7eaf3 100644
--- a/cpio/test/test_0.c
+++ b/cpio/test/test_0.c
@@ -40,15 +40,23 @@ DEFINE_TEST(test_0)
struct stat st;
failure("File %s does not exist?!", testprogfile);
- if (!assertEqualInt(0, stat(testprogfile, &st)))
+ if (!assertEqualInt(0, stat(testprogfile, &st))) {
+ fprintf(stderr,
+ "\nFile %s does not exist; aborting test.\n\n",
+ testprog);
exit(1);
+ }
failure("%s is not executable?!", testprogfile);
- if (!assert((st.st_mode & 0111) != 0))
+ if (!assert((st.st_mode & 0111) != 0)) {
+ fprintf(stderr,
+ "\nFile %s not executable; aborting test.\n\n",
+ testprog);
exit(1);
+ }
/*
- * Try to succesfully run the program; this requires that
+ * Try to successfully run the program; this requires that
* we know some option that will succeed.
*/
if (0 == systemf("%s --version >" DEV_NULL, testprog)) {
diff --git a/cpio/test/test_basic.c b/cpio/test/test_basic.c
index 852b069a16e7..c40813e9a26f 100644
--- a/cpio/test/test_basic.c
+++ b/cpio/test/test_basic.c
@@ -33,12 +33,15 @@ verify_files(const char *msg)
*/
/* Regular file with 2 links. */
+ failure(msg);
assertIsReg("file", 0644);
failure(msg);
assertFileSize("file", 10);
+ failure(msg);
assertFileNLinks("file", 2);
/* Another name for the same file. */
+ failure(msg);
assertIsHardlink("linkfile", "file");
/* Symlink */
@@ -46,8 +49,11 @@ verify_files(const char *msg)
assertIsSymlink("symlink", "file");
/* Another file with 1 link and different permissions. */
+ failure(msg);
assertIsReg("file2", 0777);
+ failure(msg);
assertFileSize("file2", 10);
+ failure(msg);
assertFileNLinks("file2", 1);
/* dir */
@@ -58,7 +64,7 @@ static void
basic_cpio(const char *target,
const char *pack_options,
const char *unpack_options,
- const char *se)
+ const char *se, const char *se2)
{
int r;
@@ -87,7 +93,7 @@ basic_cpio(const char *target,
/* Verify stderr. */
failure("Error invoking %s -i %s in dir %s", testprog, unpack_options, target);
- assertTextFileContents(se, "unpack.err");
+ assertTextFileContents(se2, "unpack.err");
verify_files(pack_options);
@@ -125,6 +131,7 @@ DEFINE_TEST(test_basic)
{
FILE *filelist;
const char *msg;
+ char result[1024];
assertUmask(0);
@@ -132,28 +139,56 @@ DEFINE_TEST(test_basic)
* Create an assortment of files on disk.
*/
filelist = fopen("filelist", "w");
+ memset(result, 0, sizeof(result));
/* File with 10 bytes content. */
assertMakeFile("file", 0644, "1234567890");
fprintf(filelist, "file\n");
+ if (is_LargeInode("file"))
+ strncat(result,
+ "bsdcpio: file: large inode number truncated: "
+ "Numerical result out of range\n",
+ sizeof(result) - strlen(result));
/* hardlink to above file. */
assertMakeHardlink("linkfile", "file");
fprintf(filelist, "linkfile\n");
+ if (is_LargeInode("linkfile"))
+ strncat(result,
+ "bsdcpio: linkfile: large inode number truncated: "
+ "Numerical result out of range\n",
+ sizeof(result) - strlen(result));
/* Symlink to above file. */
if (canSymlink()) {
assertMakeSymlink("symlink", "file");
fprintf(filelist, "symlink\n");
+ if (is_LargeInode("symlink"))
+ strncat(result,
+ "bsdcpio: symlink: large inode number truncated: "
+ "Numerical result out of range\n",
+ sizeof(result) - strlen(result));
}
/* Another file with different permissions. */
assertMakeFile("file2", 0777, "1234567890");
fprintf(filelist, "file2\n");
+ if (is_LargeInode("file2"))
+ strncat(result,
+ "bsdcpio: file2: large inode number truncated: "
+ "Numerical result out of range\n",
+ sizeof(result) - strlen(result));
/* Directory. */
assertMakeDir("dir", 0775);
fprintf(filelist, "dir\n");
+ if (is_LargeInode("dir"))
+ strncat(result,
+ "bsdcpio: dir: large inode number truncated: "
+ "Numerical result out of range\n",
+ sizeof(result) - strlen(result));
+ strncat(result, "2 blocks\n", sizeof(result) - strlen(result));
+
/* All done. */
fclose(filelist);
@@ -161,12 +196,12 @@ DEFINE_TEST(test_basic)
/* Archive/dearchive with a variety of options. */
msg = canSymlink() ? "2 blocks\n" : "1 block\n";
- basic_cpio("copy", "", "", msg);
- basic_cpio("copy_odc", "--format=odc", "", msg);
- basic_cpio("copy_newc", "-H newc", "", "2 blocks\n");
- basic_cpio("copy_cpio", "-H odc", "", msg);
+ basic_cpio("copy", "", "", msg, msg);
+ basic_cpio("copy_odc", "--format=odc", "", msg, msg);
+ basic_cpio("copy_newc", "-H newc", "", result, "2 blocks\n");
+ basic_cpio("copy_cpio", "-H odc", "", msg, msg);
msg = canSymlink() ? "9 blocks\n" : "8 blocks\n";
- basic_cpio("copy_ustar", "-H ustar", "", msg);
+ basic_cpio("copy_ustar", "-H ustar", "", msg, msg);
/* Copy in one step using -p */
passthrough("passthrough");
diff --git a/cpio/test/test_format_newc.c b/cpio/test/test_format_newc.c
index 06749a2f9caa..ced62a639e7a 100644
--- a/cpio/test/test_format_newc.c
+++ b/cpio/test/test_format_newc.c
@@ -68,6 +68,16 @@ from_hex(const char *p, size_t l)
return (r);
}
+#if !defined(_WIN32) || defined(__CYGWIN__)
+static int
+nlinks(const char *p)
+{
+ struct stat st;
+ assertEqualInt(0, stat(p, &st));
+ return st.st_nlink;
+}
+#endif
+
DEFINE_TEST(test_format_newc)
{
FILE *list;
@@ -77,6 +87,7 @@ DEFINE_TEST(test_format_newc)
time_t t, t2, now;
char *p, *e;
size_t s, fs, ns;
+ char result[1024];
assertUmask(0);
@@ -111,6 +122,29 @@ DEFINE_TEST(test_format_newc)
assertMakeDir("dir", 0775);
fprintf(list, "dir\n");
+ /* Setup result message. */
+ memset(result, 0, sizeof(result));
+ if (is_LargeInode("file1"))
+ strncat(result,
+ "bsdcpio: file1: large inode number truncated: "
+ "Numerical result out of range\n",
+ sizeof(result) - strlen(result) -1);
+ if (canSymlink() && is_LargeInode("symlink"))
+ strncat(result,
+ "bsdcpio: symlink: large inode number truncated: "
+ "Numerical result out of range\n",
+ sizeof(result) - strlen(result) -1);
+ if (is_LargeInode("dir"))
+ strncat(result,
+ "bsdcpio: dir: large inode number truncated: "
+ "Numerical result out of range\n",
+ sizeof(result) - strlen(result) -1);
+ if (is_LargeInode("hardlink"))
+ strncat(result,
+ "bsdcpio: hardlink: large inode number truncated: "
+ "Numerical result out of range\n",
+ sizeof(result) - strlen(result) -1);
+
/* Record some facts about what we just created: */
now = time(NULL); /* They were all created w/in last two seconds. */
@@ -123,10 +157,11 @@ DEFINE_TEST(test_format_newc)
/* Verify that nothing went to stderr. */
if (canSymlink()) {
- assertTextFileContents("2 blocks\n", "newc.err");
+ strncat(result, "2 blocks\n", sizeof(result) - strlen(result));
} else {
- assertTextFileContents("1 block\n", "newc.err");
+ strncat(result, "1 block\n", sizeof(result) - strlen(result));
}
+ assertTextFileContents(result, "newc.err");
/* Verify that stdout is a well-formed cpio file in "newc" format. */
p = slurpfile(&s, "newc.out");
@@ -216,10 +251,10 @@ DEFINE_TEST(test_format_newc)
/* Mode: sgid bit sometimes propagates from parent dirs, ignore it. */
assertEqualInt(040775, from_hex(e + 14, 8) & ~02000);
#endif
- assertEqualInt(from_hex(e + 22, 8), uid); /* uid */
+ assertEqualInt(uid, from_hex(e + 22, 8)); /* uid */
assertEqualInt(gid, from_hex(e + 30, 8)); /* gid */
-#ifndef NLINKS_INACCURATE_FOR_DIRS
- assertEqualMem(e + 38, "00000002", 8); /* nlink */
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ assertEqualInt(nlinks("dir"), from_hex(e + 38, 8)); /* nlinks */
#endif
t2 = from_hex(e + 46, 8); /* mtime */
failure("First entry created at t=0x%08x this entry created at t2=0x%08x", t, t2);
diff --git a/cpio/test/test_option_0.c b/cpio/test/test_option_0.c
new file mode 100644
index 000000000000..bc4aecd2afc2
--- /dev/null
+++ b/cpio/test/test_option_0.c
@@ -0,0 +1,92 @@
+/*-
+ * Copyright (c) 2003-2010 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+DEFINE_TEST(test_option_0)
+{
+ FILE *filelist;
+ int r;
+
+ assertUmask(0);
+
+ /* Create a few files. */
+ assertMakeFile("file1", 0644, "1234567890");
+ assertMakeFile("file2", 0644, "1234567890");
+ assertMakeFile("file3", 0644, "1234567890");
+ assertMakeFile("file4", 0644, "1234567890");
+
+ /* Create a file list of filenames with varying end-of-line. */
+ filelist = fopen("filelist", "wb");
+ assertEqualInt(fwrite("file1\x0a", 1, 6, filelist), 6);
+ assertEqualInt(fwrite("file2\x0d", 1, 6, filelist), 6);
+ assertEqualInt(fwrite("file3\x0a\x0d", 1, 7, filelist), 7);
+ assertEqualInt(fwrite("file4", 1, 5, filelist), 5);
+ fclose(filelist);
+
+ /* Create a file list of null-delimited names. */
+ filelist = fopen("filelistNull", "wb");
+ assertEqualInt(fwrite("file1\0", 1, 6, filelist), 6);
+ assertEqualInt(fwrite("file2\0", 1, 6, filelist), 6);
+ assertEqualInt(fwrite("file3\0", 1, 6, filelist), 6);
+ assertEqualInt(fwrite("file4", 1, 5, filelist), 5);
+ fclose(filelist);
+
+ assertUmask(022);
+
+ /* Pack up using the file list with text line endings. */
+ r = systemf("%s -o < filelist > archive 2> stderr1.txt", testprog);
+ assertEqualInt(r, 0);
+
+ /* Extract into a new dir. */
+ assertMakeDir("copy", 0775);
+ assertChdir("copy");
+ r = systemf("%s -i < ../archive > stdout3.txt 2> stderr3.txt", testprog);
+ assertEqualInt(r, 0);
+
+ /* Verify the files. */
+ assertIsReg("file1", 0644);
+ assertIsReg("file2", 0644);
+ assertIsReg("file3", 0644);
+ assertIsReg("file4", 0644);
+
+ assertChdir("..");
+
+ /* Pack up using the file list with nulls. */
+ r = systemf("%s -o0 < filelistNull > archiveNull 2> stderr2.txt", testprog);
+ assertEqualInt(r, 0);
+
+ /* Extract into a new dir. */
+ assertMakeDir("copyNull", 0775);
+ assertChdir("copyNull");
+ r = systemf("%s -i < ../archiveNull > stdout4.txt 2> stderr4.txt", testprog);
+ assertEqualInt(r, 0);
+
+ /* Verify the files. */
+ assertIsReg("file1", 0644);
+ assertIsReg("file2", 0644);
+ assertIsReg("file3", 0644);
+ assertIsReg("file4", 0644);
+}
diff --git a/cpio/test/test_option_c.c b/cpio/test/test_option_c.c
index 63dcdbd53d46..a634be10ba7c 100644
--- a/cpio/test/test_option_c.c
+++ b/cpio/test/test_option_c.c
@@ -51,6 +51,16 @@ from_octal(const char *p, size_t l)
return (r);
}
+#if !defined(_WIN32) || defined(__CYGWIN__)
+static int
+nlinks(const char *p)
+{
+ struct stat st;
+ assertEqualInt(0, stat(p, &st));
+ return st.st_nlink;
+}
+#endif
+
DEFINE_TEST(test_option_c)
{
FILE *filelist;
@@ -181,17 +191,19 @@ DEFINE_TEST(test_option_c)
/* Group members bits and others bits do not work. */
assertEqualMem(e + 18, "040777", 6); /* Mode */
#else
- /* Accept 042775 to accomodate systems where sgid bit propagates. */
+ /* Accept 042775 to accommodate systems where sgid bit propagates. */
if (memcmp(e + 18, "042775", 6) != 0)
assertEqualMem(e + 18, "040775", 6); /* Mode */
#endif
- assertEqualInt(from_octal(e + 24, 6), uid); /* uid */
+ assertEqualInt(uid, from_octal(e + 24, 6)); /* uid */
/* Gid should be same as first entry. */
assert(is_octal(e + 30, 6)); /* gid */
assertEqualInt(gid, from_octal(e + 30, 6));
-#ifndef NLINKS_INACCURATE_FOR_DIRS
- assertEqualMem(e + 36, "000002", 6); /* Nlink */
+
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ assertEqualInt(nlinks("dir"), from_octal(e + 36, 6)); /* Nlink */
#endif
+
t = from_octal(e + 48, 11); /* mtime */
assert(t <= now); /* File wasn't created in future. */
assert(t >= now - 2); /* File was created w/in last 2 secs. */
diff --git a/cpio/test/test_option_t.c b/cpio/test/test_option_t.c
index 4427bb3a6cd7..6bcaee3c87ce 100644
--- a/cpio/test/test_option_t.c
+++ b/cpio/test/test_option_t.c
@@ -25,11 +25,17 @@
#include "test.h"
__FBSDID("$FreeBSD$");
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#endif
DEFINE_TEST(test_option_t)
{
char *p;
int r;
+ time_t mtime;
+ char date[32];
+ char date2[32];
/* List reference archive, make sure the TOC is correct. */
extract_reference_file("test_option_t.cpio");
@@ -75,17 +81,20 @@ DEFINE_TEST(test_option_t)
/* Since -n uses numeric UID/GID, this part should be the
* same on every system. */
assertEqualMem(p, "-rw-r--r-- 1 1000 1000 0 ",42);
- /* Date varies depending on local timezone. */
- if (memcmp(p + 42, "Dec 31 1969", 12) == 0) {
- /* East of Greenwich we get Dec 31, 1969. */
- } else {
- /* West of Greenwich get Jan 1, 1970 */
- assertEqualMem(p + 42, "Jan ", 4);
- /* Some systems format "Jan 01", some "Jan 1" */
- assert(p[46] == ' ' || p[46] == '0');
- assertEqualMem(p + 47, "1 1970 ", 8);
- }
- assertEqualMem(p + 54, " file", 5);
+
+ /* Date varies depending on local timezone and locale. */
+ mtime = 1;
+#ifdef HAVE_LOCALE_H
+ setlocale(LC_ALL, "");
+#endif
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ strftime(date2, sizeof(date), "%b %d %Y", localtime(&mtime));
+ _snprintf(date, sizeof(date)-1, "%12s file", date2);
+#else
+ strftime(date2, sizeof(date), "%b %e %Y", localtime(&mtime));
+ snprintf(date, sizeof(date)-1, "%12s file", date2);
+#endif
+ assertEqualMem(p + 42, date, strlen(date));
free(p);
/* But "-n" without "-t" is an error. */
diff --git a/cpio/test/test_option_u.c b/cpio/test/test_option_u.c
index 08058aa45396..b377def020fb 100644
--- a/cpio/test/test_option_u.c
+++ b/cpio/test/test_option_u.c
@@ -41,7 +41,7 @@ DEFINE_TEST(test_option_u)
assertMakeFile("f", 0644, "a");
/* Copy the file to the "copy" dir. */
- r = systemf("echo f | %s -pd copy >copy.out 2>copy.err",
+ r = systemf("echo f| %s -pd copy >copy.out 2>copy.err",
testprog);
assertEqualInt(r, 0);
@@ -60,7 +60,7 @@ DEFINE_TEST(test_option_u)
assertEqualInt(0, utime("f", &times));
/* Copy the file to the "copy" dir. */
- r = systemf("echo f | %s -pd copy >copy.out 2>copy.err",
+ r = systemf("echo f| %s -pd copy >copy.out 2>copy.err",
testprog);
assertEqualInt(r, 0);
@@ -70,7 +70,7 @@ DEFINE_TEST(test_option_u)
assertEqualMem(p, "a", 1);
/* Copy the file to the "copy" dir with -u (force) */
- r = systemf("echo f | %s -pud copy >copy.out 2>copy.err",
+ r = systemf("echo f| %s -pud copy >copy.out 2>copy.err",
testprog);
assertEqualInt(r, 0);
diff --git a/cpio/test/test_owner_parse.c b/cpio/test/test_owner_parse.c
index d07724e0e776..a9f605398e36 100644
--- a/cpio/test/test_owner_parse.c
+++ b/cpio/test/test_owner_parse.c
@@ -30,9 +30,8 @@ __FBSDID("$FreeBSD$");
#if !defined(_WIN32)
#define ROOT "root"
-static int root_uids[] = { 0 };
-/* Solaris 9 root has gid 1 (other) */
-static int root_gids[] = { 0, 1 };
+static const int root_uids[] = { 0 };
+static const int root_gids[] = { 0, 1 };
#elif defined(__CYGWIN__)
/* On cygwin, the Administrator user most likely exists (unless
* it has been renamed or is in a non-English localization), but
@@ -43,13 +42,13 @@ static int root_gids[] = { 0, 1 };
* Use CreateWellKnownSID() and LookupAccountName()?
*/
#define ROOT "Administrator"
-static int root_uids[] = { 500 };
-static int root_gids[] = { 513, 545, 544 };
+static const int root_uids[] = { 500 };
+static const int root_gids[] = { 513, 545, 544 };
#endif
#if defined(ROOT)
static int
-int_in_list(int i, int *l, size_t n)
+int_in_list(int i, const int *l, size_t n)
{
while (n-- > 0)
if (*l++ == i)
diff --git a/doc/html/.ignore_me b/doc/html/.ignore_me
new file mode 100644
index 000000000000..d285484d4fee
--- /dev/null
+++ b/doc/html/.ignore_me
@@ -0,0 +1,2 @@
+*** PLEASE DO NOT DELETE THIS FILE! ***
+This file is used to track an otherwise empty directory in git.
diff --git a/doc/man/.ignore_me b/doc/man/.ignore_me
new file mode 100644
index 000000000000..d285484d4fee
--- /dev/null
+++ b/doc/man/.ignore_me
@@ -0,0 +1,2 @@
+*** PLEASE DO NOT DELETE THIS FILE! ***
+This file is used to track an otherwise empty directory in git.
diff --git a/doc/mdoc2wiki.awk b/doc/mdoc2wiki.awk
index 146d9619824f..fcccd9b3a2b6 100644
--- a/doc/mdoc2wiki.awk
+++ b/doc/mdoc2wiki.awk
@@ -255,10 +255,7 @@ function splitwords(l, dest, n, o, w) {
} else if(match(words[w],"^Nd$")) {
add("- " wtail())
} else if(match(words[w],"^Fl$")) {
- if (displaylines == 0)
- add("*-" words[++w] "*")
- else
- add("-" words[++w])
+ addopen("-")
} else if(match(words[w],"^Ar$")) {
if(w==nwords)
add("_file ..._")
@@ -422,6 +419,9 @@ function splitwords(l, dest, n, o, w) {
addpunct("<li>")
listnext[listdepth] = "</li>"
}
+ } else if(match(words[w], "^Vt$")) {
+ w++
+ add("_" words[w] "_")
} else if(match(words[w],"^Xo$")) {
# TODO: Figure out how to handle this
} else if(match(words[w],"^Xc$")) {
diff --git a/doc/pdf/.ignore_me b/doc/pdf/.ignore_me
new file mode 100644
index 000000000000..d285484d4fee
--- /dev/null
+++ b/doc/pdf/.ignore_me
@@ -0,0 +1,2 @@
+*** PLEASE DO NOT DELETE THIS FILE! ***
+This file is used to track an otherwise empty directory in git.
diff --git a/doc/text/.ignore_me b/doc/text/.ignore_me
new file mode 100644
index 000000000000..d285484d4fee
--- /dev/null
+++ b/doc/text/.ignore_me
@@ -0,0 +1,2 @@
+*** PLEASE DO NOT DELETE THIS FILE! ***
+This file is used to track an otherwise empty directory in git.
diff --git a/doc/wiki/.ignore_me b/doc/wiki/.ignore_me
new file mode 100644
index 000000000000..d285484d4fee
--- /dev/null
+++ b/doc/wiki/.ignore_me
@@ -0,0 +1,2 @@
+*** PLEASE DO NOT DELETE THIS FILE! ***
+This file is used to track an otherwise empty directory in git.
diff --git a/examples/minitar/Makefile b/examples/minitar/Makefile
index 3cd61f36e7e0..1ec4593df66b 100644
--- a/examples/minitar/Makefile
+++ b/examples/minitar/Makefile
@@ -5,29 +5,21 @@
#
CFLAGS= \
-DNO_BZIP2_CREATE \
- -DNO_BZIP2_EXTRACT \
- -DNO_COMPRESS_EXTRACT \
- -DNO_CPIO_EXTRACT \
- -DNO_CREATE \
- -DNO_GZIP_CREATE \
- -DNO_GZIP_EXTRACT \
- -DNO_LOOKUP
+ -I../../libarchive \
+ -g
-# Omit 'tree.o' if you're not including create support
-#OBJS= minitar.o tree.o
-OBJS= minitar.o
+# How to link against libarchive.
+LIBARCHIVE= ../../libarchive/libarchive.a
all: minitar
-minitar: $(OBJS)
- cc -o minitar -static $(OBJS) -larchive -lz -lbz2
+minitar: minitar.o
+ cc -g -o minitar minitar.o $(LIBARCHIVE) -lz -lbz2
strip minitar
ls -l minitar
minitar.o: minitar.c
-tree.o: tree.c
-
clean::
rm -f *.o
rm -f minitar
diff --git a/examples/minitar/minitar.c b/examples/minitar/minitar.c
index 7e9011183774..2d6d4208a22a 100644
--- a/examples/minitar/minitar.c
+++ b/examples/minitar/minitar.c
@@ -40,8 +40,6 @@
*/
#include <sys/types.h>
-__FBSDID("$FreeBSD$");
-
#include <sys/stat.h>
#include <archive.h>
@@ -52,10 +50,6 @@ __FBSDID("$FreeBSD$");
#include <string.h>
#include <unistd.h>
-#ifndef NO_CREATE
-#include "tree.h"
-#endif
-
/*
* NO_CREATE implies NO_BZIP2_CREATE and NO_GZIP_CREATE and NO_COMPRESS_CREATE.
*/
@@ -264,32 +258,75 @@ create(const char *filename, int compress, const char **argv)
archive_read_disk_set_standard_lookup(disk);
#endif
while (*argv != NULL) {
- struct tree *t = tree_open(*argv);
- while (tree_next(t)) {
+ struct archive *disk = archive_read_disk_new();
+ int r;
+
+ r = archive_read_disk_open(disk, *argv);
+ if (r != ARCHIVE_OK) {
+ errmsg(archive_error_string(disk));
+ errmsg("\n");
+ exit(1);
+ }
+
+ for (;;) {
+ int needcr = 0;
+
entry = archive_entry_new();
- archive_entry_set_pathname(entry, tree_current_path(t));
- archive_read_disk_entry_from_file(disk, entry, -1,
- tree_current_stat(t));
+ r = archive_read_next_header2(disk, entry);
+ if (r == ARCHIVE_EOF)
+ break;
+ if (r != ARCHIVE_OK) {
+ errmsg(archive_error_string(disk));
+ errmsg("\n");
+ exit(1);
+ }
+ archive_read_disk_descend(disk);
if (verbose) {
msg("a ");
- msg(tree_current_path(t));
+ msg(archive_entry_pathname(entry));
+ needcr = 1;
+ }
+ r = archive_write_header(a, entry);
+ if (r < ARCHIVE_OK) {
+ errmsg(": ");
+ errmsg(archive_error_string(a));
+ needcr = 1;
}
- archive_write_header(a, entry);
- fd = open(tree_current_access_path(t), O_RDONLY);
- len = read(fd, buff, sizeof(buff));
- while (len > 0) {
- archive_write_data(a, buff, len);
+ if (r == ARCHIVE_FATAL)
+ exit(1);
+ if (r > ARCHIVE_FAILED) {
+#if 0
+ /* Ideally, we would be able to use
+ * the same code to copy a body from
+ * an archive_read_disk to an
+ * archive_write that we use for
+ * copying data from an archive_read
+ * to an archive_write_disk.
+ * Unfortunately, this doesn't quite
+ * work yet. */
+ copy_data(disk, a);
+#else
+ /* For now, we use a simpler loop to copy data
+ * into the target archive. */
+ fd = open(archive_entry_sourcepath(entry), O_RDONLY);
len = read(fd, buff, sizeof(buff));
+ while (len > 0) {
+ archive_write_data(a, buff, len);
+ len = read(fd, buff, sizeof(buff));
+ }
+ close(fd);
+#endif
}
- close(fd);
archive_entry_free(entry);
- if (verbose)
+ if (needcr)
msg("\n");
}
+ archive_read_close(disk);
+ archive_read_free(disk);
argv++;
}
archive_write_close(a);
- archive_write_finish(a);
+ archive_write_free(a);
}
#endif
@@ -305,13 +342,13 @@ extract(const char *filename, int do_extract, int flags)
ext = archive_write_disk_new();
archive_write_disk_set_options(ext, flags);
#ifndef NO_BZIP2_EXTRACT
- archive_read_support_compression_bzip2(a);
+ archive_read_support_filter_bzip2(a);
#endif
#ifndef NO_GZIP_EXTRACT
- archive_read_support_compression_gzip(a);
+ archive_read_support_filter_gzip(a);
#endif
#ifndef NO_COMPRESS_EXTRACT
- archive_read_support_compression_compress(a);
+ archive_read_support_filter_compress(a);
#endif
#ifndef NO_TAR_EXTRACT
archive_read_support_format_tar(a);
@@ -353,7 +390,7 @@ extract(const char *filename, int do_extract, int flags)
msg("\n");
}
archive_read_close(a);
- archive_read_finish(a);
+ archive_read_free(a);
exit(0);
}
diff --git a/examples/minitar/tree.c b/examples/minitar/tree.c
deleted file mode 100644
index 8af0b4d88e71..000000000000
--- a/examples/minitar/tree.c
+++ /dev/null
@@ -1,423 +0,0 @@
-/*-
- * Copyright (c) 2003-2004 Tim Kientzle
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer
- * in this position and unchanged.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*-
- * There is a single list of "tree_entry" items that represent
- * filesystem objects that require further attention. Non-directories
- * are not kept in memory: they are pulled from readdir(), returned to
- * the client, then freed as soon as possible. Any directory entry to
- * be traversed gets pushed onto the stack.
- *
- * There is surprisingly little information that needs to be kept for
- * each item on the stack. Just the name, depth (represented here as the
- * string length of the parent directory's pathname), and some markers
- * indicating how to get back to the parent (via chdir("..") for a
- * regular dir or via fchdir(2) for a symlink).
- */
-
-#include <sys/stat.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "tree.h"
-
-/*
- * TODO:
- * 1) Loop checking.
- * 3) Arbitrary logical traversals by closing/reopening intermediate fds.
- */
-
-struct tree_entry {
- struct tree_entry *next;
- char *name;
- size_t dirname_length;
- int fd;
- int flags;
-};
-
-/* Definitions for tree_entry.flags bitmap. */
-#define isDir 1 /* This entry is a regular directory. */
-#define isDirLink 2 /* This entry is a symbolic link to a directory. */
-#define needsTraversal 4 /* This entry hasn't yet been traversed. */
-
-/*
- * Local data for this package.
- */
-struct tree {
- struct tree_entry *stack;
- DIR *d;
- int initialDirFd;
- int flags;
-
- char *buff;
- char *basename;
- size_t buff_length;
- size_t path_length;
- size_t dirname_length;
-
- int depth;
- int openCount;
- int maxOpenCount;
-
- struct stat lst;
- struct stat st;
-};
-
-/* Definitions for tree.flags bitmap. */
-#define needsReturn 8 /* Marks first entry as not having been returned yet. */
-#define hasStat 16 /* The st entry is set. */
-#define hasLstat 32 /* The lst entry is set. */
-
-
-#define HAVE_DIRENT_D_NAMLEN 1
-#ifdef HAVE_DIRENT_D_NAMLEN
-/* BSD extension; avoids need for a strlen() call. */
-#define D_NAMELEN(dp) (dp)->d_namlen
-#else
-#define D_NAMELEN(dp) (strlen((dp)->d_name))
-#endif
-
-#if 0
-static void
-dumpStack(struct tree *t)
-{
- struct tree_entry *te;
-
- printf("\tbuff: %s\n", t->buff);
- printf("\tpwd: "); fflush(stdout); system("pwd");
- printf("\tstack:\n");
- for (te = t->stack; te != NULL; te = te->next) {
- printf("\t\tte->name: %s %s\n", te->name, te->flags & needsTraversal ? "" : "*");
- }
-}
-#endif
-
-/*
- * Add a directory path to the current stack.
- */
-static void
-tree_add(struct tree *t, const char *path)
-{
- struct tree_entry *te;
-
- te = malloc(sizeof(*te));
- memset(te, 0, sizeof(*te));
- te->next = t->stack;
- t->stack = te;
- te->fd = -1;
- te->name = strdup(path);
- te->flags = needsTraversal;
- te->dirname_length = t->dirname_length;
-}
-
-/*
- * Append a name to the current path.
- */
-static void
-tree_append(struct tree *t, const char *name, size_t name_length)
-{
- if (t->buff != NULL)
- t->buff[t->dirname_length] = '\0';
-
- /* Resize pathname buffer as needed. */
- while (name_length + 1 + t->dirname_length >= t->buff_length) {
- t->buff_length *= 2;
- if (t->buff_length < 1024)
- t->buff_length = 1024;
- t->buff = realloc(t->buff, t->buff_length);
- }
- t->basename = t->buff + t->dirname_length;
- t->path_length = t->dirname_length + name_length;
- if (t->dirname_length > 0) {
- *t->basename++ = '/';
- t->path_length ++;
- }
- strcpy(t->basename, name);
-}
-
-/*
- * Open a directory tree for traversal.
- */
-struct tree *
-tree_open(const char *path)
-{
- struct tree *t;
-
- t = malloc(sizeof(*t));
- memset(t, 0, sizeof(*t));
- tree_append(t, path, strlen(path));
- t->initialDirFd = open(".", O_RDONLY);
- /*
- * During most of the traversal, items are set up and then
- * returned immediately from tree_next(). That doesn't work
- * for the very first entry, so we set a flag for this special
- * case.
- */
- t->flags = needsReturn;
- return (t);
-}
-
-/*
- * We've finished a directory; ascend back to the parent.
- */
-static void
-tree_ascend(struct tree *t)
-{
- struct tree_entry *te;
-
- te = t->stack;
- t->depth--;
- if (te->flags & isDirLink) {
- fchdir(te->fd);
- close(te->fd);
- t->openCount--;
- } else {
- chdir("..");
- }
-}
-
-/*
- * Pop the working stack.
- */
-static void
-tree_pop(struct tree *t)
-{
- struct tree_entry *te;
-
- te = t->stack;
- t->stack = te->next;
- t->dirname_length = te->dirname_length;
- free(te->name);
- free(te);
-}
-
-/*
- * Get the next item in the tree traversal.
- */
-int
-tree_next(struct tree *t)
-{
- struct dirent *de = NULL;
-
- /* Handle the startup case by returning the initial entry. */
- if (t->flags & needsReturn) {
- t->flags &= ~needsReturn;
- return (1);
- }
-
- while (t->stack != NULL) {
- /* If there's an open dir, get the next entry from there. */
- while (t->d != NULL) {
- de = readdir(t->d);
- if (de == NULL) {
- closedir(t->d);
- t->d = NULL;
- } else if (de->d_name[0] == '.'
- && de->d_name[1] == '\0') {
- /* Skip '.' */
- } else if (de->d_name[0] == '.'
- && de->d_name[1] == '.'
- && de->d_name[2] == '\0') {
- /* Skip '..' */
- } else {
- /*
- * Append the path to the current path
- * and return it.
- */
- tree_append(t, de->d_name, D_NAMELEN(de));
- t->flags &= ~hasLstat;
- t->flags &= ~hasStat;
- return (1);
- }
- }
-
- /* If the current dir needs to be traversed, set it up. */
- if (t->stack->flags & needsTraversal) {
- tree_append(t, t->stack->name, strlen(t->stack->name));
- t->stack->flags &= ~needsTraversal;
- /* If it is a link, set up fd for the ascent. */
- if (t->stack->flags & isDirLink) {
- t->stack->fd = open(".", O_RDONLY);
- t->openCount++;
- if (t->openCount > t->maxOpenCount)
- t->maxOpenCount = t->openCount;
- }
- if (chdir(t->stack->name) == 0) {
- t->depth++;
- t->dirname_length = t->path_length;
- t->d = opendir(".");
- } else
- tree_pop(t);
- continue;
- }
-
- /* We've done everything necessary for the top stack entry. */
- tree_ascend(t);
- tree_pop(t);
- }
- return (0);
-}
-
-/*
- * Called by the client to mark the directory just returned from
- * tree_next() as needing to be visited.
- */
-void
-tree_descend(struct tree *t)
-{
- const struct stat *s = tree_current_lstat(t);
-
- if (S_ISDIR(s->st_mode)) {
- tree_add(t, t->basename);
- t->stack->flags |= isDir;
- }
-
- if (S_ISLNK(s->st_mode) && S_ISDIR(tree_current_stat(t)->st_mode)) {
- tree_add(t, t->basename);
- t->stack->flags |= isDirLink;
- }
-}
-
-/*
- * Get the stat() data for the entry just returned from tree_next().
- */
-const struct stat *
-tree_current_stat(struct tree *t)
-{
- if (!(t->flags & hasStat)) {
- stat(t->basename, &t->st);
- t->flags |= hasStat;
- }
- return (&t->st);
-}
-
-/*
- * Get the lstat() data for the entry just returned from tree_next().
- */
-const struct stat *
-tree_current_lstat(struct tree *t)
-{
- if (!(t->flags & hasLstat)) {
- lstat(t->basename, &t->lst);
- t->flags |= hasLstat;
- }
- return (&t->lst);
-}
-
-/*
- * Return the access path for the entry just returned from tree_next().
- */
-const char *
-tree_current_access_path(struct tree *t)
-{
- return (t->basename);
-}
-
-/*
- * Return the full path for the entry just returned from tree_next().
- */
-const char *
-tree_current_path(struct tree *t)
-{
- return (t->buff);
-}
-
-/*
- * Return the length of the path for the entry just returned from tree_next().
- */
-size_t
-tree_current_pathlen(struct tree *t)
-{
- return (t->path_length);
-}
-
-/*
- * Return the nesting depth of the entry just returned from tree_next().
- */
-int
-tree_current_depth(struct tree *t)
-{
- return (t->depth);
-}
-
-/*
- * Terminate the traversal and release any resources.
- */
-void
-tree_close(struct tree *t)
-{
- /* Release anything remaining in the stack. */
- while (t->stack != NULL)
- tree_pop(t);
- if (t->buff)
- free(t->buff);
- /* chdir() back to where we started. */
- if (t->initialDirFd >= 0) {
- fchdir(t->initialDirFd);
- close(t->initialDirFd);
- t->initialDirFd = -1;
- }
- free(t);
-}
-
-
-#if 0
-/* Main function for testing. */
-#include <stdio.h>
-
-int main(int argc, char **argv)
-{
- size_t max_path_len = 0;
- int max_depth = 0;
-
- system("pwd");
- while (*++argv) {
- struct tree *t = tree_open(*argv);
- while (tree_next(t)) {
- size_t path_len = tree_current_pathlen(t);
- int depth = tree_current_depth(t);
- if (path_len > max_path_len)
- max_path_len = path_len;
- if (depth > max_depth)
- max_depth = depth;
- printf("%s\n", tree_current_path(t));
- if (S_ISDIR(tree_current_lstat(t)->st_mode))
- tree_descend(t); /* Descend into every dir. */
- }
- tree_close(t);
- printf("Max path length: %d\n", max_path_len);
- printf("Max depth: %d\n", max_depth);
- printf("Final open count: %d\n", t->openCount);
- printf("Max open count: %d\n", t->maxOpenCount);
- fflush(stdout);
- system("pwd");
- }
- return (0);
-}
-#endif
diff --git a/examples/minitar/tree.h b/examples/minitar/tree.h
deleted file mode 100644
index 554e6c2da219..000000000000
--- a/examples/minitar/tree.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*-
- * Copyright (c) 2003-2004 Tim Kientzle
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer
- * in this position and unchanged.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*-
- * A set of routines for traversing directory trees.
- * Similar in concept to the fts library, but with a few
- * important differences:
- * * Uses less memory. In particular, fts stores an entire directory
- * in memory at a time. This package only keeps enough subdirectory
- * information in memory to track the traversal. Information
- * about non-directories is discarded as soon as possible.
- * * Supports very deep logical traversals. The fts package
- * uses "non-chdir" approach for logical traversals. This
- * package does use a chdir approach for logical traversals
- * and can therefore handle pathnames much longer than
- * PATH_MAX.
- * * Supports deep physical traversals "out of the box."
- * Due to the memory optimizations above, there's no need to
- * limit dir names to 32k.
- */
-
-#include <sys/stat.h>
-
-struct tree;
-
-struct tree *tree_open(const char *);
-/* Returns TRUE if there is a next entry. Zero if there is no next entry. */
-int tree_next(struct tree *);
-/* Return information about the current entry. */
-int tree_current_depth(struct tree *);
-/*
- * The current full pathname, length of the full pathname,
- * and a name that can be used to access the file.
- * Because tree does use chdir extensively, the access path is
- * almost never the same as the full current path.
- */
-const char *tree_current_path(struct tree *);
-size_t tree_current_pathlen(struct tree *);
-const char *tree_current_access_path(struct tree *);
-/*
- * Request the lstat() or stat() data for the current path.
- * Since the tree package needs to do some of this anyway,
- * you should take advantage of it here if you need it.
- */
-const struct stat *tree_current_stat(struct tree *);
-const struct stat *tree_current_lstat(struct tree *);
-/*
- * Request that current entry be visited. If you invoke it on every
- * directory, you'll get a physical traversal. This is ignored if the
- * current entry isn't a directory or a link to a directory. So, if
- * you invoke this on every returned path, you'll get a full logical
- * traversal.
- */
-void tree_descend(struct tree *);
-void tree_close(struct tree *);
diff --git a/examples/tarfilter.c b/examples/tarfilter.c
index b7e08cfc1dac..0d323e1cb2cb 100644
--- a/examples/tarfilter.c
+++ b/examples/tarfilter.c
@@ -49,7 +49,7 @@ main(int argc, char **argv)
ina = archive_read_new();
if (ina == NULL)
die("Couldn't create archive reader.");
- if (archive_read_support_compression_all(ina) != ARCHIVE_OK)
+ if (archive_read_support_filter_all(ina) != ARCHIVE_OK)
die("Couldn't enable decompression");
if (archive_read_support_format_all(ina) != ARCHIVE_OK)
die("Couldn't enable read formats");
@@ -105,9 +105,9 @@ main(int argc, char **argv)
if (r != ARCHIVE_EOF)
die("Error reading archive");
/* Close the archives. */
- if (archive_read_finish(ina) != ARCHIVE_OK)
+ if (archive_read_free(ina) != ARCHIVE_OK)
die("Error closing input archive");
- if (archive_write_finish(outa) != ARCHIVE_OK)
+ if (archive_write_free(outa) != ARCHIVE_OK)
die("Error closing output archive");
return (0);
}
diff --git a/examples/untar.c b/examples/untar.c
index e77adf701257..c027f7735b87 100644
--- a/examples/untar.c
+++ b/examples/untar.c
@@ -190,7 +190,7 @@ extract(const char *filename, int do_extract, int flags)
msg("\n");
}
archive_read_close(a);
- archive_read_finish(a);
+ archive_read_free(a);
exit(0);
}
@@ -200,7 +200,11 @@ copy_data(struct archive *ar, struct archive *aw)
int r;
const void *buff;
size_t size;
+#if ARCHIVE_VERSION >= 3000000
+ int64_t offset;
+#else
off_t offset;
+#endif
for (;;) {
r = archive_read_data_block(ar, &buff, &size, &offset);
diff --git a/libarchive/CMakeLists.txt b/libarchive/CMakeLists.txt
index 459a5ddbb903..a801fb2888f5 100644
--- a/libarchive/CMakeLists.txt
+++ b/libarchive/CMakeLists.txt
@@ -13,23 +13,34 @@ SET(include_HEADERS
# Sources and private headers
SET(libarchive_SOURCES
+ archive_acl.c
archive_check_magic.c
+ archive_crypto.c
+ archive_crypto_private.h
archive_endian.h
archive_entry.c
archive_entry.h
archive_entry_copy_stat.c
archive_entry_link_resolver.c
+ archive_entry_locale.h
archive_entry_private.h
+ archive_entry_sparse.c
archive_entry_stat.c
archive_entry_strmode.c
archive_entry_xattr.c
- archive_hash.h
+ archive_options.c
+ archive_options_private.h
archive_platform.h
+ archive_ppmd_private.h
+ archive_ppmd7.c
+ archive_ppmd7_private.h
archive_private.h
+ archive_rb.c
+ archive_rb.h
archive_read.c
archive_read_data_into_fd.c
- archive_read_disk.c
archive_read_disk_entry_from_file.c
+ archive_read_disk_posix.c
archive_read_disk_private.h
archive_read_disk_set_standard_lookup.c
archive_read_extract.c
@@ -38,32 +49,39 @@ SET(libarchive_SOURCES
archive_read_open_filename.c
archive_read_open_memory.c
archive_read_private.h
- archive_read_support_compression_all.c
- archive_read_support_compression_bzip2.c
- archive_read_support_compression_compress.c
- archive_read_support_compression_gzip.c
- archive_read_support_compression_none.c
- archive_read_support_compression_program.c
- archive_read_support_compression_rpm.c
- archive_read_support_compression_uu.c
- archive_read_support_compression_xz.c
+ archive_read_set_options.c
+ archive_read_support_filter_all.c
+ archive_read_support_filter_bzip2.c
+ archive_read_support_filter_compress.c
+ archive_read_support_filter_gzip.c
+ archive_read_support_filter_none.c
+ archive_read_support_filter_program.c
+ archive_read_support_filter_rpm.c
+ archive_read_support_filter_uu.c
+ archive_read_support_filter_xz.c
+ archive_read_support_format_7zip.c
archive_read_support_format_all.c
archive_read_support_format_ar.c
+ archive_read_support_format_by_code.c
+ archive_read_support_format_cab.c
archive_read_support_format_cpio.c
archive_read_support_format_empty.c
archive_read_support_format_iso9660.c
+ archive_read_support_format_lha.c
archive_read_support_format_mtree.c
+ archive_read_support_format_rar.c
archive_read_support_format_raw.c
archive_read_support_format_tar.c
archive_read_support_format_xar.c
archive_read_support_format_zip.c
archive_string.c
archive_string.h
+ archive_string_composition.h
archive_string_sprintf.c
archive_util.c
archive_virtual.c
archive_write.c
- archive_write_disk.c
+ archive_write_disk_posix.c
archive_write_disk_private.h
archive_write_disk_set_standard_lookup.c
archive_write_private.h
@@ -71,22 +89,27 @@ SET(libarchive_SOURCES
archive_write_open_file.c
archive_write_open_filename.c
archive_write_open_memory.c
- archive_write_set_compression_bzip2.c
- archive_write_set_compression_compress.c
- archive_write_set_compression_gzip.c
- archive_write_set_compression_none.c
- archive_write_set_compression_program.c
- archive_write_set_compression_xz.c
+ archive_write_add_filter_bzip2.c
+ archive_write_add_filter_compress.c
+ archive_write_add_filter_gzip.c
+ archive_write_add_filter_none.c
+ archive_write_add_filter_program.c
+ archive_write_add_filter_xz.c
archive_write_set_format.c
+ archive_write_set_format_7zip.c
archive_write_set_format_ar.c
archive_write_set_format_by_name.c
archive_write_set_format_cpio.c
archive_write_set_format_cpio_newc.c
+ archive_write_set_format_gnutar.c
+ archive_write_set_format_iso9660.c
archive_write_set_format_mtree.c
archive_write_set_format_pax.c
archive_write_set_format_shar.c
archive_write_set_format_ustar.c
+ archive_write_set_format_xar.c
archive_write_set_format_zip.c
+ archive_write_set_options.c
filter_fork.c
filter_fork.h
)
@@ -94,11 +117,19 @@ SET(libarchive_SOURCES
# Man pages
SET(libarchive_MANS
archive_entry.3
+ archive_entry_acl.3
+ archive_entry_linkify.3
+ archive_entry_paths.3
+ archive_entry_perms.3
+ archive_entry_stat.3
+ archive_entry_time.3
archive_read.3
archive_read_disk.3
+ archive_read_set_options.3
archive_util.3
archive_write.3
archive_write_disk.3
+ archive_write_set_options.3
cpio.5
libarchive.3
libarchive_internals.3
@@ -109,8 +140,10 @@ SET(libarchive_MANS
IF(WIN32 AND NOT CYGWIN)
LIST(APPEND libarchive_SOURCES archive_entry_copy_bhfi.c)
+ LIST(APPEND libarchive_SOURCES archive_read_disk_windows.c)
LIST(APPEND libarchive_SOURCES archive_windows.c)
LIST(APPEND libarchive_SOURCES archive_windows.h)
+ LIST(APPEND libarchive_SOURCES archive_write_disk_windows.c)
LIST(APPEND libarchive_SOURCES filter_fork_windows.c)
ENDIF(WIN32 AND NOT CYGWIN)
diff --git a/libarchive/archive.h b/libarchive/archive.h
index f4a4ea11e171..47191e7ebb2d 100644
--- a/libarchive/archive.h
+++ b/libarchive/archive.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2003-2010 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -28,6 +28,10 @@
#ifndef ARCHIVE_H_INCLUDED
#define ARCHIVE_H_INCLUDED
+#include <sys/stat.h>
+#include <stddef.h> /* for wchar_t */
+#include <stdio.h> /* For FILE * */
+
/*
* Note: archive.h is for use outside of libarchive; the configuration
* headers (config.h, archive_platform.h, etc.) are purely internal.
@@ -36,22 +40,15 @@
* platform macros.
*/
#if defined(__BORLANDC__) && __BORLANDC__ >= 0x560
-# define __LA_STDINT_H <stdint.h>
-#elif !defined(__WATCOMC__) && !defined(_MSC_VER) && !defined(__INTERIX) && !defined(__BORLANDC__)
-# define __LA_STDINT_H <inttypes.h>
-#endif
-
-#include <sys/stat.h>
-#include <sys/types.h> /* Linux requires this for off_t */
-#ifdef __LA_STDINT_H
-# include __LA_STDINT_H /* int64_t, etc. */
+# include <stdint.h>
+#elif !defined(__WATCOMC__) && !defined(_MSC_VER) && !defined(__INTERIX) && !defined(__BORLANDC__) && !defined(_SCO_DS)
+# include <inttypes.h>
#endif
-#include <stdio.h> /* For FILE * */
/* Get appropriate definitions of standard POSIX-style types. */
/* These should match the types used in 'struct stat' */
#if defined(_WIN32) && !defined(__CYGWIN__)
-#define __LA_INT64_T __int64
+# define __LA_INT64_T __int64
# if defined(_SSIZE_T_DEFINED) || defined(_SSIZE_T_)
# define __LA_SSIZE_T ssize_t
# elif defined(_WIN64)
@@ -67,11 +64,15 @@
# define __LA_GID_T short
# endif
#else
-#include <unistd.h> /* ssize_t, uid_t, and gid_t */
-#define __LA_INT64_T int64_t
-#define __LA_SSIZE_T ssize_t
-#define __LA_UID_T uid_t
-#define __LA_GID_T gid_t
+# include <unistd.h> /* ssize_t, uid_t, and gid_t */
+# if defined(_SCO_DS)
+# define __LA_INT64_T long long
+# else
+# define __LA_INT64_T int64_t
+# endif
+# define __LA_SSIZE_T ssize_t
+# define __LA_UID_T uid_t
+# define __LA_GID_T gid_t
#endif
/*
@@ -88,7 +89,7 @@
# endif
# else
# ifdef __GNUC__
-# define __LA_DECL __attribute__((dllimport)) extern
+# define __LA_DECL
# else
# define __LA_DECL __declspec(dllimport)
# endif
@@ -98,7 +99,7 @@
# define __LA_DECL
#endif
-#if defined(__GNUC__) && __GNUC__ >= 3
+#if defined(__GNUC__) && __GNUC__ >= 3 && !defined(__MINGW32__)
#define __LA_PRINTF(fmtarg, firstvararg) \
__attribute__((__format__ (__printf__, fmtarg, firstvararg)))
#else
@@ -123,50 +124,18 @@ extern "C" {
* easy to compare versions at build time: for version a.b.c, the
* version number is printf("%d%03d%03d",a,b,c). For example, if you
* know your application requires version 2.12.108 or later, you can
- * assert that ARCHIVE_VERSION >= 2012108.
- *
- * This single-number format was introduced with libarchive 1.9.0 in
- * the libarchive 1.x family and libarchive 2.2.4 in the libarchive
- * 2.x family. The following may be useful if you really want to do
- * feature detection for earlier libarchive versions (which defined
- * ARCHIVE_API_VERSION and ARCHIVE_API_FEATURE instead):
- *
- * #ifndef ARCHIVE_VERSION_NUMBER
- * #define ARCHIVE_VERSION_NUMBER \
- * (ARCHIVE_API_VERSION * 1000000 + ARCHIVE_API_FEATURE * 1000)
- * #endif
+ * assert that ARCHIVE_VERSION_NUMBER >= 2012108.
*/
-#define ARCHIVE_VERSION_NUMBER 2008005
+/* Note: Compiler will complain if this does not match archive_entry.h! */
+#define ARCHIVE_VERSION_NUMBER 3000003
__LA_DECL int archive_version_number(void);
/*
* Textual name/version of the library, useful for version displays.
*/
-#define ARCHIVE_VERSION_STRING "libarchive 2.8.5"
+#define ARCHIVE_VERSION_STRING "libarchive 3.0.3"
__LA_DECL const char * archive_version_string(void);
-#if ARCHIVE_VERSION_NUMBER < 3000000
-/*
- * Deprecated; these are older names that will be removed in favor of
- * the simpler definitions above.
- */
-#define ARCHIVE_VERSION_STAMP ARCHIVE_VERSION_NUMBER
-__LA_DECL int archive_version_stamp(void);
-#define ARCHIVE_LIBRARY_VERSION ARCHIVE_VERSION_STRING
-__LA_DECL const char * archive_version(void);
-#define ARCHIVE_API_VERSION (ARCHIVE_VERSION_NUMBER / 1000000)
-__LA_DECL int archive_api_version(void);
-#define ARCHIVE_API_FEATURE ((ARCHIVE_VERSION_NUMBER / 1000) % 1000)
-__LA_DECL int archive_api_feature(void);
-#endif
-
-#if ARCHIVE_VERSION_NUMBER < 3000000
-/* This should never have been here in the first place. */
-/* Legacy of old tar assumptions, will be removed in libarchive 3.0. */
-#define ARCHIVE_BYTES_PER_RECORD 512
-#define ARCHIVE_DEFAULT_BYTES_PER_BLOCK 10240
-#endif
-
/* Declare our basic types. */
struct archive;
struct archive_entry;
@@ -210,48 +179,56 @@ struct archive_entry;
typedef __LA_SSIZE_T archive_read_callback(struct archive *,
void *_client_data, const void **_buffer);
-/* Skips at most request bytes from archive and returns the skipped amount */
-#if ARCHIVE_VERSION_NUMBER < 2000000
-/* Libarchive 1.0 used ssize_t for the return, which is only 32 bits
- * on most 32-bit platforms; not large enough. */
-typedef __LA_SSIZE_T archive_skip_callback(struct archive *,
- void *_client_data, size_t request);
-#elif ARCHIVE_VERSION_NUMBER < 3000000
-/* Libarchive 2.0 used off_t here, but that is a bad idea on Linux and a
- * few other platforms where off_t varies with build settings. */
-typedef off_t archive_skip_callback(struct archive *,
- void *_client_data, off_t request);
-#else
-/* Libarchive 3.0 uses int64_t here, which is actually guaranteed to be
- * 64 bits on every platform. */
+/* Skips at most request bytes from archive and returns the skipped amount.
+ * This may skip fewer bytes than requested; it may even skip zero bytes.
+ * If you do skip fewer bytes than requested, libarchive will invoke your
+ * read callback and discard data as necessary to make up the full skip.
+ */
typedef __LA_INT64_T archive_skip_callback(struct archive *,
void *_client_data, __LA_INT64_T request);
-#endif
+
+/* Seeks to specified location in the file and returns the position.
+ * Whence values are SEEK_SET, SEEK_CUR, SEEK_END from stdio.h.
+ * Return ARCHIVE_FATAL if the seek fails for any reason.
+ */
+typedef __LA_INT64_T archive_seek_callback(struct archive *,
+ void *_client_data, __LA_INT64_T offset, int whence);
/* Returns size actually written, zero on EOF, -1 on error. */
typedef __LA_SSIZE_T archive_write_callback(struct archive *,
void *_client_data,
const void *_buffer, size_t _length);
-#if ARCHIVE_VERSION_NUMBER < 3000000
-/* Open callback is actually never needed; remove it in libarchive 3.0. */
typedef int archive_open_callback(struct archive *, void *_client_data);
-#endif
typedef int archive_close_callback(struct archive *, void *_client_data);
/*
- * Codes for archive_compression.
+ * Codes to identify various stream filters.
*/
-#define ARCHIVE_COMPRESSION_NONE 0
-#define ARCHIVE_COMPRESSION_GZIP 1
-#define ARCHIVE_COMPRESSION_BZIP2 2
-#define ARCHIVE_COMPRESSION_COMPRESS 3
-#define ARCHIVE_COMPRESSION_PROGRAM 4
-#define ARCHIVE_COMPRESSION_LZMA 5
-#define ARCHIVE_COMPRESSION_XZ 6
-#define ARCHIVE_COMPRESSION_UU 7
-#define ARCHIVE_COMPRESSION_RPM 8
+#define ARCHIVE_FILTER_NONE 0
+#define ARCHIVE_FILTER_GZIP 1
+#define ARCHIVE_FILTER_BZIP2 2
+#define ARCHIVE_FILTER_COMPRESS 3
+#define ARCHIVE_FILTER_PROGRAM 4
+#define ARCHIVE_FILTER_LZMA 5
+#define ARCHIVE_FILTER_XZ 6
+#define ARCHIVE_FILTER_UU 7
+#define ARCHIVE_FILTER_RPM 8
+#define ARCHIVE_FILTER_LZIP 9
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+#define ARCHIVE_COMPRESSION_NONE ARCHIVE_FILTER_NONE
+#define ARCHIVE_COMPRESSION_GZIP ARCHIVE_FILTER_GZIP
+#define ARCHIVE_COMPRESSION_BZIP2 ARCHIVE_FILTER_BZIP2
+#define ARCHIVE_COMPRESSION_COMPRESS ARCHIVE_FILTER_COMPRESS
+#define ARCHIVE_COMPRESSION_PROGRAM ARCHIVE_FILTER_PROGRAM
+#define ARCHIVE_COMPRESSION_LZMA ARCHIVE_FILTER_LZMA
+#define ARCHIVE_COMPRESSION_XZ ARCHIVE_FILTER_XZ
+#define ARCHIVE_COMPRESSION_UU ARCHIVE_FILTER_UU
+#define ARCHIVE_COMPRESSION_RPM ARCHIVE_FILTER_RPM
+#define ARCHIVE_COMPRESSION_LZIP ARCHIVE_FILTER_LZIP
+#endif
/*
* Codes returned by archive_format.
@@ -265,7 +242,7 @@ typedef int archive_close_callback(struct archive *, void *_client_data);
* will change the format code to indicate the extended format that
* was used). In other cases, it's because different tools have
* modified the archive and so different parts of the archive
- * actually have slightly different formts. (Both tar and cpio store
+ * actually have slightly different formats. (Both tar and cpio store
* format codes in each entry, so it is quite possible for each
* entry to be in a different format.)
*/
@@ -276,6 +253,7 @@ typedef int archive_close_callback(struct archive *, void *_client_data);
#define ARCHIVE_FORMAT_CPIO_BIN_BE (ARCHIVE_FORMAT_CPIO | 3)
#define ARCHIVE_FORMAT_CPIO_SVR4_NOCRC (ARCHIVE_FORMAT_CPIO | 4)
#define ARCHIVE_FORMAT_CPIO_SVR4_CRC (ARCHIVE_FORMAT_CPIO | 5)
+#define ARCHIVE_FORMAT_CPIO_AFIO_LARGE (ARCHIVE_FORMAT_CPIO | 6)
#define ARCHIVE_FORMAT_SHAR 0x20000
#define ARCHIVE_FORMAT_SHAR_BASE (ARCHIVE_FORMAT_SHAR | 1)
#define ARCHIVE_FORMAT_SHAR_DUMP (ARCHIVE_FORMAT_SHAR | 2)
@@ -294,6 +272,10 @@ typedef int archive_close_callback(struct archive *, void *_client_data);
#define ARCHIVE_FORMAT_MTREE 0x80000
#define ARCHIVE_FORMAT_RAW 0x90000
#define ARCHIVE_FORMAT_XAR 0xA0000
+#define ARCHIVE_FORMAT_LHA 0xB0000
+#define ARCHIVE_FORMAT_CAB 0xC0000
+#define ARCHIVE_FORMAT_RAR 0xD0000
+#define ARCHIVE_FORMAT_7ZIP 0xE0000
/*-
* Basic outline for reading an archive:
@@ -316,40 +298,81 @@ __LA_DECL struct archive *archive_read_new(void);
* support_compression_bzip2(). The "all" functions provide the
* obvious shorthand.
*/
-__LA_DECL int archive_read_support_compression_all(struct archive *);
-__LA_DECL int archive_read_support_compression_bzip2(struct archive *);
-__LA_DECL int archive_read_support_compression_compress(struct archive *);
-__LA_DECL int archive_read_support_compression_gzip(struct archive *);
-__LA_DECL int archive_read_support_compression_lzma(struct archive *);
-__LA_DECL int archive_read_support_compression_none(struct archive *);
-__LA_DECL int archive_read_support_compression_program(struct archive *,
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+__LA_DECL int archive_read_support_compression_all(struct archive *);
+__LA_DECL int archive_read_support_compression_bzip2(struct archive *);
+__LA_DECL int archive_read_support_compression_compress(struct archive *);
+__LA_DECL int archive_read_support_compression_gzip(struct archive *);
+__LA_DECL int archive_read_support_compression_lzip(struct archive *);
+__LA_DECL int archive_read_support_compression_lzma(struct archive *);
+__LA_DECL int archive_read_support_compression_none(struct archive *);
+__LA_DECL int archive_read_support_compression_program(struct archive *,
+ const char *command);
+__LA_DECL int archive_read_support_compression_program_signature
+ (struct archive *, const char *,
+ const void * /* match */, size_t);
+
+__LA_DECL int archive_read_support_compression_rpm(struct archive *);
+__LA_DECL int archive_read_support_compression_uu(struct archive *);
+__LA_DECL int archive_read_support_compression_xz(struct archive *);
+#endif
+
+__LA_DECL int archive_read_support_filter_all(struct archive *);
+__LA_DECL int archive_read_support_filter_bzip2(struct archive *);
+__LA_DECL int archive_read_support_filter_compress(struct archive *);
+__LA_DECL int archive_read_support_filter_gzip(struct archive *);
+__LA_DECL int archive_read_support_filter_lzip(struct archive *);
+__LA_DECL int archive_read_support_filter_lzma(struct archive *);
+__LA_DECL int archive_read_support_filter_none(struct archive *);
+__LA_DECL int archive_read_support_filter_program(struct archive *,
const char *command);
-__LA_DECL int archive_read_support_compression_program_signature
- (struct archive *, const char *,
+__LA_DECL int archive_read_support_filter_program_signature
+ (struct archive *, const char *,
const void * /* match */, size_t);
-__LA_DECL int archive_read_support_compression_rpm(struct archive *);
-__LA_DECL int archive_read_support_compression_uu(struct archive *);
-__LA_DECL int archive_read_support_compression_xz(struct archive *);
-
-__LA_DECL int archive_read_support_format_all(struct archive *);
-__LA_DECL int archive_read_support_format_ar(struct archive *);
-__LA_DECL int archive_read_support_format_cpio(struct archive *);
-__LA_DECL int archive_read_support_format_empty(struct archive *);
-__LA_DECL int archive_read_support_format_gnutar(struct archive *);
-__LA_DECL int archive_read_support_format_iso9660(struct archive *);
-__LA_DECL int archive_read_support_format_mtree(struct archive *);
-__LA_DECL int archive_read_support_format_raw(struct archive *);
-__LA_DECL int archive_read_support_format_tar(struct archive *);
-__LA_DECL int archive_read_support_format_xar(struct archive *);
-__LA_DECL int archive_read_support_format_zip(struct archive *);
-
-
-/* Open the archive using callbacks for archive I/O. */
-__LA_DECL int archive_read_open(struct archive *, void *_client_data,
+__LA_DECL int archive_read_support_filter_rpm(struct archive *);
+__LA_DECL int archive_read_support_filter_uu(struct archive *);
+__LA_DECL int archive_read_support_filter_xz(struct archive *);
+
+__LA_DECL int archive_read_support_format_7zip(struct archive *);
+__LA_DECL int archive_read_support_format_all(struct archive *);
+__LA_DECL int archive_read_support_format_ar(struct archive *);
+__LA_DECL int archive_read_support_format_by_code(struct archive *, int);
+__LA_DECL int archive_read_support_format_cab(struct archive *);
+__LA_DECL int archive_read_support_format_cpio(struct archive *);
+__LA_DECL int archive_read_support_format_empty(struct archive *);
+__LA_DECL int archive_read_support_format_gnutar(struct archive *);
+__LA_DECL int archive_read_support_format_iso9660(struct archive *);
+__LA_DECL int archive_read_support_format_lha(struct archive *);
+__LA_DECL int archive_read_support_format_mtree(struct archive *);
+__LA_DECL int archive_read_support_format_rar(struct archive *);
+__LA_DECL int archive_read_support_format_raw(struct archive *);
+__LA_DECL int archive_read_support_format_tar(struct archive *);
+__LA_DECL int archive_read_support_format_xar(struct archive *);
+__LA_DECL int archive_read_support_format_zip(struct archive *);
+
+/* Set various callbacks. */
+__LA_DECL int archive_read_set_open_callback(struct archive *,
+ archive_open_callback *);
+__LA_DECL int archive_read_set_read_callback(struct archive *,
+ archive_read_callback *);
+__LA_DECL int archive_read_set_seek_callback(struct archive *,
+ archive_seek_callback *);
+__LA_DECL int archive_read_set_skip_callback(struct archive *,
+ archive_skip_callback *);
+__LA_DECL int archive_read_set_close_callback(struct archive *,
+ archive_close_callback *);
+/* The callback data is provided to all of the callbacks above. */
+__LA_DECL int archive_read_set_callback_data(struct archive *, void *);
+/* Opening freezes the callbacks. */
+__LA_DECL int archive_read_open1(struct archive *);
+
+/* Convenience wrappers around the above. */
+__LA_DECL int archive_read_open(struct archive *, void *_client_data,
archive_open_callback *, archive_read_callback *,
archive_close_callback *);
-__LA_DECL int archive_read_open2(struct archive *, void *_client_data,
+__LA_DECL int archive_read_open2(struct archive *, void *_client_data,
archive_open_callback *, archive_read_callback *,
archive_skip_callback *, archive_close_callback *);
@@ -359,30 +382,32 @@ __LA_DECL int archive_read_open2(struct archive *, void *_client_data,
* accept a block size handle tape blocking correctly.
*/
/* Use this if you know the filename. Note: NULL indicates stdin. */
-__LA_DECL int archive_read_open_filename(struct archive *,
+__LA_DECL int archive_read_open_filename(struct archive *,
const char *_filename, size_t _block_size);
+__LA_DECL int archive_read_open_filename_w(struct archive *,
+ const wchar_t *_filename, size_t _block_size);
/* archive_read_open_file() is a deprecated synonym for ..._open_filename(). */
-__LA_DECL int archive_read_open_file(struct archive *,
+__LA_DECL int archive_read_open_file(struct archive *,
const char *_filename, size_t _block_size);
/* Read an archive that's stored in memory. */
-__LA_DECL int archive_read_open_memory(struct archive *,
+__LA_DECL int archive_read_open_memory(struct archive *,
void * buff, size_t size);
/* A more involved version that is only used for internal testing. */
-__LA_DECL int archive_read_open_memory2(struct archive *a, void *buff,
+__LA_DECL int archive_read_open_memory2(struct archive *a, void *buff,
size_t size, size_t read_size);
/* Read an archive that's already open, using the file descriptor. */
-__LA_DECL int archive_read_open_fd(struct archive *, int _fd,
+__LA_DECL int archive_read_open_fd(struct archive *, int _fd,
size_t _block_size);
/* Read an archive that's already open, using a FILE *. */
/* Note: DO NOT use this with tape drives. */
-__LA_DECL int archive_read_open_FILE(struct archive *, FILE *_file);
+__LA_DECL int archive_read_open_FILE(struct archive *, FILE *_file);
/* Parses and returns next entry header. */
-__LA_DECL int archive_read_next_header(struct archive *,
+__LA_DECL int archive_read_next_header(struct archive *,
struct archive_entry **);
/* Parses and returns next entry header using the archive_entry passed in */
-__LA_DECL int archive_read_next_header2(struct archive *,
+__LA_DECL int archive_read_next_header2(struct archive *,
struct archive_entry *);
/*
@@ -401,14 +426,8 @@ __LA_DECL __LA_SSIZE_T archive_read_data(struct archive *,
* the desired size of the block. The API does guarantee that offsets will
* be strictly increasing and that returned blocks will not overlap.
*/
-#if ARCHIVE_VERSION_NUMBER < 3000000
-__LA_DECL int archive_read_data_block(struct archive *a,
- const void **buff, size_t *size, off_t *offset);
-#else
-__LA_DECL int archive_read_data_block(struct archive *a,
- const void **buff, size_t *size,
- __LA_INT64_T *offset);
-#endif
+__LA_DECL int archive_read_data_block(struct archive *a,
+ const void **buff, size_t *size, __LA_INT64_T *offset);
/*-
* Some convenience functions that are built on archive_read_data:
@@ -416,23 +435,27 @@ __LA_DECL int archive_read_data_block(struct archive *a,
* 'into_buffer': writes data into memory buffer that you provide
* 'into_fd': writes data to specified filedes
*/
-__LA_DECL int archive_read_data_skip(struct archive *);
-__LA_DECL int archive_read_data_into_buffer(struct archive *,
- void *buffer, __LA_SSIZE_T len);
-__LA_DECL int archive_read_data_into_fd(struct archive *, int fd);
+__LA_DECL int archive_read_data_skip(struct archive *);
+__LA_DECL int archive_read_data_into_fd(struct archive *, int fd);
/*
* Set read options.
*/
-/* Apply option string to the format only. */
-__LA_DECL int archive_read_set_format_options(struct archive *_a,
- const char *s);
-/* Apply option string to the filter only. */
-__LA_DECL int archive_read_set_filter_options(struct archive *_a,
- const char *s);
+/* Apply option to the format only. */
+__LA_DECL int archive_read_set_format_option(struct archive *_a,
+ const char *m, const char *o,
+ const char *v);
+/* Apply option to the filter only. */
+__LA_DECL int archive_read_set_filter_option(struct archive *_a,
+ const char *m, const char *o,
+ const char *v);
+/* Apply option to both the format and the filter. */
+__LA_DECL int archive_read_set_option(struct archive *_a,
+ const char *m, const char *o,
+ const char *v);
/* Apply option string to both the format and the filter. */
-__LA_DECL int archive_read_set_options(struct archive *_a,
- const char *s);
+__LA_DECL int archive_read_set_options(struct archive *_a,
+ const char *opts);
/*-
* Convenience function to recreate the current entry (whose header
@@ -477,10 +500,13 @@ __LA_DECL int archive_read_set_options(struct archive *_a,
#define ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER (0x0800)
/* Detect blocks of 0 and write holes instead. */
#define ARCHIVE_EXTRACT_SPARSE (0x1000)
+/* Default: Do not restore Mac extended metadata. */
+/* This has no effect except on Mac OS. */
+#define ARCHIVE_EXTRACT_MAC_METADATA (0x2000)
-__LA_DECL int archive_read_extract(struct archive *, struct archive_entry *,
+__LA_DECL int archive_read_extract(struct archive *, struct archive_entry *,
int flags);
-__LA_DECL int archive_read_extract2(struct archive *, struct archive_entry *,
+__LA_DECL int archive_read_extract2(struct archive *, struct archive_entry *,
struct archive * /* dest */);
__LA_DECL void archive_read_extract_set_progress_callback(struct archive *,
void (*_progress_func)(void *), void *_user_data);
@@ -488,7 +514,7 @@ __LA_DECL void archive_read_extract_set_progress_callback(struct archive *,
/* Record the dev/ino of a file that will not be written. This is
* generally set to the dev/ino of the archive being read. */
__LA_DECL void archive_read_extract_set_skip_file(struct archive *,
- dev_t, ino_t);
+ __LA_INT64_T, __LA_INT64_T);
/* Close the file and release most resources. */
__LA_DECL int archive_read_close(struct archive *);
@@ -502,7 +528,7 @@ __LA_DECL int archive_read_finish(struct archive *);
/*-
* To create an archive:
- * 1) Ask archive_write_new for a archive writer object.
+ * 1) Ask archive_write_new for an archive writer object.
* 2) Set any global properties. In particular, you should set
* the compression and format to use.
* 3) Call archive_write_open to open the file (most people
@@ -516,85 +542,93 @@ __LA_DECL int archive_read_finish(struct archive *);
* 6) archive_write_free to cleanup the writer and release resources
*/
__LA_DECL struct archive *archive_write_new(void);
-__LA_DECL int archive_write_set_bytes_per_block(struct archive *,
+__LA_DECL int archive_write_set_bytes_per_block(struct archive *,
int bytes_per_block);
-__LA_DECL int archive_write_get_bytes_per_block(struct archive *);
+__LA_DECL int archive_write_get_bytes_per_block(struct archive *);
/* XXX This is badly misnamed; suggestions appreciated. XXX */
-__LA_DECL int archive_write_set_bytes_in_last_block(struct archive *,
+__LA_DECL int archive_write_set_bytes_in_last_block(struct archive *,
int bytes_in_last_block);
-__LA_DECL int archive_write_get_bytes_in_last_block(struct archive *);
+__LA_DECL int archive_write_get_bytes_in_last_block(struct archive *);
/* The dev/ino of a file that won't be archived. This is used
* to avoid recursively adding an archive to itself. */
-__LA_DECL int archive_write_set_skip_file(struct archive *, dev_t, ino_t);
-
-__LA_DECL int archive_write_set_compression_bzip2(struct archive *);
-__LA_DECL int archive_write_set_compression_compress(struct archive *);
-__LA_DECL int archive_write_set_compression_gzip(struct archive *);
-__LA_DECL int archive_write_set_compression_lzma(struct archive *);
-__LA_DECL int archive_write_set_compression_none(struct archive *);
-__LA_DECL int archive_write_set_compression_program(struct archive *,
+__LA_DECL int archive_write_set_skip_file(struct archive *,
+ __LA_INT64_T, __LA_INT64_T);
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+__LA_DECL int archive_write_set_compression_bzip2(struct archive *);
+__LA_DECL int archive_write_set_compression_compress(struct archive *);
+__LA_DECL int archive_write_set_compression_gzip(struct archive *);
+__LA_DECL int archive_write_set_compression_lzip(struct archive *);
+__LA_DECL int archive_write_set_compression_lzma(struct archive *);
+__LA_DECL int archive_write_set_compression_none(struct archive *);
+__LA_DECL int archive_write_set_compression_program(struct archive *,
+ const char *cmd);
+__LA_DECL int archive_write_set_compression_xz(struct archive *);
+#endif
+
+__LA_DECL int archive_write_add_filter_bzip2(struct archive *);
+__LA_DECL int archive_write_add_filter_compress(struct archive *);
+__LA_DECL int archive_write_add_filter_gzip(struct archive *);
+__LA_DECL int archive_write_add_filter_lzip(struct archive *);
+__LA_DECL int archive_write_add_filter_lzma(struct archive *);
+__LA_DECL int archive_write_add_filter_none(struct archive *);
+__LA_DECL int archive_write_add_filter_program(struct archive *,
const char *cmd);
-__LA_DECL int archive_write_set_compression_xz(struct archive *);
+__LA_DECL int archive_write_add_filter_xz(struct archive *);
+
+
/* A convenience function to set the format based on the code or name. */
-__LA_DECL int archive_write_set_format(struct archive *, int format_code);
-__LA_DECL int archive_write_set_format_by_name(struct archive *,
+__LA_DECL int archive_write_set_format(struct archive *, int format_code);
+__LA_DECL int archive_write_set_format_by_name(struct archive *,
const char *name);
/* To minimize link pollution, use one or more of the following. */
-__LA_DECL int archive_write_set_format_ar_bsd(struct archive *);
-__LA_DECL int archive_write_set_format_ar_svr4(struct archive *);
-__LA_DECL int archive_write_set_format_cpio(struct archive *);
-__LA_DECL int archive_write_set_format_cpio_newc(struct archive *);
-__LA_DECL int archive_write_set_format_mtree(struct archive *);
+__LA_DECL int archive_write_set_format_7zip(struct archive *);
+__LA_DECL int archive_write_set_format_ar_bsd(struct archive *);
+__LA_DECL int archive_write_set_format_ar_svr4(struct archive *);
+__LA_DECL int archive_write_set_format_cpio(struct archive *);
+__LA_DECL int archive_write_set_format_cpio_newc(struct archive *);
+__LA_DECL int archive_write_set_format_gnutar(struct archive *);
+__LA_DECL int archive_write_set_format_iso9660(struct archive *);
+__LA_DECL int archive_write_set_format_mtree(struct archive *);
/* TODO: int archive_write_set_format_old_tar(struct archive *); */
-__LA_DECL int archive_write_set_format_pax(struct archive *);
-__LA_DECL int archive_write_set_format_pax_restricted(struct archive *);
-__LA_DECL int archive_write_set_format_shar(struct archive *);
-__LA_DECL int archive_write_set_format_shar_dump(struct archive *);
-__LA_DECL int archive_write_set_format_ustar(struct archive *);
-__LA_DECL int archive_write_set_format_zip(struct archive *);
-__LA_DECL int archive_write_open(struct archive *, void *,
+__LA_DECL int archive_write_set_format_pax(struct archive *);
+__LA_DECL int archive_write_set_format_pax_restricted(struct archive *);
+__LA_DECL int archive_write_set_format_shar(struct archive *);
+__LA_DECL int archive_write_set_format_shar_dump(struct archive *);
+__LA_DECL int archive_write_set_format_ustar(struct archive *);
+__LA_DECL int archive_write_set_format_xar(struct archive *);
+__LA_DECL int archive_write_set_format_zip(struct archive *);
+__LA_DECL int archive_write_open(struct archive *, void *,
archive_open_callback *, archive_write_callback *,
archive_close_callback *);
-__LA_DECL int archive_write_open_fd(struct archive *, int _fd);
-__LA_DECL int archive_write_open_filename(struct archive *, const char *_file);
+__LA_DECL int archive_write_open_fd(struct archive *, int _fd);
+__LA_DECL int archive_write_open_filename(struct archive *, const char *_file);
+__LA_DECL int archive_write_open_filename_w(struct archive *,
+ const wchar_t *_file);
/* A deprecated synonym for archive_write_open_filename() */
-__LA_DECL int archive_write_open_file(struct archive *, const char *_file);
-__LA_DECL int archive_write_open_FILE(struct archive *, FILE *);
+__LA_DECL int archive_write_open_file(struct archive *, const char *_file);
+__LA_DECL int archive_write_open_FILE(struct archive *, FILE *);
/* _buffSize is the size of the buffer, _used refers to a variable that
* will be updated after each write into the buffer. */
-__LA_DECL int archive_write_open_memory(struct archive *,
+__LA_DECL int archive_write_open_memory(struct archive *,
void *_buffer, size_t _buffSize, size_t *_used);
/*
* Note that the library will truncate writes beyond the size provided
* to archive_write_header or pad if the provided data is short.
*/
-__LA_DECL int archive_write_header(struct archive *,
+__LA_DECL int archive_write_header(struct archive *,
struct archive_entry *);
-#if ARCHIVE_VERSION_NUMBER < 2000000
-/* This was erroneously declared to return "int" in libarchive 1.x. */
-__LA_DECL int archive_write_data(struct archive *,
- const void *, size_t);
-#else
-/* Libarchive 2.0 and later return ssize_t here. */
-__LA_DECL __LA_SSIZE_T archive_write_data(struct archive *,
+__LA_DECL __LA_SSIZE_T archive_write_data(struct archive *,
const void *, size_t);
-#endif
-#if ARCHIVE_VERSION_NUMBER < 3000000
-/* Libarchive 1.x and 2.x use off_t for the argument, but that's not
- * stable on Linux. */
-__LA_DECL __LA_SSIZE_T archive_write_data_block(struct archive *,
- const void *, size_t, off_t);
-#else
-/* Libarchive 3.0 uses explicit int64_t to ensure consistent 64-bit support. */
+/* This interface is currently only available for archive_write_disk handles. */
__LA_DECL __LA_SSIZE_T archive_write_data_block(struct archive *,
const void *, size_t, __LA_INT64_T);
-#endif
+
__LA_DECL int archive_write_finish_entry(struct archive *);
__LA_DECL int archive_write_close(struct archive *);
-
/* This can fail if the archive wasn't already closed, in which case
* archive_write_free() will implicitly call archive_write_close(). */
__LA_DECL int archive_write_free(struct archive *);
@@ -606,16 +640,21 @@ __LA_DECL int archive_write_finish(struct archive *);
/*
* Set write options.
*/
-/* Apply option string to the format only. */
-__LA_DECL int archive_write_set_format_options(struct archive *_a,
- const char *s);
-/* Apply option string to the compressor only. */
-__LA_DECL int archive_write_set_compressor_options(struct archive *_a,
- const char *s);
-/* Apply option string to both the format and the compressor. */
-__LA_DECL int archive_write_set_options(struct archive *_a,
- const char *s);
-
+/* Apply option to the format only. */
+__LA_DECL int archive_write_set_format_option(struct archive *_a,
+ const char *m, const char *o,
+ const char *v);
+/* Apply option to the filter only. */
+__LA_DECL int archive_write_set_filter_option(struct archive *_a,
+ const char *m, const char *o,
+ const char *v);
+/* Apply option to both the format and the filter. */
+__LA_DECL int archive_write_set_option(struct archive *_a,
+ const char *m, const char *o,
+ const char *v);
+/* Apply option string to both the format and the filter. */
+__LA_DECL int archive_write_set_options(struct archive *_a,
+ const char *opts);
/*-
* ARCHIVE_WRITE_DISK API
@@ -635,8 +674,8 @@ __LA_DECL int archive_write_set_options(struct archive *_a,
*/
__LA_DECL struct archive *archive_write_disk_new(void);
/* This file will not be overwritten. */
-__LA_DECL int archive_write_disk_set_skip_file(struct archive *,
- dev_t, ino_t);
+__LA_DECL int archive_write_disk_set_skip_file(struct archive *,
+ __LA_INT64_T, __LA_INT64_T);
/* Set flags to control how the next item gets created.
* This accepts a bitmask of ARCHIVE_EXTRACT_XXX flags defined above. */
__LA_DECL int archive_write_disk_set_options(struct archive *,
@@ -664,14 +703,16 @@ __LA_DECL int archive_write_disk_set_standard_lookup(struct archive *);
* your needs, you can write your own and register them. Be sure to
* include a cleanup function if you have allocated private data.
*/
-__LA_DECL int archive_write_disk_set_group_lookup(struct archive *,
- void * /* private_data */,
- __LA_GID_T (*)(void *, const char *, __LA_GID_T),
- void (* /* cleanup */)(void *));
-__LA_DECL int archive_write_disk_set_user_lookup(struct archive *,
- void * /* private_data */,
- __LA_UID_T (*)(void *, const char *, __LA_UID_T),
- void (* /* cleanup */)(void *));
+__LA_DECL int archive_write_disk_set_group_lookup(struct archive *,
+ void * /* private_data */,
+ __LA_INT64_T (*)(void *, const char *, __LA_INT64_T),
+ void (* /* cleanup */)(void *));
+__LA_DECL int archive_write_disk_set_user_lookup(struct archive *,
+ void * /* private_data */,
+ __LA_INT64_T (*)(void *, const char *, __LA_INT64_T),
+ void (* /* cleanup */)(void *));
+__LA_DECL __LA_INT64_T archive_write_disk_gid(struct archive *, const char *, __LA_INT64_T);
+__LA_DECL __LA_INT64_T archive_write_disk_uid(struct archive *, const char *, __LA_INT64_T);
/*
* ARCHIVE_READ_DISK API
@@ -692,32 +733,64 @@ __LA_DECL int archive_read_disk_entry_from_file(struct archive *,
struct archive_entry *, int /* fd */, const struct stat *);
/* Look up gname for gid or uname for uid. */
/* Default implementations are very, very stupid. */
-__LA_DECL const char *archive_read_disk_gname(struct archive *, __LA_GID_T);
-__LA_DECL const char *archive_read_disk_uname(struct archive *, __LA_UID_T);
+__LA_DECL const char *archive_read_disk_gname(struct archive *, __LA_INT64_T);
+__LA_DECL const char *archive_read_disk_uname(struct archive *, __LA_INT64_T);
/* "Standard" implementation uses getpwuid_r, getgrgid_r and caches the
* results for performance. */
__LA_DECL int archive_read_disk_set_standard_lookup(struct archive *);
/* You can install your own lookups if you like. */
__LA_DECL int archive_read_disk_set_gname_lookup(struct archive *,
void * /* private_data */,
- const char *(* /* lookup_fn */)(void *, __LA_GID_T),
+ const char *(* /* lookup_fn */)(void *, __LA_INT64_T),
void (* /* cleanup_fn */)(void *));
__LA_DECL int archive_read_disk_set_uname_lookup(struct archive *,
void * /* private_data */,
- const char *(* /* lookup_fn */)(void *, __LA_UID_T),
+ const char *(* /* lookup_fn */)(void *, __LA_INT64_T),
void (* /* cleanup_fn */)(void *));
+/* Start traversal. */
+__LA_DECL int archive_read_disk_open(struct archive *, const char *);
+__LA_DECL int archive_read_disk_open_w(struct archive *, const wchar_t *);
+/*
+ * Request that current entry be visited. If you invoke it on every
+ * directory, you'll get a physical traversal. This is ignored if the
+ * current entry isn't a directory or a link to a directory. So, if
+ * you invoke this on every returned path, you'll get a full logical
+ * traversal.
+ */
+__LA_DECL int archive_read_disk_descend(struct archive *);
+__LA_DECL int archive_read_disk_current_filesystem(struct archive *);
+__LA_DECL int archive_read_disk_current_filesystem_is_synthetic(struct archive *);
+__LA_DECL int archive_read_disk_current_filesystem_is_remote(struct archive *);
+/* Request that the access time of the entry visited by travesal be restored. */
+__LA_DECL int archive_read_disk_set_atime_restored(struct archive *);
/*
* Accessor functions to read/set various information in
* the struct archive object:
*/
-/* Bytes written after compression or read before decompression. */
+
+/* Number of filters in the current filter pipeline. */
+/* Filter #0 is the one closest to the format, -1 is a synonym for the
+ * last filter, which is always the pseudo-filter that wraps the
+ * client callbacks. */
+__LA_DECL int archive_filter_count(struct archive *);
+__LA_DECL __LA_INT64_T archive_filter_bytes(struct archive *, int);
+__LA_DECL int archive_filter_code(struct archive *, int);
+__LA_DECL const char * archive_filter_name(struct archive *, int);
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+/* These don't properly handle multiple filters, so are deprecated and
+ * will eventually be removed. */
+/* As of libarchive 3.0, this is an alias for archive_filter_bytes(a, -1); */
__LA_DECL __LA_INT64_T archive_position_compressed(struct archive *);
-/* Bytes written to compressor or read from decompressor. */
+/* As of libarchive 3.0, this is an alias for archive_filter_bytes(a, 0); */
__LA_DECL __LA_INT64_T archive_position_uncompressed(struct archive *);
-
+/* As of libarchive 3.0, this is an alias for archive_filter_name(a, 0); */
__LA_DECL const char *archive_compression_name(struct archive *);
+/* As of libarchive 3.0, this is an alias for archive_filter_code(a, 0); */
__LA_DECL int archive_compression(struct archive *);
+#endif
+
__LA_DECL int archive_errno(struct archive *);
__LA_DECL const char *archive_error_string(struct archive *);
__LA_DECL const char *archive_format_name(struct archive *);
diff --git a/libarchive/archive_acl.c b/libarchive/archive_acl.c
new file mode 100644
index 000000000000..4747a4c5a11f
--- /dev/null
+++ b/libarchive/archive_acl.c
@@ -0,0 +1,1264 @@
+/*-
+ * Copyright (c) 2003-2010 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+__FBSDID("$FreeBSD$");
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifdef HAVE_WCHAR_H
+#include <wchar.h>
+#endif
+
+#include "archive_acl_private.h"
+#include "archive_entry.h"
+#include "archive_private.h"
+
+#undef max
+#define max(a, b) ((a)>(b)?(a):(b))
+
+#ifndef HAVE_WMEMCMP
+/* Good enough for simple equality testing, but not for sorting. */
+#define wmemcmp(a,b,i) memcmp((a), (b), (i) * sizeof(wchar_t))
+#endif
+
+static int acl_special(struct archive_acl *acl,
+ int type, int permset, int tag);
+static struct archive_acl_entry *acl_new_entry(struct archive_acl *acl,
+ int type, int permset, int tag, int id);
+static int isint_w(const wchar_t *start, const wchar_t *end, int *result);
+static int ismode_w(const wchar_t *start, const wchar_t *end, int *result);
+static void next_field_w(const wchar_t **wp, const wchar_t **start,
+ const wchar_t **end, wchar_t *sep);
+static int prefix_w(const wchar_t *start, const wchar_t *end,
+ const wchar_t *test);
+static void append_entry_w(wchar_t **wp, const wchar_t *prefix, int tag,
+ const wchar_t *wname, int perm, int id);
+static void append_id_w(wchar_t **wp, int id);
+static int isint(const char *start, const char *end, int *result);
+static int ismode(const char *start, const char *end, int *result);
+static void next_field(const char **p, const char **start,
+ const char **end, char *sep);
+static int prefix(const char *start, const char *end,
+ const char *test);
+static void append_entry(char **p, const char *prefix, int tag,
+ const char *name, int perm, int id);
+static void append_id(char **p, int id);
+
+void
+archive_acl_clear(struct archive_acl *acl)
+{
+ struct archive_acl_entry *ap;
+
+ while (acl->acl_head != NULL) {
+ ap = acl->acl_head->next;
+ archive_mstring_clean(&acl->acl_head->name);
+ free(acl->acl_head);
+ acl->acl_head = ap;
+ }
+ if (acl->acl_text_w != NULL) {
+ free(acl->acl_text_w);
+ acl->acl_text_w = NULL;
+ }
+ if (acl->acl_text != NULL) {
+ free(acl->acl_text);
+ acl->acl_text = NULL;
+ }
+ acl->acl_p = NULL;
+ acl->acl_state = 0; /* Not counting. */
+}
+
+void
+archive_acl_copy(struct archive_acl *dest, struct archive_acl *src)
+{
+ struct archive_acl_entry *ap, *ap2;
+
+ archive_acl_clear(dest);
+
+ dest->mode = src->mode;
+ ap = src->acl_head;
+ while (ap != NULL) {
+ ap2 = acl_new_entry(dest,
+ ap->type, ap->permset, ap->tag, ap->id);
+ if (ap2 != NULL)
+ archive_mstring_copy(&ap2->name, &ap->name);
+ ap = ap->next;
+ }
+}
+
+int
+archive_acl_add_entry(struct archive_acl *acl,
+ int type, int permset, int tag, int id, const char *name)
+{
+ struct archive_acl_entry *ap;
+
+ if (acl_special(acl, type, permset, tag) == 0)
+ return ARCHIVE_OK;
+ ap = acl_new_entry(acl, type, permset, tag, id);
+ if (ap == NULL) {
+ /* XXX Error XXX */
+ return ARCHIVE_FAILED;
+ }
+ if (name != NULL && *name != '\0')
+ archive_mstring_copy_mbs(&ap->name, name);
+ else
+ archive_mstring_clean(&ap->name);
+ return ARCHIVE_OK;
+}
+
+int
+archive_acl_add_entry_w_len(struct archive_acl *acl,
+ int type, int permset, int tag, int id, const wchar_t *name, size_t len)
+{
+ struct archive_acl_entry *ap;
+
+ if (acl_special(acl, type, permset, tag) == 0)
+ return ARCHIVE_OK;
+ ap = acl_new_entry(acl, type, permset, tag, id);
+ if (ap == NULL) {
+ /* XXX Error XXX */
+ return ARCHIVE_FAILED;
+ }
+ if (name != NULL && *name != L'\0' && len > 0)
+ archive_mstring_copy_wcs_len(&ap->name, name, len);
+ else
+ archive_mstring_clean(&ap->name);
+ return ARCHIVE_OK;
+}
+
+int
+archive_acl_add_entry_len_l(struct archive_acl *acl,
+ int type, int permset, int tag, int id, const char *name, size_t len,
+ struct archive_string_conv *sc)
+{
+ struct archive_acl_entry *ap;
+ int r;
+
+ if (acl_special(acl, type, permset, tag) == 0)
+ return ARCHIVE_OK;
+ ap = acl_new_entry(acl, type, permset, tag, id);
+ if (ap == NULL) {
+ /* XXX Error XXX */
+ return ARCHIVE_FAILED;
+ }
+ if (name != NULL && *name != '\0' && len > 0) {
+ r = archive_mstring_copy_mbs_len_l(&ap->name, name, len, sc);
+ } else {
+ r = 0;
+ archive_mstring_clean(&ap->name);
+ }
+ if (r == 0)
+ return (ARCHIVE_OK);
+ else if (errno == ENOMEM)
+ return (ARCHIVE_FATAL);
+ else
+ return (ARCHIVE_WARN);
+}
+
+/*
+ * If this ACL entry is part of the standard POSIX permissions set,
+ * store the permissions in the stat structure and return zero.
+ */
+static int
+acl_special(struct archive_acl *acl, int type, int permset, int tag)
+{
+ if (type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS
+ && ((permset & ~007) == 0)) {
+ switch (tag) {
+ case ARCHIVE_ENTRY_ACL_USER_OBJ:
+ acl->mode &= ~0700;
+ acl->mode |= (permset & 7) << 6;
+ return (0);
+ case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
+ acl->mode &= ~0070;
+ acl->mode |= (permset & 7) << 3;
+ return (0);
+ case ARCHIVE_ENTRY_ACL_OTHER:
+ acl->mode &= ~0007;
+ acl->mode |= permset & 7;
+ return (0);
+ }
+ }
+ return (1);
+}
+
+/*
+ * Allocate and populate a new ACL entry with everything but the
+ * name.
+ */
+static struct archive_acl_entry *
+acl_new_entry(struct archive_acl *acl,
+ int type, int permset, int tag, int id)
+{
+ struct archive_acl_entry *ap, *aq;
+
+ /* Type argument must be a valid NFS4 or POSIX.1e type.
+ * The type must agree with anything already set and
+ * the permset must be compatible. */
+ if (type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
+ if (acl->acl_types & ~ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
+ return (NULL);
+ }
+ if (permset &
+ ~(ARCHIVE_ENTRY_ACL_PERMS_NFS4
+ | ARCHIVE_ENTRY_ACL_INHERITANCE_NFS4)) {
+ return (NULL);
+ }
+ } else if (type & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) {
+ if (acl->acl_types & ~ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) {
+ return (NULL);
+ }
+ if (permset & ~ARCHIVE_ENTRY_ACL_PERMS_POSIX1E) {
+ return (NULL);
+ }
+ } else {
+ return (NULL);
+ }
+
+ /* Verify the tag is valid and compatible with NFS4 or POSIX.1e. */
+ switch (tag) {
+ case ARCHIVE_ENTRY_ACL_USER:
+ case ARCHIVE_ENTRY_ACL_USER_OBJ:
+ case ARCHIVE_ENTRY_ACL_GROUP:
+ case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
+ /* Tags valid in both NFS4 and POSIX.1e */
+ break;
+ case ARCHIVE_ENTRY_ACL_MASK:
+ case ARCHIVE_ENTRY_ACL_OTHER:
+ /* Tags valid only in POSIX.1e. */
+ if (type & ~ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) {
+ return (NULL);
+ }
+ break;
+ case ARCHIVE_ENTRY_ACL_EVERYONE:
+ /* Tags valid only in NFS4. */
+ if (type & ~ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
+ return (NULL);
+ }
+ break;
+ default:
+ /* No other values are valid. */
+ return (NULL);
+ }
+
+ if (acl->acl_text_w != NULL) {
+ free(acl->acl_text_w);
+ acl->acl_text_w = NULL;
+ }
+ if (acl->acl_text != NULL) {
+ free(acl->acl_text);
+ acl->acl_text = NULL;
+ }
+
+ /* If there's a matching entry already in the list, overwrite it. */
+ ap = acl->acl_head;
+ aq = NULL;
+ while (ap != NULL) {
+ if (ap->type == type && ap->tag == tag && ap->id == id) {
+ ap->permset = permset;
+ return (ap);
+ }
+ aq = ap;
+ ap = ap->next;
+ }
+
+ /* Add a new entry to the end of the list. */
+ ap = (struct archive_acl_entry *)malloc(sizeof(*ap));
+ if (ap == NULL)
+ return (NULL);
+ memset(ap, 0, sizeof(*ap));
+ if (aq == NULL)
+ acl->acl_head = ap;
+ else
+ aq->next = ap;
+ ap->type = type;
+ ap->tag = tag;
+ ap->id = id;
+ ap->permset = permset;
+ acl->acl_types |= type;
+ return (ap);
+}
+
+/*
+ * Return a count of entries matching "want_type".
+ */
+int
+archive_acl_count(struct archive_acl *acl, int want_type)
+{
+ int count;
+ struct archive_acl_entry *ap;
+
+ count = 0;
+ ap = acl->acl_head;
+ while (ap != NULL) {
+ if ((ap->type & want_type) != 0)
+ count++;
+ ap = ap->next;
+ }
+
+ if (count > 0 && ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0))
+ count += 3;
+ return (count);
+}
+
+/*
+ * Prepare for reading entries from the ACL data. Returns a count
+ * of entries matching "want_type", or zero if there are no
+ * non-extended ACL entries of that type.
+ */
+int
+archive_acl_reset(struct archive_acl *acl, int want_type)
+{
+ int count, cutoff;
+
+ count = archive_acl_count(acl, want_type);
+
+ /*
+ * If the only entries are the three standard ones,
+ * then don't return any ACL data. (In this case,
+ * client can just use chmod(2) to set permissions.)
+ */
+ if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0)
+ cutoff = 3;
+ else
+ cutoff = 0;
+
+ if (count > cutoff)
+ acl->acl_state = ARCHIVE_ENTRY_ACL_USER_OBJ;
+ else
+ acl->acl_state = 0;
+ acl->acl_p = acl->acl_head;
+ return (count);
+}
+
+
+/*
+ * Return the next ACL entry in the list. Fake entries for the
+ * standard permissions and include them in the returned list.
+ */
+int
+archive_acl_next(struct archive *a, struct archive_acl *acl, int want_type, int *type,
+ int *permset, int *tag, int *id, const char **name)
+{
+ *name = NULL;
+ *id = -1;
+
+ /*
+ * The acl_state is either zero (no entries available), -1
+ * (reading from list), or an entry type (retrieve that type
+ * from ae_stat.aest_mode).
+ */
+ if (acl->acl_state == 0)
+ return (ARCHIVE_WARN);
+
+ /* The first three access entries are special. */
+ if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
+ switch (acl->acl_state) {
+ case ARCHIVE_ENTRY_ACL_USER_OBJ:
+ *permset = (acl->mode >> 6) & 7;
+ *type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
+ *tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
+ acl->acl_state = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
+ return (ARCHIVE_OK);
+ case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
+ *permset = (acl->mode >> 3) & 7;
+ *type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
+ *tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
+ acl->acl_state = ARCHIVE_ENTRY_ACL_OTHER;
+ return (ARCHIVE_OK);
+ case ARCHIVE_ENTRY_ACL_OTHER:
+ *permset = acl->mode & 7;
+ *type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
+ *tag = ARCHIVE_ENTRY_ACL_OTHER;
+ acl->acl_state = -1;
+ acl->acl_p = acl->acl_head;
+ return (ARCHIVE_OK);
+ default:
+ break;
+ }
+ }
+
+ while (acl->acl_p != NULL && (acl->acl_p->type & want_type) == 0)
+ acl->acl_p = acl->acl_p->next;
+ if (acl->acl_p == NULL) {
+ acl->acl_state = 0;
+ *type = 0;
+ *permset = 0;
+ *tag = 0;
+ *id = -1;
+ *name = NULL;
+ return (ARCHIVE_EOF); /* End of ACL entries. */
+ }
+ *type = acl->acl_p->type;
+ *permset = acl->acl_p->permset;
+ *tag = acl->acl_p->tag;
+ *id = acl->acl_p->id;
+ if (archive_mstring_get_mbs(a, &acl->acl_p->name, name) != 0)
+ *name = NULL;
+ acl->acl_p = acl->acl_p->next;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Generate a text version of the ACL. The flags parameter controls
+ * the style of the generated ACL.
+ */
+const wchar_t *
+archive_acl_text_w(struct archive *a, struct archive_acl *acl, int flags)
+{
+ int count;
+ size_t length;
+ const wchar_t *wname;
+ const wchar_t *prefix;
+ wchar_t separator;
+ struct archive_acl_entry *ap;
+ int id;
+ wchar_t *wp;
+
+ if (acl->acl_text_w != NULL) {
+ free (acl->acl_text_w);
+ acl->acl_text_w = NULL;
+ }
+
+ separator = L',';
+ count = 0;
+ length = 0;
+ ap = acl->acl_head;
+ while (ap != NULL) {
+ if ((ap->type & flags) != 0) {
+ count++;
+ if ((flags & ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT) &&
+ (ap->type & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT))
+ length += 8; /* "default:" */
+ length += 5; /* tag name */
+ length += 1; /* colon */
+ if (archive_mstring_get_wcs(a, &ap->name, &wname) == 0 &&
+ wname != NULL)
+ length += wcslen(wname);
+ else
+ length += sizeof(uid_t) * 3 + 1;
+ length ++; /* colon */
+ length += 3; /* rwx */
+ length += 1; /* colon */
+ length += max(sizeof(uid_t), sizeof(gid_t)) * 3 + 1;
+ length ++; /* newline */
+ }
+ ap = ap->next;
+ }
+
+ if (count > 0 && ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0)) {
+ length += 10; /* "user::rwx\n" */
+ length += 11; /* "group::rwx\n" */
+ length += 11; /* "other::rwx\n" */
+ }
+
+ if (count == 0)
+ return (NULL);
+
+ /* Now, allocate the string and actually populate it. */
+ wp = acl->acl_text_w = (wchar_t *)malloc(length * sizeof(wchar_t));
+ if (wp == NULL)
+ __archive_errx(1, "No memory to generate the text version of the ACL");
+ count = 0;
+ if ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
+ append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_USER_OBJ, NULL,
+ acl->mode & 0700, -1);
+ *wp++ = ',';
+ append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_GROUP_OBJ, NULL,
+ acl->mode & 0070, -1);
+ *wp++ = ',';
+ append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_OTHER, NULL,
+ acl->mode & 0007, -1);
+ count += 3;
+
+ ap = acl->acl_head;
+ while (ap != NULL) {
+ if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0 &&
+ archive_mstring_get_wcs(a, &ap->name, &wname) == 0) {
+ *wp++ = separator;
+ if (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID)
+ id = ap->id;
+ else
+ id = -1;
+ append_entry_w(&wp, NULL, ap->tag, wname,
+ ap->permset, id);
+ count++;
+ }
+ ap = ap->next;
+ }
+ }
+
+
+ if ((flags & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0) {
+ if (flags & ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT)
+ prefix = L"default:";
+ else
+ prefix = NULL;
+ ap = acl->acl_head;
+ count = 0;
+ while (ap != NULL) {
+ if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0 &&
+ archive_mstring_get_wcs(a, &ap->name, &wname) == 0) {
+ if (count > 0)
+ *wp++ = separator;
+ if (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID)
+ id = ap->id;
+ else
+ id = -1;
+ append_entry_w(&wp, prefix, ap->tag,
+ wname, ap->permset, id);
+ count ++;
+ }
+ ap = ap->next;
+ }
+ }
+
+ return (acl->acl_text_w);
+}
+
+
+static void
+append_id_w(wchar_t **wp, int id)
+{
+ if (id < 0)
+ id = 0;
+ if (id > 9)
+ append_id_w(wp, id / 10);
+ *(*wp)++ = L"0123456789"[id % 10];
+}
+
+static void
+append_entry_w(wchar_t **wp, const wchar_t *prefix, int tag,
+ const wchar_t *wname, int perm, int id)
+{
+ if (prefix != NULL) {
+ wcscpy(*wp, prefix);
+ *wp += wcslen(*wp);
+ }
+ switch (tag) {
+ case ARCHIVE_ENTRY_ACL_USER_OBJ:
+ wname = NULL;
+ id = -1;
+ /* FALLTHROUGH */
+ case ARCHIVE_ENTRY_ACL_USER:
+ wcscpy(*wp, L"user");
+ break;
+ case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
+ wname = NULL;
+ id = -1;
+ /* FALLTHROUGH */
+ case ARCHIVE_ENTRY_ACL_GROUP:
+ wcscpy(*wp, L"group");
+ break;
+ case ARCHIVE_ENTRY_ACL_MASK:
+ wcscpy(*wp, L"mask");
+ wname = NULL;
+ id = -1;
+ break;
+ case ARCHIVE_ENTRY_ACL_OTHER:
+ wcscpy(*wp, L"other");
+ wname = NULL;
+ id = -1;
+ break;
+ }
+ *wp += wcslen(*wp);
+ *(*wp)++ = L':';
+ if (wname != NULL) {
+ wcscpy(*wp, wname);
+ *wp += wcslen(*wp);
+ } else if (tag == ARCHIVE_ENTRY_ACL_USER
+ || tag == ARCHIVE_ENTRY_ACL_GROUP) {
+ append_id_w(wp, id);
+ id = -1;
+ }
+ *(*wp)++ = L':';
+ *(*wp)++ = (perm & 0444) ? L'r' : L'-';
+ *(*wp)++ = (perm & 0222) ? L'w' : L'-';
+ *(*wp)++ = (perm & 0111) ? L'x' : L'-';
+ if (id != -1) {
+ *(*wp)++ = L':';
+ append_id_w(wp, id);
+ }
+ **wp = L'\0';
+}
+
+int
+archive_acl_text_l(struct archive_acl *acl, int flags,
+ const char **acl_text, size_t *acl_text_len,
+ struct archive_string_conv *sc)
+{
+ int count;
+ size_t length;
+ const char *name;
+ const char *prefix;
+ char separator;
+ struct archive_acl_entry *ap;
+ size_t len;
+ int id, r;
+ char *p;
+
+ if (acl->acl_text != NULL) {
+ free (acl->acl_text);
+ acl->acl_text = NULL;
+ }
+
+ *acl_text = NULL;
+ if (acl_text_len != NULL)
+ *acl_text_len = 0;
+ separator = ',';
+ count = 0;
+ length = 0;
+ ap = acl->acl_head;
+ while (ap != NULL) {
+ if ((ap->type & flags) != 0) {
+ count++;
+ if ((flags & ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT) &&
+ (ap->type & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT))
+ length += 8; /* "default:" */
+ length += 5; /* tag name */
+ length += 1; /* colon */
+ r = archive_mstring_get_mbs_l(
+ &ap->name, &name, &len, sc);
+ if (r != 0)
+ return (-1);
+ if (len > 0 && name != NULL)
+ length += len;
+ else
+ length += sizeof(uid_t) * 3 + 1;
+ length ++; /* colon */
+ length += 3; /* rwx */
+ length += 1; /* colon */
+ length += max(sizeof(uid_t), sizeof(gid_t)) * 3 + 1;
+ length ++; /* newline */
+ }
+ ap = ap->next;
+ }
+
+ if (count > 0 && ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0)) {
+ length += 10; /* "user::rwx\n" */
+ length += 11; /* "group::rwx\n" */
+ length += 11; /* "other::rwx\n" */
+ }
+
+ if (count == 0)
+ return (0);
+
+ /* Now, allocate the string and actually populate it. */
+ p = acl->acl_text = (char *)malloc(length);
+ if (p == NULL)
+ __archive_errx(1, "No memory to generate the text version of the ACL");
+ count = 0;
+ if ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
+ append_entry(&p, NULL, ARCHIVE_ENTRY_ACL_USER_OBJ, NULL,
+ acl->mode & 0700, -1);
+ *p++ = ',';
+ append_entry(&p, NULL, ARCHIVE_ENTRY_ACL_GROUP_OBJ, NULL,
+ acl->mode & 0070, -1);
+ *p++ = ',';
+ append_entry(&p, NULL, ARCHIVE_ENTRY_ACL_OTHER, NULL,
+ acl->mode & 0007, -1);
+ count += 3;
+
+ for (ap = acl->acl_head; ap != NULL; ap = ap->next) {
+ if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) == 0)
+ continue;
+ r = archive_mstring_get_mbs_l(
+ &ap->name, &name, &len, sc);
+ if (r != 0)
+ return (-1);
+ *p++ = separator;
+ if (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID)
+ id = ap->id;
+ else
+ id = -1;
+ append_entry(&p, NULL, ap->tag, name,
+ ap->permset, id);
+ count++;
+ }
+ }
+
+
+ if ((flags & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0) {
+ if (flags & ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT)
+ prefix = "default:";
+ else
+ prefix = NULL;
+ count = 0;
+ for (ap = acl->acl_head; ap != NULL; ap = ap->next) {
+ if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) == 0)
+ continue;
+ r = archive_mstring_get_mbs_l(
+ &ap->name, &name, &len, sc);
+ if (r != 0)
+ return (-1);
+ if (count > 0)
+ *p++ = separator;
+ if (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID)
+ id = ap->id;
+ else
+ id = -1;
+ append_entry(&p, prefix, ap->tag,
+ name, ap->permset, id);
+ count ++;
+ }
+ }
+
+ *acl_text = acl->acl_text;
+ if (acl_text_len != NULL)
+ *acl_text_len = strlen(acl->acl_text);
+ return (0);
+}
+
+static void
+append_id(char **p, int id)
+{
+ if (id < 0)
+ id = 0;
+ if (id > 9)
+ append_id(p, id / 10);
+ *(*p)++ = "0123456789"[id % 10];
+}
+
+static void
+append_entry(char **p, const char *prefix, int tag,
+ const char *name, int perm, int id)
+{
+ if (prefix != NULL) {
+ strcpy(*p, prefix);
+ *p += strlen(*p);
+ }
+ switch (tag) {
+ case ARCHIVE_ENTRY_ACL_USER_OBJ:
+ name = NULL;
+ id = -1;
+ /* FALLTHROUGH */
+ case ARCHIVE_ENTRY_ACL_USER:
+ strcpy(*p, "user");
+ break;
+ case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
+ name = NULL;
+ id = -1;
+ /* FALLTHROUGH */
+ case ARCHIVE_ENTRY_ACL_GROUP:
+ strcpy(*p, "group");
+ break;
+ case ARCHIVE_ENTRY_ACL_MASK:
+ strcpy(*p, "mask");
+ name = NULL;
+ id = -1;
+ break;
+ case ARCHIVE_ENTRY_ACL_OTHER:
+ strcpy(*p, "other");
+ name = NULL;
+ id = -1;
+ break;
+ }
+ *p += strlen(*p);
+ *(*p)++ = ':';
+ if (name != NULL) {
+ strcpy(*p, name);
+ *p += strlen(*p);
+ } else if (tag == ARCHIVE_ENTRY_ACL_USER
+ || tag == ARCHIVE_ENTRY_ACL_GROUP) {
+ append_id(p, id);
+ id = -1;
+ }
+ *(*p)++ = ':';
+ *(*p)++ = (perm & 0444) ? 'r' : '-';
+ *(*p)++ = (perm & 0222) ? 'w' : '-';
+ *(*p)++ = (perm & 0111) ? 'x' : '-';
+ if (id != -1) {
+ *(*p)++ = ':';
+ append_id(p, id);
+ }
+ **p = '\0';
+}
+
+/*
+ * Parse a textual ACL. This automatically recognizes and supports
+ * extensions described above. The 'type' argument is used to
+ * indicate the type that should be used for any entries not
+ * explicitly marked as "default:".
+ */
+int
+archive_acl_parse_w(struct archive_acl *acl,
+ const wchar_t *text, int default_type)
+{
+ struct {
+ const wchar_t *start;
+ const wchar_t *end;
+ } field[4], name;
+
+ int fields, n;
+ int type, tag, permset, id;
+ wchar_t sep;
+
+ while (text != NULL && *text != L'\0') {
+ /*
+ * Parse the fields out of the next entry,
+ * advance 'text' to start of next entry.
+ */
+ fields = 0;
+ do {
+ const wchar_t *start, *end;
+ next_field_w(&text, &start, &end, &sep);
+ if (fields < 4) {
+ field[fields].start = start;
+ field[fields].end = end;
+ }
+ ++fields;
+ } while (sep == L':');
+
+ /* Set remaining fields to blank. */
+ for (n = fields; n < 4; ++n)
+ field[n].start = field[n].end = NULL;
+
+ /* Check for a numeric ID in field 1 or 3. */
+ id = -1;
+ isint_w(field[1].start, field[1].end, &id);
+ /* Field 3 is optional. */
+ if (id == -1 && fields > 3)
+ isint_w(field[3].start, field[3].end, &id);
+
+ /*
+ * Solaris extension: "defaultuser::rwx" is the
+ * default ACL corresponding to "user::rwx", etc.
+ */
+ if (field[0].end - field[0].start > 7
+ && wmemcmp(field[0].start, L"default", 7) == 0) {
+ type = ARCHIVE_ENTRY_ACL_TYPE_DEFAULT;
+ field[0].start += 7;
+ } else
+ type = default_type;
+
+ name.start = name.end = NULL;
+ if (prefix_w(field[0].start, field[0].end, L"user")) {
+ if (!ismode_w(field[2].start, field[2].end, &permset))
+ return (ARCHIVE_WARN);
+ if (id != -1 || field[1].start < field[1].end) {
+ tag = ARCHIVE_ENTRY_ACL_USER;
+ name = field[1];
+ } else
+ tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
+ } else if (prefix_w(field[0].start, field[0].end, L"group")) {
+ if (!ismode_w(field[2].start, field[2].end, &permset))
+ return (ARCHIVE_WARN);
+ if (id != -1 || field[1].start < field[1].end) {
+ tag = ARCHIVE_ENTRY_ACL_GROUP;
+ name = field[1];
+ } else
+ tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
+ } else if (prefix_w(field[0].start, field[0].end, L"other")) {
+ if (fields == 2
+ && field[1].start < field[1].end
+ && ismode_w(field[1].start, field[1].end, &permset)) {
+ /* This is Solaris-style "other:rwx" */
+ } else if (fields == 3
+ && field[1].start == field[1].end
+ && field[2].start < field[2].end
+ && ismode_w(field[2].start, field[2].end, &permset)) {
+ /* This is FreeBSD-style "other::rwx" */
+ } else
+ return (ARCHIVE_WARN);
+ tag = ARCHIVE_ENTRY_ACL_OTHER;
+ } else if (prefix_w(field[0].start, field[0].end, L"mask")) {
+ if (fields == 2
+ && field[1].start < field[1].end
+ && ismode_w(field[1].start, field[1].end, &permset)) {
+ /* This is Solaris-style "mask:rwx" */
+ } else if (fields == 3
+ && field[1].start == field[1].end
+ && field[2].start < field[2].end
+ && ismode_w(field[2].start, field[2].end, &permset)) {
+ /* This is FreeBSD-style "mask::rwx" */
+ } else
+ return (ARCHIVE_WARN);
+ tag = ARCHIVE_ENTRY_ACL_MASK;
+ } else
+ return (ARCHIVE_WARN);
+
+ /* Add entry to the internal list. */
+ archive_acl_add_entry_w_len(acl, type, permset,
+ tag, id, name.start, name.end - name.start);
+ }
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Parse a string to a positive decimal integer. Returns true if
+ * the string is non-empty and consists only of decimal digits,
+ * false otherwise.
+ */
+static int
+isint_w(const wchar_t *start, const wchar_t *end, int *result)
+{
+ int n = 0;
+ if (start >= end)
+ return (0);
+ while (start < end) {
+ if (*start < '0' || *start > '9')
+ return (0);
+ if (n > (INT_MAX / 10) ||
+ (n == INT_MAX / 10 && (*start - '0') > INT_MAX % 10)) {
+ n = INT_MAX;
+ } else {
+ n *= 10;
+ n += *start - '0';
+ }
+ start++;
+ }
+ *result = n;
+ return (1);
+}
+
+/*
+ * Parse a string as a mode field. Returns true if
+ * the string is non-empty and consists only of mode characters,
+ * false otherwise.
+ */
+static int
+ismode_w(const wchar_t *start, const wchar_t *end, int *permset)
+{
+ const wchar_t *p;
+
+ if (start >= end)
+ return (0);
+ p = start;
+ *permset = 0;
+ while (p < end) {
+ switch (*p++) {
+ case 'r': case 'R':
+ *permset |= ARCHIVE_ENTRY_ACL_READ;
+ break;
+ case 'w': case 'W':
+ *permset |= ARCHIVE_ENTRY_ACL_WRITE;
+ break;
+ case 'x': case 'X':
+ *permset |= ARCHIVE_ENTRY_ACL_EXECUTE;
+ break;
+ case '-':
+ break;
+ default:
+ return (0);
+ }
+ }
+ return (1);
+}
+
+/*
+ * Match "[:whitespace:]*(.*)[:whitespace:]*[:,\n]". *wp is updated
+ * to point to just after the separator. *start points to the first
+ * character of the matched text and *end just after the last
+ * character of the matched identifier. In particular *end - *start
+ * is the length of the field body, not including leading or trailing
+ * whitespace.
+ */
+static void
+next_field_w(const wchar_t **wp, const wchar_t **start,
+ const wchar_t **end, wchar_t *sep)
+{
+ /* Skip leading whitespace to find start of field. */
+ while (**wp == L' ' || **wp == L'\t' || **wp == L'\n') {
+ (*wp)++;
+ }
+ *start = *wp;
+
+ /* Scan for the separator. */
+ while (**wp != L'\0' && **wp != L',' && **wp != L':' &&
+ **wp != L'\n') {
+ (*wp)++;
+ }
+ *sep = **wp;
+
+ /* Trim trailing whitespace to locate end of field. */
+ *end = *wp - 1;
+ while (**end == L' ' || **end == L'\t' || **end == L'\n') {
+ (*end)--;
+ }
+ (*end)++;
+
+ /* Adjust scanner location. */
+ if (**wp != L'\0')
+ (*wp)++;
+}
+
+/*
+ * Return true if the characters [start...end) are a prefix of 'test'.
+ * This makes it easy to handle the obvious abbreviations: 'u' for 'user', etc.
+ */
+static int
+prefix_w(const wchar_t *start, const wchar_t *end, const wchar_t *test)
+{
+ if (start == end)
+ return (0);
+
+ if (*start++ != *test++)
+ return (0);
+
+ while (start < end && *start++ == *test++)
+ ;
+
+ if (start < end)
+ return (0);
+
+ return (1);
+}
+
+/*
+ * Parse a textual ACL. This automatically recognizes and supports
+ * extensions described above. The 'type' argument is used to
+ * indicate the type that should be used for any entries not
+ * explicitly marked as "default:".
+ */
+int
+archive_acl_parse_l(struct archive_acl *acl,
+ const char *text, int default_type, struct archive_string_conv *sc)
+{
+ struct {
+ const char *start;
+ const char *end;
+ } field[4], name;
+
+ int fields, n, r, ret = ARCHIVE_OK;
+ int type, tag, permset, id;
+ char sep;
+
+ while (text != NULL && *text != '\0') {
+ /*
+ * Parse the fields out of the next entry,
+ * advance 'text' to start of next entry.
+ */
+ fields = 0;
+ do {
+ const char *start, *end;
+ next_field(&text, &start, &end, &sep);
+ if (fields < 4) {
+ field[fields].start = start;
+ field[fields].end = end;
+ }
+ ++fields;
+ } while (sep == ':');
+
+ /* Set remaining fields to blank. */
+ for (n = fields; n < 4; ++n)
+ field[n].start = field[n].end = NULL;
+
+ /* Check for a numeric ID in field 1 or 3. */
+ id = -1;
+ isint(field[1].start, field[1].end, &id);
+ /* Field 3 is optional. */
+ if (id == -1 && fields > 3)
+ isint(field[3].start, field[3].end, &id);
+
+ /*
+ * Solaris extension: "defaultuser::rwx" is the
+ * default ACL corresponding to "user::rwx", etc.
+ */
+ if (field[0].end - field[0].start > 7
+ && memcmp(field[0].start, "default", 7) == 0) {
+ type = ARCHIVE_ENTRY_ACL_TYPE_DEFAULT;
+ field[0].start += 7;
+ } else
+ type = default_type;
+
+ name.start = name.end = NULL;
+ if (prefix(field[0].start, field[0].end, "user")) {
+ if (!ismode(field[2].start, field[2].end, &permset))
+ return (ARCHIVE_WARN);
+ if (id != -1 || field[1].start < field[1].end) {
+ tag = ARCHIVE_ENTRY_ACL_USER;
+ name = field[1];
+ } else
+ tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
+ } else if (prefix(field[0].start, field[0].end, "group")) {
+ if (!ismode(field[2].start, field[2].end, &permset))
+ return (ARCHIVE_WARN);
+ if (id != -1 || field[1].start < field[1].end) {
+ tag = ARCHIVE_ENTRY_ACL_GROUP;
+ name = field[1];
+ } else
+ tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
+ } else if (prefix(field[0].start, field[0].end, "other")) {
+ if (fields == 2
+ && field[1].start < field[1].end
+ && ismode(field[1].start, field[1].end, &permset)) {
+ /* This is Solaris-style "other:rwx" */
+ } else if (fields == 3
+ && field[1].start == field[1].end
+ && field[2].start < field[2].end
+ && ismode(field[2].start, field[2].end, &permset)) {
+ /* This is FreeBSD-style "other::rwx" */
+ } else
+ return (ARCHIVE_WARN);
+ tag = ARCHIVE_ENTRY_ACL_OTHER;
+ } else if (prefix(field[0].start, field[0].end, "mask")) {
+ if (fields == 2
+ && field[1].start < field[1].end
+ && ismode(field[1].start, field[1].end, &permset)) {
+ /* This is Solaris-style "mask:rwx" */
+ } else if (fields == 3
+ && field[1].start == field[1].end
+ && field[2].start < field[2].end
+ && ismode(field[2].start, field[2].end, &permset)) {
+ /* This is FreeBSD-style "mask::rwx" */
+ } else
+ return (ARCHIVE_WARN);
+ tag = ARCHIVE_ENTRY_ACL_MASK;
+ } else
+ return (ARCHIVE_WARN);
+
+ /* Add entry to the internal list. */
+ r = archive_acl_add_entry_len_l(acl, type, permset,
+ tag, id, name.start, name.end - name.start, sc);
+ if (r < ARCHIVE_WARN)
+ return (r);
+ if (r != ARCHIVE_OK)
+ ret = ARCHIVE_WARN;
+ }
+ return (ret);
+}
+
+/*
+ * Parse a string to a positive decimal integer. Returns true if
+ * the string is non-empty and consists only of decimal digits,
+ * false otherwise.
+ */
+static int
+isint(const char *start, const char *end, int *result)
+{
+ int n = 0;
+ if (start >= end)
+ return (0);
+ while (start < end) {
+ if (*start < '0' || *start > '9')
+ return (0);
+ if (n > (INT_MAX / 10) ||
+ (n == INT_MAX / 10 && (*start - '0') > INT_MAX % 10)) {
+ n = INT_MAX;
+ } else {
+ n *= 10;
+ n += *start - '0';
+ }
+ start++;
+ }
+ *result = n;
+ return (1);
+}
+
+/*
+ * Parse a string as a mode field. Returns true if
+ * the string is non-empty and consists only of mode characters,
+ * false otherwise.
+ */
+static int
+ismode(const char *start, const char *end, int *permset)
+{
+ const char *p;
+
+ if (start >= end)
+ return (0);
+ p = start;
+ *permset = 0;
+ while (p < end) {
+ switch (*p++) {
+ case 'r': case 'R':
+ *permset |= ARCHIVE_ENTRY_ACL_READ;
+ break;
+ case 'w': case 'W':
+ *permset |= ARCHIVE_ENTRY_ACL_WRITE;
+ break;
+ case 'x': case 'X':
+ *permset |= ARCHIVE_ENTRY_ACL_EXECUTE;
+ break;
+ case '-':
+ break;
+ default:
+ return (0);
+ }
+ }
+ return (1);
+}
+
+/*
+ * Match "[:whitespace:]*(.*)[:whitespace:]*[:,\n]". *wp is updated
+ * to point to just after the separator. *start points to the first
+ * character of the matched text and *end just after the last
+ * character of the matched identifier. In particular *end - *start
+ * is the length of the field body, not including leading or trailing
+ * whitespace.
+ */
+static void
+next_field(const char **p, const char **start,
+ const char **end, char *sep)
+{
+ /* Skip leading whitespace to find start of field. */
+ while (**p == ' ' || **p == '\t' || **p == '\n') {
+ (*p)++;
+ }
+ *start = *p;
+
+ /* Scan for the separator. */
+ while (**p != '\0' && **p != ',' && **p != ':' && **p != '\n') {
+ (*p)++;
+ }
+ *sep = **p;
+
+ /* Trim trailing whitespace to locate end of field. */
+ *end = *p - 1;
+ while (**end == ' ' || **end == '\t' || **end == '\n') {
+ (*end)--;
+ }
+ (*end)++;
+
+ /* Adjust scanner location. */
+ if (**p != '\0')
+ (*p)++;
+}
+
+/*
+ * Return true if the characters [start...end) are a prefix of 'test'.
+ * This makes it easy to handle the obvious abbreviations: 'u' for 'user', etc.
+ */
+static int
+prefix(const char *start, const char *end, const char *test)
+{
+ if (start == end)
+ return (0);
+
+ if (*start++ != *test++)
+ return (0);
+
+ while (start < end && *start++ == *test++)
+ ;
+
+ if (start < end)
+ return (0);
+
+ return (1);
+}
diff --git a/libarchive/archive_acl_private.h b/libarchive/archive_acl_private.h
new file mode 100644
index 000000000000..1421adbf8a23
--- /dev/null
+++ b/libarchive/archive_acl_private.h
@@ -0,0 +1,87 @@
+/*-
+ * Copyright (c) 2003-2010 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
+#ifndef ARCHIVE_ACL_PRIVATE_H_INCLUDED
+#define ARCHIVE_ACL_PRIVATE_H_INCLUDED
+
+#include "archive_string.h"
+
+struct archive_acl_entry {
+ struct archive_acl_entry *next;
+ int type; /* E.g., access or default */
+ int tag; /* E.g., user/group/other/mask */
+ int permset; /* r/w/x bits */
+ int id; /* uid/gid for user/group */
+ struct archive_mstring name; /* uname/gname */
+};
+
+struct archive_acl {
+ mode_t mode;
+ struct archive_acl_entry *acl_head;
+ struct archive_acl_entry *acl_p;
+ int acl_state; /* See acl_next for details. */
+ wchar_t *acl_text_w;
+ char *acl_text;
+ int acl_types;
+};
+
+void archive_acl_clear(struct archive_acl *);
+void archive_acl_copy(struct archive_acl *, struct archive_acl *);
+int archive_acl_count(struct archive_acl *, int);
+int archive_acl_reset(struct archive_acl *, int);
+int archive_acl_next(struct archive *, struct archive_acl *, int,
+ int *, int *, int *, int *, const char **);
+
+int archive_acl_add_entry(struct archive_acl *, int, int, int, int, const char *);
+int archive_acl_add_entry_w_len(struct archive_acl *,
+ int, int, int, int, const wchar_t *, size_t);
+int archive_acl_add_entry_len(struct archive_acl *,
+ int, int, int, int, const char *, size_t);
+
+const wchar_t *archive_acl_text_w(struct archive *, struct archive_acl *, int);
+int archive_acl_text_l(struct archive_acl *, int, const char **, size_t *,
+ struct archive_string_conv *);
+
+/*
+ * Private ACL parser. This is private because it handles some
+ * very weird formats that clients should not be messing with.
+ * Clients should only deal with their platform-native formats.
+ * Because of the need to support many formats cleanly, new arguments
+ * are likely to get added on a regular basis. Clients who try to use
+ * this interface are likely to be surprised when it changes.
+ */
+int archive_acl_parse_w(struct archive_acl *,
+ const wchar_t *, int /* type */);
+int archive_acl_parse_l(struct archive_acl *,
+ const char *, int /* type */,
+ struct archive_string_conv *);
+
+#endif /* ARCHIVE_ENTRY_PRIVATE_H_INCLUDED */
diff --git a/libarchive/archive_check_magic.c b/libarchive/archive_check_magic.c
index e27e5d827089..91229557a35d 100644
--- a/libarchive/archive_check_magic.c
+++ b/libarchive/archive_check_magic.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2003-2010 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -86,49 +86,89 @@ state_name(unsigned s)
}
}
+static const char *
+archive_handle_type_name(unsigned m)
+{
+ switch (m) {
+ case ARCHIVE_WRITE_MAGIC: return ("archive_write");
+ case ARCHIVE_READ_MAGIC: return ("archive_read");
+ case ARCHIVE_WRITE_DISK_MAGIC: return ("archive_write_disk");
+ case ARCHIVE_READ_DISK_MAGIC: return ("archive_read_disk");
+ default: return NULL;
+ }
+}
-static void
-write_all_states(unsigned int states)
+
+static char *
+write_all_states(char *buff, unsigned int states)
{
unsigned int lowbit;
+ buff[0] = '\0';
+
/* A trick for computing the lowest set bit. */
while ((lowbit = states & (1 + ~states)) != 0) {
states &= ~lowbit; /* Clear the low bit. */
- errmsg(state_name(lowbit));
+ strcat(buff, state_name(lowbit));
if (states != 0)
- errmsg("/");
+ strcat(buff, "/");
}
+ return buff;
}
/*
- * Check magic value and current state; bail if it isn't valid.
+ * Check magic value and current state.
+ * Magic value mismatches are fatal and result in calls to abort().
+ * State mismatches return ARCHIVE_FATAL.
+ * Otherwise, returns ARCHIVE_OK.
*
* This is designed to catch serious programming errors that violate
* the libarchive API.
*/
-void
+int
__archive_check_magic(struct archive *a, unsigned int magic,
unsigned int state, const char *function)
{
- if (a->magic != magic) {
- errmsg("INTERNAL ERROR: Function ");
+ char states1[64];
+ char states2[64];
+ const char *handle_type;
+
+ /*
+ * If this isn't some form of archive handle,
+ * then the library user has screwed up so bad that
+ * we don't even have a reliable way to report an error.
+ */
+ handle_type = archive_handle_type_name(a->magic);
+
+ if (!handle_type) {
+ errmsg("PROGRAMMER ERROR: Function ");
errmsg(function);
- errmsg(" invoked with invalid struct archive structure.\n");
+ errmsg(" invoked with invalid archive handle.\n");
diediedie();
}
- if (state == ARCHIVE_STATE_ANY)
- return;
+ if (a->magic != magic) {
+ archive_set_error(a, -1,
+ "PROGRAMMER ERROR: Function '%s' invoked"
+ " on '%s' archive object, which is not supported.",
+ function,
+ handle_type);
+ a->state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+ }
if ((a->state & state) == 0) {
- errmsg("INTERNAL ERROR: Function '");
- errmsg(function);
- errmsg("' invoked with archive structure in state '");
- write_all_states(a->state);
- errmsg("', should be in state '");
- write_all_states(state);
- errmsg("'\n");
- diediedie();
+ /* If we're already FATAL, don't overwrite the error. */
+ if (a->state != ARCHIVE_STATE_FATAL)
+ archive_set_error(a, -1,
+ "INTERNAL ERROR: Function '%s' invoked with"
+ " archive structure in state '%s',"
+ " should be in state '%s'",
+ function,
+ write_all_states(states1, a->state),
+ write_all_states(states2, state));
+ a->state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
}
+ return ARCHIVE_OK;
}
diff --git a/libarchive/archive_crc32.h b/libarchive/archive_crc32.h
index 103e5df35c15..cd633af89b4a 100644
--- a/libarchive/archive_crc32.h
+++ b/libarchive/archive_crc32.h
@@ -60,6 +60,18 @@ crc32(unsigned long crc, const void *_p, size_t len)
}
crc = crc ^ 0xffffffffUL;
+ /* A use of this loop is about 20% - 30% faster than
+ * no use version in any optimization option of gcc. */
+ for (;len >= 8; len -= 8) {
+ crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
+ crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
+ crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
+ crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
+ crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
+ crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
+ crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
+ crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
+ }
while (len--)
crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
return (crc ^ 0xffffffffUL);
diff --git a/libarchive/archive_crypto.c b/libarchive/archive_crypto.c
new file mode 100644
index 000000000000..2caf57169296
--- /dev/null
+++ b/libarchive/archive_crypto.c
@@ -0,0 +1,1427 @@
+/*-
+* Copyright (c) 2003-2007 Tim Kientzle
+* Copyright (c) 2011 Andres Mejia
+* Copyright (c) 2011 Michihiro NAKAJIMA
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "archive_platform.h"
+
+#include "archive.h"
+#include "archive_crypto_private.h"
+
+/* In particular, force the configure probe to break if it tries
+ * to test a combination of OpenSSL and libmd. */
+#if defined(ARCHIVE_CRYPTO_OPENSSL) && defined(ARCHIVE_CRYPTO_LIBMD)
+#error Cannot use both OpenSSL and libmd.
+#endif
+
+/*
+ * Message digest functions for Windows platform.
+ */
+#if defined(ARCHIVE_CRYPTO_MD5_WIN) ||\
+ defined(ARCHIVE_CRYPTO_SHA1_WIN) ||\
+ defined(ARCHIVE_CRYPTO_SHA256_WIN) ||\
+ defined(ARCHIVE_CRYPTO_SHA384_WIN) ||\
+ defined(ARCHIVE_CRYPTO_SHA512_WIN)
+
+/*
+ * Initialize a Message digest.
+ */
+static int
+win_crypto_init(Digest_CTX *ctx, ALG_ID algId)
+{
+
+ ctx->valid = 0;
+ if (!CryptAcquireContext(&ctx->cryptProv, NULL, NULL,
+ PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
+ if (GetLastError() != (DWORD)NTE_BAD_KEYSET)
+ return (ARCHIVE_FAILED);
+ if (!CryptAcquireContext(&ctx->cryptProv, NULL, NULL,
+ PROV_RSA_FULL, CRYPT_NEWKEYSET))
+ return (ARCHIVE_FAILED);
+ }
+
+ if (!CryptCreateHash(ctx->cryptProv, algId, 0, 0, &ctx->hash)) {
+ CryptReleaseContext(ctx->cryptProv, 0);
+ return (ARCHIVE_FAILED);
+ }
+
+ ctx->valid = 1;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Update a Message digest.
+ */
+static int
+win_crypto_Update(Digest_CTX *ctx, const unsigned char *buf, size_t len)
+{
+
+ if (!ctx->valid)
+ return (ARCHIVE_FAILED);
+
+ CryptHashData(ctx->hash,
+ (unsigned char *)(uintptr_t)buf,
+ (DWORD)len, 0);
+ return (ARCHIVE_OK);
+}
+
+static int
+win_crypto_Final(unsigned char *buf, size_t bufsize, Digest_CTX *ctx)
+{
+ DWORD siglen = bufsize;
+
+ if (!ctx->valid)
+ return (ARCHIVE_FAILED);
+
+ CryptGetHashParam(ctx->hash, HP_HASHVAL, buf, &siglen, 0);
+ CryptDestroyHash(ctx->hash);
+ CryptReleaseContext(ctx->cryptProv, 0);
+ ctx->valid = 0;
+ return (ARCHIVE_OK);
+}
+
+#endif /* defined(ARCHIVE_CRYPTO_*_WIN) */
+
+
+/* MD5 implementations */
+#if defined(ARCHIVE_CRYPTO_MD5_LIBC)
+
+static int
+__archive_libc_md5init(archive_md5_ctx *ctx)
+{
+ MD5Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc_md5update(archive_md5_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ MD5Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc_md5final(archive_md5_ctx *ctx, void *md)
+{
+ MD5Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_MD5_LIBMD)
+
+static int
+__archive_libmd_md5init(archive_md5_ctx *ctx)
+{
+ MD5Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libmd_md5update(archive_md5_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ MD5Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libmd_md5final(archive_md5_ctx *ctx, void *md)
+{
+ MD5Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM)
+
+static int
+__archive_libsystem_md5init(archive_md5_ctx *ctx)
+{
+ CC_MD5_Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libsystem_md5update(archive_md5_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ CC_MD5_Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libsystem_md5final(archive_md5_ctx *ctx, void *md)
+{
+ CC_MD5_Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_MD5_NETTLE)
+
+static int
+__archive_nettle_md5init(archive_md5_ctx *ctx)
+{
+ md5_init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_nettle_md5update(archive_md5_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ md5_update(ctx, insize, indata);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_nettle_md5final(archive_md5_ctx *ctx, void *md)
+{
+ md5_digest(ctx, MD5_DIGEST_SIZE, md);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_MD5_OPENSSL)
+
+static int
+__archive_openssl_md5init(archive_md5_ctx *ctx)
+{
+ EVP_DigestInit(ctx, EVP_md5());
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_openssl_md5update(archive_md5_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ EVP_DigestUpdate(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_openssl_md5final(archive_md5_ctx *ctx, void *md)
+{
+ /* HACK: archive_write_set_format_xar.c is finalizing empty contexts, so
+ * this is meant to cope with that. Real fix is probably to fix
+ * archive_write_set_format_xar.c
+ */
+ if (ctx->digest)
+ EVP_DigestFinal(ctx, md, NULL);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_MD5_WIN)
+
+static int
+__archive_windowsapi_md5init(archive_md5_ctx *ctx)
+{
+ return (win_crypto_init(ctx, CALG_MD5));
+}
+
+static int
+__archive_windowsapi_md5update(archive_md5_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ return (win_crypto_Update(ctx, indata, insize));
+}
+
+static int
+__archive_windowsapi_md5final(archive_md5_ctx *ctx, void *md)
+{
+ return (win_crypto_Final(md, 16, ctx));
+}
+
+#else
+
+static int
+__archive_stub_md5init(archive_md5_ctx *ctx)
+{
+ (void)ctx; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+static int
+__archive_stub_md5update(archive_md5_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ (void)ctx; /* UNUSED */
+ (void)indata; /* UNUSED */
+ (void)insize; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+static int
+__archive_stub_md5final(archive_md5_ctx *ctx, void *md)
+{
+ (void)ctx; /* UNUSED */
+ (void)md; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+#endif
+
+/* RIPEMD160 implementations */
+#if defined(ARCHIVE_CRYPTO_RMD160_LIBC)
+
+static int
+__archive_libc_ripemd160init(archive_rmd160_ctx *ctx)
+{
+ RMD160Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ RMD160Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc_ripemd160final(archive_rmd160_ctx *ctx, void *md)
+{
+ RMD160Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_RMD160_LIBMD)
+
+static int
+__archive_libmd_ripemd160init(archive_rmd160_ctx *ctx)
+{
+ RIPEMD160_Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libmd_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ RIPEMD160_Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libmd_ripemd160final(archive_rmd160_ctx *ctx, void *md)
+{
+ RIPEMD160_Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_RMD160_NETTLE)
+
+static int
+__archive_nettle_ripemd160init(archive_rmd160_ctx *ctx)
+{
+ ripemd160_init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_nettle_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ ripemd160_update(ctx, insize, indata);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_nettle_ripemd160final(archive_rmd160_ctx *ctx, void *md)
+{
+ ripemd160_digest(ctx, RIPEMD160_DIGEST_SIZE, md);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_RMD160_OPENSSL)
+
+static int
+__archive_openssl_ripemd160init(archive_rmd160_ctx *ctx)
+{
+ EVP_DigestInit(ctx, EVP_ripemd160());
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_openssl_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ EVP_DigestUpdate(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_openssl_ripemd160final(archive_rmd160_ctx *ctx, void *md)
+{
+ EVP_DigestFinal(ctx, md, NULL);
+ return (ARCHIVE_OK);
+}
+
+#else
+
+static int
+__archive_stub_ripemd160init(archive_rmd160_ctx *ctx)
+{
+ (void)ctx; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+static int
+__archive_stub_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ (void)ctx; /* UNUSED */
+ (void)indata; /* UNUSED */
+ (void)insize; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+static int
+__archive_stub_ripemd160final(archive_rmd160_ctx *ctx, void *md)
+{
+ (void)ctx; /* UNUSED */
+ (void)md; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+#endif
+
+/* SHA1 implementations */
+#if defined(ARCHIVE_CRYPTO_SHA1_LIBC)
+
+static int
+__archive_libc_sha1init(archive_sha1_ctx *ctx)
+{
+ SHA1Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc_sha1update(archive_sha1_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ SHA1Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc_sha1final(archive_sha1_ctx *ctx, void *md)
+{
+ SHA1Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA1_LIBMD)
+
+static int
+__archive_libmd_sha1init(archive_sha1_ctx *ctx)
+{
+ SHA1_Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libmd_sha1update(archive_sha1_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ SHA1_Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libmd_sha1final(archive_sha1_ctx *ctx, void *md)
+{
+ SHA1_Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM)
+
+static int
+__archive_libsystem_sha1init(archive_sha1_ctx *ctx)
+{
+ CC_SHA1_Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libsystem_sha1update(archive_sha1_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ CC_SHA1_Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libsystem_sha1final(archive_sha1_ctx *ctx, void *md)
+{
+ CC_SHA1_Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA1_NETTLE)
+
+static int
+__archive_nettle_sha1init(archive_sha1_ctx *ctx)
+{
+ sha1_init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_nettle_sha1update(archive_sha1_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ sha1_update(ctx, insize, indata);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_nettle_sha1final(archive_sha1_ctx *ctx, void *md)
+{
+ sha1_digest(ctx, SHA1_DIGEST_SIZE, md);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA1_OPENSSL)
+
+static int
+__archive_openssl_sha1init(archive_sha1_ctx *ctx)
+{
+ EVP_DigestInit(ctx, EVP_sha1());
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_openssl_sha1update(archive_sha1_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ EVP_DigestUpdate(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_openssl_sha1final(archive_sha1_ctx *ctx, void *md)
+{
+ /* HACK: archive_write_set_format_xar.c is finalizing empty contexts, so
+ * this is meant to cope with that. Real fix is probably to fix
+ * archive_write_set_format_xar.c
+ */
+ if (ctx->digest)
+ EVP_DigestFinal(ctx, md, NULL);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA1_WIN)
+
+static int
+__archive_windowsapi_sha1init(archive_sha1_ctx *ctx)
+{
+ return (win_crypto_init(ctx, CALG_SHA1));
+}
+
+static int
+__archive_windowsapi_sha1update(archive_sha1_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ return (win_crypto_Update(ctx, indata, insize));
+}
+
+static int
+__archive_windowsapi_sha1final(archive_sha1_ctx *ctx, void *md)
+{
+ return (win_crypto_Final(md, 20, ctx));
+}
+
+#else
+
+static int
+__archive_stub_sha1init(archive_sha1_ctx *ctx)
+{
+ (void)ctx; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+static int
+__archive_stub_sha1update(archive_sha1_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ (void)ctx; /* UNUSED */
+ (void)indata; /* UNUSED */
+ (void)insize; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+static int
+__archive_stub_sha1final(archive_sha1_ctx *ctx, void *md)
+{
+ (void)ctx; /* UNUSED */
+ (void)md; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+#endif
+
+/* SHA256 implementations */
+#if defined(ARCHIVE_CRYPTO_SHA256_LIBC)
+
+static int
+__archive_libc_sha256init(archive_sha256_ctx *ctx)
+{
+ SHA256_Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc_sha256update(archive_sha256_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ SHA256_Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc_sha256final(archive_sha256_ctx *ctx, void *md)
+{
+ SHA256_Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC2)
+
+static int
+__archive_libc2_sha256init(archive_sha256_ctx *ctx)
+{
+ SHA256Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc2_sha256update(archive_sha256_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ SHA256Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc2_sha256final(archive_sha256_ctx *ctx, void *md)
+{
+ SHA256Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC3)
+
+static int
+__archive_libc3_sha256init(archive_sha256_ctx *ctx)
+{
+ SHA256Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc3_sha256update(archive_sha256_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ SHA256Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc3_sha256final(archive_sha256_ctx *ctx, void *md)
+{
+ SHA256Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA256_LIBMD)
+
+static int
+__archive_libmd_sha256init(archive_sha256_ctx *ctx)
+{
+ SHA256_Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libmd_sha256update(archive_sha256_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ SHA256_Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libmd_sha256final(archive_sha256_ctx *ctx, void *md)
+{
+ SHA256_Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM)
+
+static int
+__archive_libsystem_sha256init(archive_sha256_ctx *ctx)
+{
+ CC_SHA256_Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libsystem_sha256update(archive_sha256_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ CC_SHA256_Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libsystem_sha256final(archive_sha256_ctx *ctx, void *md)
+{
+ CC_SHA256_Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA256_NETTLE)
+
+static int
+__archive_nettle_sha256init(archive_sha256_ctx *ctx)
+{
+ sha256_init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_nettle_sha256update(archive_sha256_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ sha256_update(ctx, insize, indata);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_nettle_sha256final(archive_sha256_ctx *ctx, void *md)
+{
+ sha256_digest(ctx, SHA256_DIGEST_SIZE, md);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA256_OPENSSL)
+
+static int
+__archive_openssl_sha256init(archive_sha256_ctx *ctx)
+{
+ EVP_DigestInit(ctx, EVP_sha256());
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_openssl_sha256update(archive_sha256_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ EVP_DigestUpdate(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_openssl_sha256final(archive_sha256_ctx *ctx, void *md)
+{
+ EVP_DigestFinal(ctx, md, NULL);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA256_WIN)
+
+static int
+__archive_windowsapi_sha256init(archive_sha256_ctx *ctx)
+{
+ return (win_crypto_init(ctx, CALG_SHA_256));
+}
+
+static int
+__archive_windowsapi_sha256update(archive_sha256_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ return (win_crypto_Update(ctx, indata, insize));
+}
+
+static int
+__archive_windowsapi_sha256final(archive_sha256_ctx *ctx, void *md)
+{
+ return (win_crypto_Final(md, 32, ctx));
+}
+
+#else
+
+static int
+__archive_stub_sha256init(archive_sha256_ctx *ctx)
+{
+ (void)ctx; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+static int
+__archive_stub_sha256update(archive_sha256_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ (void)ctx; /* UNUSED */
+ (void)indata; /* UNUSED */
+ (void)insize; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+static int
+__archive_stub_sha256final(archive_sha256_ctx *ctx, void *md)
+{
+ (void)ctx; /* UNUSED */
+ (void)md; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+#endif
+
+/* SHA384 implementations */
+#if defined(ARCHIVE_CRYPTO_SHA384_LIBC)
+
+static int
+__archive_libc_sha384init(archive_sha384_ctx *ctx)
+{
+ SHA384_Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc_sha384update(archive_sha384_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ SHA384_Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc_sha384final(archive_sha384_ctx *ctx, void *md)
+{
+ SHA384_Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC2)
+
+static int
+__archive_libc2_sha384init(archive_sha384_ctx *ctx)
+{
+ SHA384Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc2_sha384update(archive_sha384_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ SHA384Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc2_sha384final(archive_sha384_ctx *ctx, void *md)
+{
+ SHA384Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC3)
+
+static int
+__archive_libc3_sha384init(archive_sha384_ctx *ctx)
+{
+ SHA384Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc3_sha384update(archive_sha384_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ SHA384Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc3_sha384final(archive_sha384_ctx *ctx, void *md)
+{
+ SHA384Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM)
+
+static int
+__archive_libsystem_sha384init(archive_sha384_ctx *ctx)
+{
+ CC_SHA384_Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libsystem_sha384update(archive_sha384_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ CC_SHA384_Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libsystem_sha384final(archive_sha384_ctx *ctx, void *md)
+{
+ CC_SHA384_Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA384_NETTLE)
+
+static int
+__archive_nettle_sha384init(archive_sha384_ctx *ctx)
+{
+ sha384_init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_nettle_sha384update(archive_sha384_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ sha384_update(ctx, insize, indata);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_nettle_sha384final(archive_sha384_ctx *ctx, void *md)
+{
+ sha384_digest(ctx, SHA384_DIGEST_SIZE, md);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA384_OPENSSL)
+
+static int
+__archive_openssl_sha384init(archive_sha384_ctx *ctx)
+{
+ EVP_DigestInit(ctx, EVP_sha384());
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_openssl_sha384update(archive_sha384_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ EVP_DigestUpdate(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_openssl_sha384final(archive_sha384_ctx *ctx, void *md)
+{
+ EVP_DigestFinal(ctx, md, NULL);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA384_WIN)
+
+static int
+__archive_windowsapi_sha384init(archive_sha384_ctx *ctx)
+{
+ return (win_crypto_init(ctx, CALG_SHA_384));
+}
+
+static int
+__archive_windowsapi_sha384update(archive_sha384_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ return (win_crypto_Update(ctx, indata, insize));
+}
+
+static int
+__archive_windowsapi_sha384final(archive_sha384_ctx *ctx, void *md)
+{
+ return (win_crypto_Final(md, 48, ctx));
+}
+
+#else
+
+static int
+__archive_stub_sha384init(archive_sha384_ctx *ctx)
+{
+ (void)ctx; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+static int
+__archive_stub_sha384update(archive_sha384_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ (void)ctx; /* UNUSED */
+ (void)indata; /* UNUSED */
+ (void)insize; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+static int
+__archive_stub_sha384final(archive_sha384_ctx *ctx, void *md)
+{
+ (void)ctx; /* UNUSED */
+ (void)md; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+#endif
+
+/* SHA512 implementations */
+#if defined(ARCHIVE_CRYPTO_SHA512_LIBC)
+
+static int
+__archive_libc_sha512init(archive_sha512_ctx *ctx)
+{
+ SHA512_Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc_sha512update(archive_sha512_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ SHA512_Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc_sha512final(archive_sha512_ctx *ctx, void *md)
+{
+ SHA512_Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC2)
+
+static int
+__archive_libc2_sha512init(archive_sha512_ctx *ctx)
+{
+ SHA512Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc2_sha512update(archive_sha512_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ SHA512Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc2_sha512final(archive_sha512_ctx *ctx, void *md)
+{
+ SHA512Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC3)
+
+static int
+__archive_libc3_sha512init(archive_sha512_ctx *ctx)
+{
+ SHA512Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc3_sha512update(archive_sha512_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ SHA512Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc3_sha512final(archive_sha512_ctx *ctx, void *md)
+{
+ SHA512Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA512_LIBMD)
+
+static int
+__archive_libmd_sha512init(archive_sha512_ctx *ctx)
+{
+ SHA512_Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libmd_sha512update(archive_sha512_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ SHA512_Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libmd_sha512final(archive_sha512_ctx *ctx, void *md)
+{
+ SHA512_Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM)
+
+static int
+__archive_libsystem_sha512init(archive_sha512_ctx *ctx)
+{
+ CC_SHA512_Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libsystem_sha512update(archive_sha512_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ CC_SHA512_Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libsystem_sha512final(archive_sha512_ctx *ctx, void *md)
+{
+ CC_SHA512_Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA512_NETTLE)
+
+static int
+__archive_nettle_sha512init(archive_sha512_ctx *ctx)
+{
+ sha512_init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_nettle_sha512update(archive_sha512_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ sha512_update(ctx, insize, indata);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_nettle_sha512final(archive_sha512_ctx *ctx, void *md)
+{
+ sha512_digest(ctx, SHA512_DIGEST_SIZE, md);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA512_OPENSSL)
+
+static int
+__archive_openssl_sha512init(archive_sha512_ctx *ctx)
+{
+ EVP_DigestInit(ctx, EVP_sha512());
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_openssl_sha512update(archive_sha512_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ EVP_DigestUpdate(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_openssl_sha512final(archive_sha512_ctx *ctx, void *md)
+{
+ EVP_DigestFinal(ctx, md, NULL);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA512_WIN)
+
+static int
+__archive_windowsapi_sha512init(archive_sha512_ctx *ctx)
+{
+ return (win_crypto_init(ctx, CALG_SHA_512));
+}
+
+static int
+__archive_windowsapi_sha512update(archive_sha512_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ return (win_crypto_Update(ctx, indata, insize));
+}
+
+static int
+__archive_windowsapi_sha512final(archive_sha512_ctx *ctx, void *md)
+{
+ return (win_crypto_Final(md, 64, ctx));
+}
+
+#else
+
+static int
+__archive_stub_sha512init(archive_sha512_ctx *ctx)
+{
+ (void)ctx; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+static int
+__archive_stub_sha512update(archive_sha512_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ (void)ctx; /* UNUSED */
+ (void)indata; /* UNUSED */
+ (void)insize; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+static int
+__archive_stub_sha512final(archive_sha512_ctx *ctx, void *md)
+{
+ (void)ctx; /* UNUSED */
+ (void)md; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+#endif
+
+/* NOTE: Crypto functions are set based on availability and by the following
+ * order of preference.
+ * 1. libc
+ * 2. libc2
+ * 3. libc3
+ * 4. libSystem
+ * 5. OpenSSL
+ * 6. Windows API
+ */
+const struct archive_crypto __archive_crypto =
+{
+/* MD5 */
+#if defined(ARCHIVE_CRYPTO_MD5_LIBC)
+ &__archive_libc_md5init,
+ &__archive_libc_md5update,
+ &__archive_libc_md5final,
+#elif defined(ARCHIVE_CRYPTO_MD5_LIBMD)
+ &__archive_libmd_md5init,
+ &__archive_libmd_md5update,
+ &__archive_libmd_md5final,
+#elif defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM)
+ &__archive_libsystem_md5init,
+ &__archive_libsystem_md5update,
+ &__archive_libsystem_md5final,
+#elif defined(ARCHIVE_CRYPTO_MD5_NETTLE)
+ &__archive_nettle_md5init,
+ &__archive_nettle_md5update,
+ &__archive_nettle_md5final,
+#elif defined(ARCHIVE_CRYPTO_MD5_OPENSSL)
+ &__archive_openssl_md5init,
+ &__archive_openssl_md5update,
+ &__archive_openssl_md5final,
+#elif defined(ARCHIVE_CRYPTO_MD5_WIN)
+ &__archive_windowsapi_md5init,
+ &__archive_windowsapi_md5update,
+ &__archive_windowsapi_md5final,
+#elif !defined(ARCHIVE_MD5_COMPILE_TEST)
+ &__archive_stub_md5init,
+ &__archive_stub_md5update,
+ &__archive_stub_md5final,
+#endif
+
+/* RIPEMD160 */
+#if defined(ARCHIVE_CRYPTO_RMD160_LIBC)
+ &__archive_libc_ripemd160init,
+ &__archive_libc_ripemd160update,
+ &__archive_libc_ripemd160final,
+#elif defined(ARCHIVE_CRYPTO_RMD160_LIBMD)
+ &__archive_libmd_ripemd160init,
+ &__archive_libmd_ripemd160update,
+ &__archive_libmd_ripemd160final,
+#elif defined(ARCHIVE_CRYPTO_RMD160_NETTLE)
+ &__archive_nettle_ripemd160init,
+ &__archive_nettle_ripemd160update,
+ &__archive_nettle_ripemd160final,
+#elif defined(ARCHIVE_CRYPTO_RMD160_OPENSSL)
+ &__archive_openssl_ripemd160init,
+ &__archive_openssl_ripemd160update,
+ &__archive_openssl_ripemd160final,
+#elif !defined(ARCHIVE_RMD160_COMPILE_TEST)
+ &__archive_stub_ripemd160init,
+ &__archive_stub_ripemd160update,
+ &__archive_stub_ripemd160final,
+#endif
+
+/* SHA1 */
+#if defined(ARCHIVE_CRYPTO_SHA1_LIBC)
+ &__archive_libc_sha1init,
+ &__archive_libc_sha1update,
+ &__archive_libc_sha1final,
+#elif defined(ARCHIVE_CRYPTO_SHA1_LIBMD)
+ &__archive_libmd_sha1init,
+ &__archive_libmd_sha1update,
+ &__archive_libmd_sha1final,
+#elif defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM)
+ &__archive_libsystem_sha1init,
+ &__archive_libsystem_sha1update,
+ &__archive_libsystem_sha1final,
+#elif defined(ARCHIVE_CRYPTO_SHA1_NETTLE)
+ &__archive_nettle_sha1init,
+ &__archive_nettle_sha1update,
+ &__archive_nettle_sha1final,
+#elif defined(ARCHIVE_CRYPTO_SHA1_OPENSSL)
+ &__archive_openssl_sha1init,
+ &__archive_openssl_sha1update,
+ &__archive_openssl_sha1final,
+#elif defined(ARCHIVE_CRYPTO_SHA1_WIN)
+ &__archive_windowsapi_sha1init,
+ &__archive_windowsapi_sha1update,
+ &__archive_windowsapi_sha1final,
+#elif !defined(ARCHIVE_SHA1_COMPILE_TEST)
+ &__archive_stub_sha1init,
+ &__archive_stub_sha1update,
+ &__archive_stub_sha1final,
+#endif
+
+/* SHA256 */
+#if defined(ARCHIVE_CRYPTO_SHA256_LIBC)
+ &__archive_libc_sha256init,
+ &__archive_libc_sha256update,
+ &__archive_libc_sha256final,
+#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC2)
+ &__archive_libc2_sha256init,
+ &__archive_libc2_sha256update,
+ &__archive_libc2_sha256final,
+#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC3)
+ &__archive_libc3_sha256init,
+ &__archive_libc3_sha256update,
+ &__archive_libc3_sha256final,
+#elif defined(ARCHIVE_CRYPTO_SHA256_LIBMD)
+ &__archive_libmd_sha256init,
+ &__archive_libmd_sha256update,
+ &__archive_libmd_sha256final,
+#elif defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM)
+ &__archive_libsystem_sha256init,
+ &__archive_libsystem_sha256update,
+ &__archive_libsystem_sha256final,
+#elif defined(ARCHIVE_CRYPTO_SHA256_NETTLE)
+ &__archive_nettle_sha256init,
+ &__archive_nettle_sha256update,
+ &__archive_nettle_sha256final,
+#elif defined(ARCHIVE_CRYPTO_SHA256_OPENSSL)
+ &__archive_openssl_sha256init,
+ &__archive_openssl_sha256update,
+ &__archive_openssl_sha256final,
+#elif defined(ARCHIVE_CRYPTO_SHA256_WIN)
+ &__archive_windowsapi_sha256init,
+ &__archive_windowsapi_sha256update,
+ &__archive_windowsapi_sha256final,
+#elif !defined(ARCHIVE_SHA256_COMPILE_TEST)
+ &__archive_stub_sha256init,
+ &__archive_stub_sha256update,
+ &__archive_stub_sha256final,
+#endif
+
+/* SHA384 */
+#if defined(ARCHIVE_CRYPTO_SHA384_LIBC)
+ &__archive_libc_sha384init,
+ &__archive_libc_sha384update,
+ &__archive_libc_sha384final,
+#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC2)
+ &__archive_libc2_sha384init,
+ &__archive_libc2_sha384update,
+ &__archive_libc2_sha384final,
+#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC3)
+ &__archive_libc3_sha384init,
+ &__archive_libc3_sha384update,
+ &__archive_libc3_sha384final,
+#elif defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM)
+ &__archive_libsystem_sha384init,
+ &__archive_libsystem_sha384update,
+ &__archive_libsystem_sha384final,
+#elif defined(ARCHIVE_CRYPTO_SHA384_NETTLE)
+ &__archive_nettle_sha384init,
+ &__archive_nettle_sha384update,
+ &__archive_nettle_sha384final,
+#elif defined(ARCHIVE_CRYPTO_SHA384_OPENSSL)
+ &__archive_openssl_sha384init,
+ &__archive_openssl_sha384update,
+ &__archive_openssl_sha384final,
+#elif defined(ARCHIVE_CRYPTO_SHA384_WIN)
+ &__archive_windowsapi_sha384init,
+ &__archive_windowsapi_sha384update,
+ &__archive_windowsapi_sha384final,
+#elif !defined(ARCHIVE_SHA384_COMPILE_TEST)
+ &__archive_stub_sha384init,
+ &__archive_stub_sha384update,
+ &__archive_stub_sha384final,
+#endif
+
+/* SHA512 */
+#if defined(ARCHIVE_CRYPTO_SHA512_LIBC)
+ &__archive_libc_sha512init,
+ &__archive_libc_sha512update,
+ &__archive_libc_sha512final
+#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC2)
+ &__archive_libc2_sha512init,
+ &__archive_libc2_sha512update,
+ &__archive_libc2_sha512final
+#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC3)
+ &__archive_libc3_sha512init,
+ &__archive_libc3_sha512update,
+ &__archive_libc3_sha512final
+#elif defined(ARCHIVE_CRYPTO_SHA512_LIBMD)
+ &__archive_libmd_sha512init,
+ &__archive_libmd_sha512update,
+ &__archive_libmd_sha512final
+#elif defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM)
+ &__archive_libsystem_sha512init,
+ &__archive_libsystem_sha512update,
+ &__archive_libsystem_sha512final
+#elif defined(ARCHIVE_CRYPTO_SHA512_NETTLE)
+ &__archive_nettle_sha512init,
+ &__archive_nettle_sha512update,
+ &__archive_nettle_sha512final,
+#elif defined(ARCHIVE_CRYPTO_SHA512_OPENSSL)
+ &__archive_openssl_sha512init,
+ &__archive_openssl_sha512update,
+ &__archive_openssl_sha512final
+#elif defined(ARCHIVE_CRYPTO_SHA512_WIN)
+ &__archive_windowsapi_sha512init,
+ &__archive_windowsapi_sha512update,
+ &__archive_windowsapi_sha512final
+#elif !defined(ARCHIVE_SHA512_COMPILE_TEST)
+ &__archive_stub_sha512init,
+ &__archive_stub_sha512update,
+ &__archive_stub_sha512final
+#endif
+};
diff --git a/libarchive/archive_crypto_private.h b/libarchive/archive_crypto_private.h
new file mode 100644
index 000000000000..f8b1fb3c3f54
--- /dev/null
+++ b/libarchive/archive_crypto_private.h
@@ -0,0 +1,376 @@
+/*-
+* Copyright (c) 2003-2007 Tim Kientzle
+* Copyright (c) 2011 Andres Mejia
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
+#ifndef ARCHIVE_CRYPTO_PRIVATE_H_INCLUDED
+#define ARCHIVE_CRYPTO_PRIVATE_H_INCLUDED
+
+/*
+ * Crypto support in various Operating Systems:
+ *
+ * NetBSD:
+ * - MD5 and SHA1 in libc: without _ after algorithm name
+ * - SHA2 in libc: with _ after algorithm name
+ *
+ * OpenBSD:
+ * - MD5, SHA1 and SHA2 in libc: without _ after algorithm name
+ * - OpenBSD 4.4 and earlier have SHA2 in libc with _ after algorithm name
+ *
+ * DragonFly and FreeBSD:
+ * - MD5 libmd: without _ after algorithm name
+ * - SHA1, SHA256 and SHA512 in libmd: with _ after algorithm name
+ *
+ * Mac OS X (10.4 and later):
+ * - MD5, SHA1 and SHA2 in libSystem: with CC_ prefix and _ after algorithm name
+ *
+ * OpenSSL:
+ * - MD5, SHA1 and SHA2 in libcrypto: with _ after algorithm name
+ *
+ * Windows:
+ * - MD5, SHA1 and SHA2 in archive_crypto.c using Windows crypto API
+ */
+
+/* libc crypto headers */
+#if defined(ARCHIVE_CRYPTO_MD5_LIBC)
+#include <md5.h>
+#endif
+#if defined(ARCHIVE_CRYPTO_RMD160_LIBC)
+#include <rmd160.h>
+#endif
+#if defined(ARCHIVE_CRYPTO_SHA1_LIBC)
+#include <sha1.h>
+#endif
+#if defined(ARCHIVE_CRYPTO_SHA256_LIBC) ||\
+ defined(ARCHIVE_CRYPTO_SHA256_LIBC2) ||\
+ defined(ARCHIVE_CRYPTO_SHA256_LIBC3) ||\
+ defined(ARCHIVE_CRYPTO_SHA384_LIBC) ||\
+ defined(ARCHIVE_CRYPTO_SHA384_LIBC2) ||\
+ defined(ARCHIVE_CRYPTO_SHA384_LIBC3) ||\
+ defined(ARCHIVE_CRYPTO_SHA512_LIBC) ||\
+ defined(ARCHIVE_CRYPTO_SHA512_LIBC2) ||\
+ defined(ARCHIVE_CRYPTO_SHA512_LIBC3)
+#include <sha2.h>
+#endif
+
+/* libmd crypto headers */
+#if defined(ARCHIVE_CRYPTO_MD5_LIBMD) ||\
+ defined(ARCHIVE_CRYPTO_RMD160_LIBMD) ||\
+ defined(ARCHIVE_CRYPTO_SHA1_LIBMD) ||\
+ defined(ARCHIVE_CRYPTO_SHA256_LIBMD) ||\
+ defined(ARCHIVE_CRYPTO_SHA512_LIBMD)
+#define ARCHIVE_CRYPTO_LIBMD 1
+#endif
+
+#if defined(ARCHIVE_CRYPTO_MD5_LIBMD)
+#include <md5.h>
+#endif
+#if defined(ARCHIVE_CRYPTO_RMD160_LIBMD)
+#include <ripemd.h>
+#endif
+#if defined(ARCHIVE_CRYPTO_SHA1_LIBMD)
+#include <sha.h>
+#endif
+#if defined(ARCHIVE_CRYPTO_SHA256_LIBMD)
+#include <sha256.h>
+#endif
+#if defined(ARCHIVE_CRYPTO_SHA512_LIBMD)
+#include <sha512.h>
+#endif
+
+/* libSystem crypto headers */
+#if defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM) ||\
+ defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM) ||\
+ defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM) ||\
+ defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM) ||\
+ defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM)
+#include <CommonCrypto/CommonDigest.h>
+#endif
+
+/* Nettle crypto headers */
+#if defined(ARCHIVE_CRYPTO_MD5_NETTLE)
+#include <nettle/md5.h>
+#endif
+#if defined(ARCHIVE_CRYPTO_RMD160_NETTLE)
+#include <nettle/ripemd160.h>
+#endif
+#if defined(ARCHIVE_CRYPTO_SHA1_NETTLE) ||\
+ defined(ARCHIVE_CRYPTO_SHA256_NETTLE) ||\
+ defined(ARCHIVE_CRYPTO_SHA384_NETTLE) ||\
+ defined(ARCHIVE_CRYPTO_SHA512_NETTLE)
+#include <nettle/sha.h>
+#endif
+
+/* OpenSSL crypto headers */
+#if defined(ARCHIVE_CRYPTO_MD5_OPENSSL) ||\
+ defined(ARCHIVE_CRYPTO_RMD160_OPENSSL) ||\
+ defined(ARCHIVE_CRYPTO_SHA1_OPENSSL) ||\
+ defined(ARCHIVE_CRYPTO_SHA256_OPENSSL) ||\
+ defined(ARCHIVE_CRYPTO_SHA384_OPENSSL) ||\
+ defined(ARCHIVE_CRYPTO_SHA512_OPENSSL)
+#define ARCHIVE_CRYPTO_OPENSSL 1
+#include <openssl/evp.h>
+#endif
+
+/* Windows crypto headers */
+#if defined(ARCHIVE_CRYPTO_MD5_WIN) ||\
+ defined(ARCHIVE_CRYPTO_SHA1_WIN) ||\
+ defined(ARCHIVE_CRYPTO_SHA256_WIN) ||\
+ defined(ARCHIVE_CRYPTO_SHA384_WIN) ||\
+ defined(ARCHIVE_CRYPTO_SHA512_WIN)
+#include <wincrypt.h>
+typedef struct {
+ int valid;
+ HCRYPTPROV cryptProv;
+ HCRYPTHASH hash;
+} Digest_CTX;
+#endif
+
+/* typedefs */
+#if defined(ARCHIVE_CRYPTO_MD5_LIBC)
+typedef MD5_CTX archive_md5_ctx;
+#elif defined(ARCHIVE_CRYPTO_MD5_LIBMD)
+typedef MD5_CTX archive_md5_ctx;
+#elif defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM)
+typedef CC_MD5_CTX archive_md5_ctx;
+#elif defined(ARCHIVE_CRYPTO_MD5_NETTLE)
+typedef struct md5_ctx archive_md5_ctx;
+#elif defined(ARCHIVE_CRYPTO_MD5_OPENSSL)
+typedef EVP_MD_CTX archive_md5_ctx;
+#elif defined(ARCHIVE_CRYPTO_MD5_WIN)
+typedef Digest_CTX archive_md5_ctx;
+#else
+typedef unsigned char archive_md5_ctx;
+#endif
+
+#if defined(ARCHIVE_CRYPTO_RMD160_LIBC)
+typedef RMD160_CTX archive_rmd160_ctx;
+#elif defined(ARCHIVE_CRYPTO_RMD160_LIBMD)
+typedef RIPEMD160_CTX archive_rmd160_ctx;
+#elif defined(ARCHIVE_CRYPTO_RMD160_NETTLE)
+typedef struct ripemd160_ctx archive_rmd160_ctx;
+#elif defined(ARCHIVE_CRYPTO_RMD160_OPENSSL)
+typedef EVP_MD_CTX archive_rmd160_ctx;
+#else
+typedef unsigned char archive_rmd160_ctx;
+#endif
+
+#if defined(ARCHIVE_CRYPTO_SHA1_LIBC)
+typedef SHA1_CTX archive_sha1_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA1_LIBMD)
+typedef SHA1_CTX archive_sha1_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM)
+typedef CC_SHA1_CTX archive_sha1_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA1_NETTLE)
+typedef struct sha1_ctx archive_sha1_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA1_OPENSSL)
+typedef EVP_MD_CTX archive_sha1_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA1_WIN)
+typedef Digest_CTX archive_sha1_ctx;
+#else
+typedef unsigned char archive_sha1_ctx;
+#endif
+
+#if defined(ARCHIVE_CRYPTO_SHA256_LIBC)
+typedef SHA256_CTX archive_sha256_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC2)
+typedef SHA256_CTX archive_sha256_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC3)
+typedef SHA2_CTX archive_sha256_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA256_LIBMD)
+typedef SHA256_CTX archive_sha256_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM)
+typedef CC_SHA256_CTX archive_sha256_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA256_NETTLE)
+typedef struct sha256_ctx archive_sha256_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA256_OPENSSL)
+typedef EVP_MD_CTX archive_sha256_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA256_WIN)
+typedef Digest_CTX archive_sha256_ctx;
+#else
+typedef unsigned char archive_sha256_ctx;
+#endif
+
+#if defined(ARCHIVE_CRYPTO_SHA384_LIBC)
+typedef SHA384_CTX archive_sha384_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC2)
+typedef SHA384_CTX archive_sha384_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC3)
+typedef SHA2_CTX archive_sha384_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM)
+typedef CC_SHA512_CTX archive_sha384_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA384_NETTLE)
+typedef struct sha384_ctx archive_sha384_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA384_OPENSSL)
+typedef EVP_MD_CTX archive_sha384_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA384_WIN)
+typedef Digest_CTX archive_sha384_ctx;
+#else
+typedef unsigned char archive_sha384_ctx;
+#endif
+
+#if defined(ARCHIVE_CRYPTO_SHA512_LIBC)
+typedef SHA512_CTX archive_sha512_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC2)
+typedef SHA512_CTX archive_sha512_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC3)
+typedef SHA2_CTX archive_sha512_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA512_LIBMD)
+typedef SHA512_CTX archive_sha512_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM)
+typedef CC_SHA512_CTX archive_sha512_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA512_NETTLE)
+typedef struct sha512_ctx archive_sha512_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA512_OPENSSL)
+typedef EVP_MD_CTX archive_sha512_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA512_WIN)
+typedef Digest_CTX archive_sha512_ctx;
+#else
+typedef unsigned char archive_sha512_ctx;
+#endif
+
+/* defines */
+#if defined(ARCHIVE_CRYPTO_MD5_LIBC) ||\
+ defined(ARCHIVE_CRYPTO_MD5_LIBMD) || \
+ defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM) ||\
+ defined(ARCHIVE_CRYPTO_MD5_NETTLE) ||\
+ defined(ARCHIVE_CRYPTO_MD5_OPENSSL) ||\
+ defined(ARCHIVE_CRYPTO_MD5_WIN)
+#define ARCHIVE_HAS_MD5
+#endif
+#define archive_md5_init(ctx)\
+ __archive_crypto.md5init(ctx)
+#define archive_md5_final(ctx, md)\
+ __archive_crypto.md5final(ctx, md)
+#define archive_md5_update(ctx, buf, n)\
+ __archive_crypto.md5update(ctx, buf, n)
+
+#if defined(ARCHIVE_CRYPTO_RMD160_LIBC) ||\
+ defined(ARCHIVE_CRYPTO_RMD160_NETTLE) ||\
+ defined(ARCHIVE_CRYPTO_RMD160_OPENSSL)
+#define ARCHIVE_HAS_RMD160
+#endif
+#define archive_rmd160_init(ctx)\
+ __archive_crypto.rmd160init(ctx)
+#define archive_rmd160_final(ctx, md)\
+ __archive_crypto.rmd160final(ctx, md)
+#define archive_rmd160_update(ctx, buf, n)\
+ __archive_crypto.rmd160update(ctx, buf, n)
+
+#if defined(ARCHIVE_CRYPTO_SHA1_LIBC) ||\
+ defined(ARCHIVE_CRYPTO_SHA1_LIBMD) || \
+ defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM) ||\
+ defined(ARCHIVE_CRYPTO_SHA1_NETTLE) ||\
+ defined(ARCHIVE_CRYPTO_SHA1_OPENSSL) ||\
+ defined(ARCHIVE_CRYPTO_SHA1_WIN)
+#define ARCHIVE_HAS_SHA1
+#endif
+#define archive_sha1_init(ctx)\
+ __archive_crypto.sha1init(ctx)
+#define archive_sha1_final(ctx, md)\
+ __archive_crypto.sha1final(ctx, md)
+#define archive_sha1_update(ctx, buf, n)\
+ __archive_crypto.sha1update(ctx, buf, n)
+
+#if defined(ARCHIVE_CRYPTO_SHA256_LIBC) ||\
+ defined(ARCHIVE_CRYPTO_SHA256_LIBC2) ||\
+ defined(ARCHIVE_CRYPTO_SHA256_LIBC3) ||\
+ defined(ARCHIVE_CRYPTO_SHA256_LIBMD) ||\
+ defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM) ||\
+ defined(ARCHIVE_CRYPTO_SHA256_NETTLE) ||\
+ defined(ARCHIVE_CRYPTO_SHA256_OPENSSL) ||\
+ defined(ARCHIVE_CRYPTO_SHA256_WIN)
+#define ARCHIVE_HAS_SHA256
+#endif
+#define archive_sha256_init(ctx)\
+ __archive_crypto.sha256init(ctx)
+#define archive_sha256_final(ctx, md)\
+ __archive_crypto.sha256final(ctx, md)
+#define archive_sha256_update(ctx, buf, n)\
+ __archive_crypto.sha256update(ctx, buf, n)
+
+#if defined(ARCHIVE_CRYPTO_SHA384_LIBC) ||\
+ defined(ARCHIVE_CRYPTO_SHA384_LIBC2) ||\
+ defined(ARCHIVE_CRYPTO_SHA384_LIBC3) ||\
+ defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM) ||\
+ defined(ARCHIVE_CRYPTO_SHA384_NETTLE) ||\
+ defined(ARCHIVE_CRYPTO_SHA384_OPENSSL) ||\
+ defined(ARCHIVE_CRYPTO_SHA384_WIN)
+#define ARCHIVE_HAS_SHA384
+#endif
+#define archive_sha384_init(ctx)\
+ __archive_crypto.sha384init(ctx)
+#define archive_sha384_final(ctx, md)\
+ __archive_crypto.sha384final(ctx, md)
+#define archive_sha384_update(ctx, buf, n)\
+ __archive_crypto.sha384update(ctx, buf, n)
+
+#if defined(ARCHIVE_CRYPTO_SHA512_LIBC) ||\
+ defined(ARCHIVE_CRYPTO_SHA512_LIBC2) ||\
+ defined(ARCHIVE_CRYPTO_SHA512_LIBC3) ||\
+ defined(ARCHIVE_CRYPTO_SHA512_LIBMD) ||\
+ defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM) ||\
+ defined(ARCHIVE_CRYPTO_SHA512_NETTLE) ||\
+ defined(ARCHIVE_CRYPTO_SHA512_OPENSSL) ||\
+ defined(ARCHIVE_CRYPTO_SHA512_WIN)
+#define ARCHIVE_HAS_SHA512
+#endif
+#define archive_sha512_init(ctx)\
+ __archive_crypto.sha512init(ctx)
+#define archive_sha512_final(ctx, md)\
+ __archive_crypto.sha512final(ctx, md)
+#define archive_sha512_update(ctx, buf, n)\
+ __archive_crypto.sha512update(ctx, buf, n)
+
+/* Minimal interface to crypto functionality for internal use in libarchive */
+struct archive_crypto
+{
+ /* Message Digest */
+ int (*md5init)(archive_md5_ctx *ctx);
+ int (*md5update)(archive_md5_ctx *, const void *, size_t);
+ int (*md5final)(archive_md5_ctx *, void *);
+ int (*rmd160init)(archive_rmd160_ctx *);
+ int (*rmd160update)(archive_rmd160_ctx *, const void *, size_t);
+ int (*rmd160final)(archive_rmd160_ctx *, void *);
+ int (*sha1init)(archive_sha1_ctx *);
+ int (*sha1update)(archive_sha1_ctx *, const void *, size_t);
+ int (*sha1final)(archive_sha1_ctx *, void *);
+ int (*sha256init)(archive_sha256_ctx *);
+ int (*sha256update)(archive_sha256_ctx *, const void *, size_t);
+ int (*sha256final)(archive_sha256_ctx *, void *);
+ int (*sha384init)(archive_sha384_ctx *);
+ int (*sha384update)(archive_sha384_ctx *, const void *, size_t);
+ int (*sha384final)(archive_sha384_ctx *, void *);
+ int (*sha512init)(archive_sha512_ctx *);
+ int (*sha512update)(archive_sha512_ctx *, const void *, size_t);
+ int (*sha512final)(archive_sha512_ctx *, void *);
+};
+
+extern const struct archive_crypto __archive_crypto;
+
+#endif
diff --git a/libarchive/archive_entry.3 b/libarchive/archive_entry.3
index f7ca88e51952..10e3c34ccbdc 100644
--- a/libarchive/archive_entry.3
+++ b/libarchive/archive_entry.3
@@ -1,4 +1,5 @@
.\" Copyright (c) 2003-2007 Tim Kientzle
+.\" Copyright (c) 2010 Joerg Sonnenberger
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@@ -24,267 +25,25 @@
.\"
.\" $FreeBSD: src/lib/libarchive/archive_entry.3,v 1.18 2008/05/26 17:00:22 kientzle Exp $
.\"
-.Dd May 12, 2008
+.Dd Feburary 22, 2010
.Dt ARCHIVE_ENTRY 3
.Os
.Sh NAME
-.Nm archive_entry_acl_add_entry ,
-.Nm archive_entry_acl_add_entry_w ,
-.Nm archive_entry_acl_clear ,
-.Nm archive_entry_acl_count ,
-.Nm archive_entry_acl_next ,
-.Nm archive_entry_acl_next_w ,
-.Nm archive_entry_acl_reset ,
-.Nm archive_entry_acl_text_w ,
-.Nm archive_entry_atime ,
-.Nm archive_entry_atime_nsec ,
.Nm archive_entry_clear ,
.Nm archive_entry_clone ,
-.Nm archive_entry_copy_fflags_text ,
-.Nm archive_entry_copy_fflags_text_w ,
-.Nm archive_entry_copy_gname ,
-.Nm archive_entry_copy_gname_w ,
-.Nm archive_entry_copy_hardlink ,
-.Nm archive_entry_copy_hardlink_w ,
-.Nm archive_entry_copy_link ,
-.Nm archive_entry_copy_link_w ,
-.Nm archive_entry_copy_pathname_w ,
-.Nm archive_entry_copy_sourcepath ,
-.Nm archive_entry_copy_stat ,
-.Nm archive_entry_copy_symlink ,
-.Nm archive_entry_copy_symlink_w ,
-.Nm archive_entry_copy_uname ,
-.Nm archive_entry_copy_uname_w ,
-.Nm archive_entry_dev ,
-.Nm archive_entry_devmajor ,
-.Nm archive_entry_devminor ,
-.Nm archive_entry_filetype ,
-.Nm archive_entry_fflags ,
-.Nm archive_entry_fflags_text ,
.Nm archive_entry_free ,
-.Nm archive_entry_gid ,
-.Nm archive_entry_gname ,
-.Nm archive_entry_hardlink ,
-.Nm archive_entry_ino ,
-.Nm archive_entry_mode ,
-.Nm archive_entry_mtime ,
-.Nm archive_entry_mtime_nsec ,
-.Nm archive_entry_nlink ,
.Nm archive_entry_new ,
-.Nm archive_entry_pathname ,
-.Nm archive_entry_pathname_w ,
-.Nm archive_entry_rdev ,
-.Nm archive_entry_rdevmajor ,
-.Nm archive_entry_rdevminor ,
-.Nm archive_entry_set_atime ,
-.Nm archive_entry_set_ctime ,
-.Nm archive_entry_set_dev ,
-.Nm archive_entry_set_devmajor ,
-.Nm archive_entry_set_devminor ,
-.Nm archive_entry_set_filetype ,
-.Nm archive_entry_set_fflags ,
-.Nm archive_entry_set_gid ,
-.Nm archive_entry_set_gname ,
-.Nm archive_entry_set_hardlink ,
-.Nm archive_entry_set_link ,
-.Nm archive_entry_set_mode ,
-.Nm archive_entry_set_mtime ,
-.Nm archive_entry_set_pathname ,
-.Nm archive_entry_set_rdevmajor ,
-.Nm archive_entry_set_rdevminor ,
-.Nm archive_entry_set_size ,
-.Nm archive_entry_set_symlink ,
-.Nm archive_entry_set_uid ,
-.Nm archive_entry_set_uname ,
-.Nm archive_entry_size ,
-.Nm archive_entry_sourcepath ,
-.Nm archive_entry_stat ,
-.Nm archive_entry_symlink ,
-.Nm archive_entry_uid ,
-.Nm archive_entry_uname
-.Nd functions for manipulating archive entry descriptions
+.Nd functions for managing archive entry descriptions
.Sh SYNOPSIS
.In archive_entry.h
-.Ft void
-.Fo archive_entry_acl_add_entry
-.Fa "struct archive_entry *"
-.Fa "int type"
-.Fa "int permset"
-.Fa "int tag"
-.Fa "int qual"
-.Fa "const char *name"
-.Fc
-.Ft void
-.Fo archive_entry_acl_add_entry_w
-.Fa "struct archive_entry *"
-.Fa "int type"
-.Fa "int permset"
-.Fa "int tag"
-.Fa "int qual"
-.Fa "const wchar_t *name"
-.Fc
-.Ft void
-.Fn archive_entry_acl_clear "struct archive_entry *"
-.Ft int
-.Fn archive_entry_acl_count "struct archive_entry *" "int type"
-.Ft int
-.Fo archive_entry_acl_next
-.Fa "struct archive_entry *"
-.Fa "int want_type"
-.Fa "int *type"
-.Fa "int *permset"
-.Fa "int *tag"
-.Fa "int *qual"
-.Fa "const char **name"
-.Fc
-.Ft int
-.Fo archive_entry_acl_next_w
-.Fa "struct archive_entry *"
-.Fa "int want_type"
-.Fa "int *type"
-.Fa "int *permset"
-.Fa "int *tag"
-.Fa "int *qual"
-.Fa "const wchar_t **name"
-.Fc
-.Ft int
-.Fn archive_entry_acl_reset "struct archive_entry *" "int want_type"
-.Ft const wchar_t *
-.Fn archive_entry_acl_text_w "struct archive_entry *" "int flags"
-.Ft time_t
-.Fn archive_entry_atime "struct archive_entry *"
-.Ft long
-.Fn archive_entry_atime_nsec "struct archive_entry *"
.Ft "struct archive_entry *"
.Fn archive_entry_clear "struct archive_entry *"
.Ft struct archive_entry *
.Fn archive_entry_clone "struct archive_entry *"
-.Ft const char * *
-.Fn archive_entry_copy_fflags_text_w "struct archive_entry *" "const char *"
-.Ft const wchar_t *
-.Fn archive_entry_copy_fflags_text_w "struct archive_entry *" "const wchar_t *"
-.Ft void
-.Fn archive_entry_copy_gname "struct archive_entry *" "const char *"
-.Ft void
-.Fn archive_entry_copy_gname_w "struct archive_entry *" "const wchar_t *"
-.Ft void
-.Fn archive_entry_copy_hardlink "struct archive_entry *" "const char *"
-.Ft void
-.Fn archive_entry_copy_hardlink_w "struct archive_entry *" "const wchar_t *"
-.Ft void
-.Fn archive_entry_copy_sourcepath "struct archive_entry *" "const char *"
-.Ft void
-.Fn archive_entry_copy_pathname_w "struct archive_entry *" "const wchar_t *"
-.Ft void
-.Fn archive_entry_copy_stat "struct archive_entry *" "const struct stat *"
-.Ft void
-.Fn archive_entry_copy_symlink "struct archive_entry *" "const char *"
-.Ft void
-.Fn archive_entry_copy_symlink_w "struct archive_entry *" "const wchar_t *"
-.Ft void
-.Fn archive_entry_copy_uname "struct archive_entry *" "const char *"
-.Ft void
-.Fn archive_entry_copy_uname_w "struct archive_entry *" "const wchar_t *"
-.Ft dev_t
-.Fn archive_entry_dev "struct archive_entry *"
-.Ft dev_t
-.Fn archive_entry_devmajor "struct archive_entry *"
-.Ft dev_t
-.Fn archive_entry_devminor "struct archive_entry *"
-.Ft mode_t
-.Fn archive_entry_filetype "struct archive_entry *"
-.Ft void
-.Fo archive_entry_fflags
-.Fa "struct archive_entry *"
-.Fa "unsigned long *set"
-.Fa "unsigned long *clear"
-.Fc
-.Ft const char *
-.Fn archive_entry_fflags_text "struct archive_entry *"
.Ft void
.Fn archive_entry_free "struct archive_entry *"
-.Ft const char *
-.Fn archive_entry_gname "struct archive_entry *"
-.Ft const char *
-.Fn archive_entry_hardlink "struct archive_entry *"
-.Ft ino_t
-.Fn archive_entry_ino "struct archive_entry *"
-.Ft mode_t
-.Fn archive_entry_mode "struct archive_entry *"
-.Ft time_t
-.Fn archive_entry_mtime "struct archive_entry *"
-.Ft long
-.Fn archive_entry_mtime_nsec "struct archive_entry *"
-.Ft unsigned int
-.Fn archive_entry_nlink "struct archive_entry *"
.Ft struct archive_entry *
.Fn archive_entry_new "void"
-.Ft const char *
-.Fn archive_entry_pathname "struct archive_entry *"
-.Ft const wchar_t *
-.Fn archive_entry_pathname_w "struct archive_entry *"
-.Ft dev_t
-.Fn archive_entry_rdev "struct archive_entry *"
-.Ft dev_t
-.Fn archive_entry_rdevmajor "struct archive_entry *"
-.Ft dev_t
-.Fn archive_entry_rdevminor "struct archive_entry *"
-.Ft void
-.Fn archive_entry_set_dev "struct archive_entry *" "dev_t"
-.Ft void
-.Fn archive_entry_set_devmajor "struct archive_entry *" "dev_t"
-.Ft void
-.Fn archive_entry_set_devminor "struct archive_entry *" "dev_t"
-.Ft void
-.Fn archive_entry_set_filetype "struct archive_entry *" "unsigned int"
-.Ft void
-.Fo archive_entry_set_fflags
-.Fa "struct archive_entry *"
-.Fa "unsigned long set"
-.Fa "unsigned long clear"
-.Fc
-.Ft void
-.Fn archive_entry_set_gid "struct archive_entry *" "gid_t"
-.Ft void
-.Fn archive_entry_set_gname "struct archive_entry *" "const char *"
-.Ft void
-.Fn archive_entry_set_hardlink "struct archive_entry *" "const char *"
-.Ft void
-.Fn archive_entry_set_ino "struct archive_entry *" "unsigned long"
-.Ft void
-.Fn archive_entry_set_link "struct archive_entry *" "const char *"
-.Ft void
-.Fn archive_entry_set_mode "struct archive_entry *" "mode_t"
-.Ft void
-.Fn archive_entry_set_mtime "struct archive_entry *" "time_t" "long nanos"
-.Ft void
-.Fn archive_entry_set_nlink "struct archive_entry *" "unsigned int"
-.Ft void
-.Fn archive_entry_set_pathname "struct archive_entry *" "const char *"
-.Ft void
-.Fn archive_entry_set_rdev "struct archive_entry *" "dev_t"
-.Ft void
-.Fn archive_entry_set_rdevmajor "struct archive_entry *" "dev_t"
-.Ft void
-.Fn archive_entry_set_rdevminor "struct archive_entry *" "dev_t"
-.Ft void
-.Fn archive_entry_set_size "struct archive_entry *" "int64_t"
-.Ft void
-.Fn archive_entry_set_symlink "struct archive_entry *" "const char *"
-.Ft void
-.Fn archive_entry_set_uid "struct archive_entry *" "uid_t"
-.Ft void
-.Fn archive_entry_set_uname "struct archive_entry *" "const char *"
-.Ft int64_t
-.Fn archive_entry_size "struct archive_entry *"
-.Ft const char *
-.Fn archive_entry_sourcepath "struct archive_entry *"
-.Ft const struct stat *
-.Fn archive_entry_stat "struct archive_entry *"
-.Ft const char *
-.Fn archive_entry_symlink "struct archive_entry *"
-.Ft const char *
-.Fn archive_entry_uname "struct archive_entry *"
.Sh DESCRIPTION
These functions create and manipulate data objects that
represent entries within an archive.
@@ -320,8 +79,24 @@ Allocate and return a blank
.Tn struct archive_entry
object.
.El
-.Ss Set and Get Functions
-Most of the functions here set or read entries in an object.
+.Ss Function groups
+Due to high number of functions, the accessor functions can be found in
+man pages grouped by the purpose.
+.Bl -tag -width ".Xr archive_entry_perms 3"
+.It Xr archive_entry_acl 3
+Access Control List manipulation
+.It Xr archive_entry_paths 3
+Path name manipulation
+.It Xr archive_entry_perms 3
+User, group and mode manipulation
+.It Xr archive_entry_stat 3
+Functions not in the other groups and copying to/from
+.Vt struct stat .
+.It Xr archive_entry_time 3
+Time field manipulation
+.El
+.Pp
+Most of the functions set or read entries in an object.
Such functions have one of the following forms:
.Bl -tag -compact -width indent
.It Fn archive_entry_set_XXXX
@@ -350,75 +125,15 @@ Similarly, if you store a wide string and then store a
narrow string for the same data, the previously-set wide string will
be discarded in favor of the new data.
.Pp
-There are a few set/get functions that merit additional description:
-.Bl -tag -compact -width indent
-.It Fn archive_entry_set_link
-This function sets the symlink field if it is already set.
-Otherwise, it sets the hardlink field.
-.El
-.Ss File Flags
-File flags are transparently converted between a bitmap
-representation and a textual format.
-For example, if you set the bitmap and ask for text, the library
-will build a canonical text format.
-However, if you set a text format and request a text format,
-you will get back the same text, even if it is ill-formed.
-If you need to canonicalize a textual flags string, you should first set the
-text form, then request the bitmap form, then use that to set the bitmap form.
-Setting the bitmap format will clear the internal text representation
-and force it to be reconstructed when you next request the text form.
-.Pp
-The bitmap format consists of two integers, one containing bits
-that should be set, the other specifying bits that should be
-cleared.
-Bits not mentioned in either bitmap will be ignored.
-Usually, the bitmap of bits to be cleared will be set to zero.
-In unusual circumstances, you can force a fully-specified set
-of file flags by setting the bitmap of flags to clear to the complement
-of the bitmap of flags to set.
-(This differs from
-.Xr fflagstostr 3 ,
-which only includes names for set bits.)
-Converting a bitmap to a textual string is a platform-specific
-operation; bits that are not meaningful on the current platform
-will be ignored.
-.Pp
-The canonical text format is a comma-separated list of flag names.
-The
-.Fn archive_entry_copy_fflags_text
-and
-.Fn archive_entry_copy_fflags_text_w
-functions parse the provided text and sets the internal bitmap values.
-This is a platform-specific operation; names that are not meaningful
-on the current platform will be ignored.
-The function returns a pointer to the start of the first name that was not
-recognized, or NULL if every name was recognized.
-Note that every name--including names that follow an unrecognized name--will
-be evaluated, and the bitmaps will be set to reflect every name that is
-recognized.
-(In particular, this differs from
-.Xr strtofflags 3 ,
-which stops parsing at the first unrecognized name.)
-.Ss ACL Handling
-XXX This needs serious help.
-XXX
-.Pp
-An
-.Dq Access Control List
-(ACL) is a list of permissions that grant access to particular users or
-groups beyond what would normally be provided by standard POSIX mode bits.
-The ACL handling here addresses some deficiencies in the POSIX.1e draft 17 ACL
-specification.
-In particular, POSIX.1e draft 17 specifies several different formats, but
-none of those formats include both textual user/group names and numeric
-UIDs/GIDs.
-.Pp
-XXX explain ACL stuff XXX
.\" .Sh EXAMPLE
.\" .Sh RETURN VALUES
.\" .Sh ERRORS
.Sh SEE ALSO
-.Xr archive 3
+.Xr archive 3 ,
+.Xr archive_entry_acl 3 ,
+.Xr archive_entry_paths 3 ,
+.Xr archive_entry_perms 3 ,
+.Xr archive_entry_time 3
.Sh HISTORY
The
.Nm libarchive
diff --git a/libarchive/archive_entry.c b/libarchive/archive_entry.c
index f734b8c4f51d..cbdda8a44def 100644
--- a/libarchive/archive_entry.c
+++ b/libarchive/archive_entry.c
@@ -39,6 +39,9 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_entry.c 201096 2009-12-28 02:41:
#include <sys/sysmacros.h>
#define HAVE_MAJOR
#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
@@ -68,13 +71,12 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_entry.c 201096 2009-12-28 02:41:
#endif
#include "archive.h"
+#include "archive_acl_private.h"
#include "archive_entry.h"
+#include "archive_entry_locale.h"
#include "archive_private.h"
#include "archive_entry_private.h"
-#undef max
-#define max(a, b) ((a)>(b)?(a):(b))
-
#if !defined(HAVE_MAJOR) && !defined(major)
/* Replacement for major/minor/makedev. */
#define major(x) ((int)(0x00ff & ((x) >> 8)))
@@ -98,39 +100,26 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_entry.c 201096 2009-12-28 02:41:
#define ae_makedev(maj, min) makedev((maj), (min))
#endif
-static void aes_clean(struct aes *);
-static void aes_copy(struct aes *dest, struct aes *src);
-static const char * aes_get_mbs(struct aes *);
-static const wchar_t * aes_get_wcs(struct aes *);
-static int aes_set_mbs(struct aes *, const char *mbs);
-static int aes_copy_mbs(struct aes *, const char *mbs);
-/* static void aes_set_wcs(struct aes *, const wchar_t *wcs); */
-static int aes_copy_wcs(struct aes *, const wchar_t *wcs);
-static int aes_copy_wcs_len(struct aes *, const wchar_t *wcs, size_t);
+/*
+ * This adjustment is needed to support the following idiom for adding
+ * 1000ns to the stored time:
+ * archive_entry_set_atime(archive_entry_atime(),
+ * archive_entry_atime_nsec() + 1000)
+ * The additional if() here compensates for ambiguity in the C standard,
+ * which permits two possible interpretations of a % b when a is negative.
+ */
+#define FIX_NS(t,ns) \
+ do { \
+ t += ns / 1000000000; \
+ ns %= 1000000000; \
+ if (ns < 0) { --t; ns += 1000000000; } \
+ } while (0)
static char * ae_fflagstostr(unsigned long bitset, unsigned long bitclear);
static const wchar_t *ae_wcstofflags(const wchar_t *stringp,
unsigned long *setp, unsigned long *clrp);
static const char *ae_strtofflags(const char *stringp,
unsigned long *setp, unsigned long *clrp);
-static void append_entry_w(wchar_t **wp, const wchar_t *prefix, int tag,
- const wchar_t *wname, int perm, int id);
-static void append_id_w(wchar_t **wp, int id);
-
-static int acl_special(struct archive_entry *entry,
- int type, int permset, int tag);
-static struct ae_acl *acl_new_entry(struct archive_entry *entry,
- int type, int permset, int tag, int id);
-static int isint_w(const wchar_t *start, const wchar_t *end, int *result);
-static int ismode_w(const wchar_t *start, const wchar_t *end, int *result);
-static void next_field_w(const wchar_t **wp, const wchar_t **start,
- const wchar_t **end, wchar_t *sep);
-static int prefix_w(const wchar_t *start, const wchar_t *end,
- const wchar_t *test);
-static void
-archive_entry_acl_add_entry_w_len(struct archive_entry *entry, int type,
- int permset, int tag, int id, const wchar_t *name, size_t);
-
#ifndef HAVE_WCSCPY
static wchar_t * wcscpy(wchar_t *s1, const wchar_t *s2)
@@ -154,214 +143,6 @@ static size_t wcslen(const wchar_t *s)
/* Good enough for simple equality testing, but not for sorting. */
#define wmemcmp(a,b,i) memcmp((a), (b), (i) * sizeof(wchar_t))
#endif
-#ifndef HAVE_WMEMCPY
-#define wmemcpy(a,b,i) (wchar_t *)memcpy((a), (b), (i) * sizeof(wchar_t))
-#endif
-
-static void
-aes_clean(struct aes *aes)
-{
- if (aes->aes_wcs) {
- free((wchar_t *)(uintptr_t)aes->aes_wcs);
- aes->aes_wcs = NULL;
- }
- archive_string_free(&(aes->aes_mbs));
- archive_string_free(&(aes->aes_utf8));
- aes->aes_set = 0;
-}
-
-static void
-aes_copy(struct aes *dest, struct aes *src)
-{
- wchar_t *wp;
-
- dest->aes_set = src->aes_set;
- archive_string_copy(&(dest->aes_mbs), &(src->aes_mbs));
- archive_string_copy(&(dest->aes_utf8), &(src->aes_utf8));
-
- if (src->aes_wcs != NULL) {
- wp = (wchar_t *)malloc((wcslen(src->aes_wcs) + 1)
- * sizeof(wchar_t));
- if (wp == NULL)
- __archive_errx(1, "No memory for aes_copy()");
- wcscpy(wp, src->aes_wcs);
- dest->aes_wcs = wp;
- }
-}
-
-static const char *
-aes_get_utf8(struct aes *aes)
-{
- if (aes->aes_set & AES_SET_UTF8)
- return (aes->aes_utf8.s);
- if ((aes->aes_set & AES_SET_WCS)
- && archive_strappend_w_utf8(&(aes->aes_utf8), aes->aes_wcs) != NULL) {
- aes->aes_set |= AES_SET_UTF8;
- return (aes->aes_utf8.s);
- }
- return (NULL);
-}
-
-static const char *
-aes_get_mbs(struct aes *aes)
-{
- /* If we already have an MBS form, return that immediately. */
- if (aes->aes_set & AES_SET_MBS)
- return (aes->aes_mbs.s);
- /* If there's a WCS form, try converting with the native locale. */
- if ((aes->aes_set & AES_SET_WCS)
- && archive_strappend_w_mbs(&(aes->aes_mbs), aes->aes_wcs) != NULL) {
- aes->aes_set |= AES_SET_MBS;
- return (aes->aes_mbs.s);
- }
- /* We'll use UTF-8 for MBS if all else fails. */
- return (aes_get_utf8(aes));
-}
-
-static const wchar_t *
-aes_get_wcs(struct aes *aes)
-{
- wchar_t *w;
- size_t r;
-
- /* Return WCS form if we already have it. */
- if (aes->aes_set & AES_SET_WCS)
- return (aes->aes_wcs);
-
- if (aes->aes_set & AES_SET_MBS) {
- /* Try converting MBS to WCS using native locale. */
- /*
- * No single byte will be more than one wide character,
- * so this length estimate will always be big enough.
- */
- size_t wcs_length = aes->aes_mbs.length;
-
- w = (wchar_t *)malloc((wcs_length + 1) * sizeof(wchar_t));
- if (w == NULL)
- __archive_errx(1, "No memory for aes_get_wcs()");
- r = mbstowcs(w, aes->aes_mbs.s, wcs_length);
- if (r != (size_t)-1 && r != 0) {
- w[r] = 0;
- aes->aes_set |= AES_SET_WCS;
- return (aes->aes_wcs = w);
- }
- free(w);
- }
-
- if (aes->aes_set & AES_SET_UTF8) {
- /* Try converting UTF8 to WCS. */
- aes->aes_wcs = __archive_string_utf8_w(&(aes->aes_utf8));
- if (aes->aes_wcs != NULL)
- aes->aes_set |= AES_SET_WCS;
- return (aes->aes_wcs);
- }
- return (NULL);
-}
-
-static int
-aes_set_mbs(struct aes *aes, const char *mbs)
-{
- return (aes_copy_mbs(aes, mbs));
-}
-
-static int
-aes_copy_mbs(struct aes *aes, const char *mbs)
-{
- if (mbs == NULL) {
- aes->aes_set = 0;
- return (0);
- }
- aes->aes_set = AES_SET_MBS; /* Only MBS form is set now. */
- archive_strcpy(&(aes->aes_mbs), mbs);
- archive_string_empty(&(aes->aes_utf8));
- if (aes->aes_wcs) {
- free((wchar_t *)(uintptr_t)aes->aes_wcs);
- aes->aes_wcs = NULL;
- }
- return (0);
-}
-
-/*
- * The 'update' form tries to proactively update all forms of
- * this string (WCS and MBS) and returns an error if any of
- * them fail. This is used by the 'pax' handler, for instance,
- * to detect and report character-conversion failures early while
- * still allowing clients to get potentially useful values from
- * the more tolerant lazy conversions. (get_mbs and get_wcs will
- * strive to give the user something useful, so you can get hopefully
- * usable values even if some of the character conversions are failing.)
- */
-static int
-aes_update_utf8(struct aes *aes, const char *utf8)
-{
- if (utf8 == NULL) {
- aes->aes_set = 0;
- return (1); /* Succeeded in clearing everything. */
- }
-
- /* Save the UTF8 string. */
- archive_strcpy(&(aes->aes_utf8), utf8);
-
- /* Empty the mbs and wcs strings. */
- archive_string_empty(&(aes->aes_mbs));
- if (aes->aes_wcs) {
- free((wchar_t *)(uintptr_t)aes->aes_wcs);
- aes->aes_wcs = NULL;
- }
-
- aes->aes_set = AES_SET_UTF8; /* Only UTF8 is set now. */
-
- /* TODO: We should just do a direct UTF-8 to MBS conversion
- * here. That would be faster, use less space, and give the
- * same information. (If a UTF-8 to MBS conversion succeeds,
- * then UTF-8->WCS and Unicode->MBS conversions will both
- * succeed.) */
-
- /* Try converting UTF8 to WCS, return false on failure. */
- aes->aes_wcs = __archive_string_utf8_w(&(aes->aes_utf8));
- if (aes->aes_wcs == NULL)
- return (0);
- aes->aes_set = AES_SET_UTF8 | AES_SET_WCS; /* Both UTF8 and WCS set. */
-
- /* Try converting WCS to MBS, return false on failure. */
- if (archive_strappend_w_mbs(&(aes->aes_mbs), aes->aes_wcs) == NULL)
- return (0);
- aes->aes_set = AES_SET_UTF8 | AES_SET_WCS | AES_SET_MBS;
-
- /* All conversions succeeded. */
- return (1);
-}
-
-static int
-aes_copy_wcs(struct aes *aes, const wchar_t *wcs)
-{
- return aes_copy_wcs_len(aes, wcs, wcs == NULL ? 0 : wcslen(wcs));
-}
-
-static int
-aes_copy_wcs_len(struct aes *aes, const wchar_t *wcs, size_t len)
-{
- wchar_t *w;
-
- if (wcs == NULL) {
- aes->aes_set = 0;
- return (0);
- }
- aes->aes_set = AES_SET_WCS; /* Only WCS form set. */
- archive_string_empty(&(aes->aes_mbs));
- archive_string_empty(&(aes->aes_utf8));
- if (aes->aes_wcs) {
- free((wchar_t *)(uintptr_t)aes->aes_wcs);
- aes->aes_wcs = NULL;
- }
- w = (wchar_t *)malloc((len + 1) * sizeof(wchar_t));
- if (w == NULL)
- __archive_errx(1, "No memory for aes_copy_wcs()");
- wmemcpy(w, wcs, len);
- w[len] = L'\0';
- aes->aes_wcs = w;
- return (0);
-}
/****************************************************************************
*
@@ -374,15 +155,17 @@ archive_entry_clear(struct archive_entry *entry)
{
if (entry == NULL)
return (NULL);
- aes_clean(&entry->ae_fflags_text);
- aes_clean(&entry->ae_gname);
- aes_clean(&entry->ae_hardlink);
- aes_clean(&entry->ae_pathname);
- aes_clean(&entry->ae_sourcepath);
- aes_clean(&entry->ae_symlink);
- aes_clean(&entry->ae_uname);
- archive_entry_acl_clear(entry);
+ archive_mstring_clean(&entry->ae_fflags_text);
+ archive_mstring_clean(&entry->ae_gname);
+ archive_mstring_clean(&entry->ae_hardlink);
+ archive_mstring_clean(&entry->ae_pathname);
+ archive_mstring_clean(&entry->ae_sourcepath);
+ archive_mstring_clean(&entry->ae_symlink);
+ archive_mstring_clean(&entry->ae_uname);
+ archive_entry_copy_mac_metadata(entry, NULL, 0);
+ archive_acl_clear(&entry->acl);
archive_entry_xattr_clear(entry);
+ archive_entry_sparse_clear(entry);
free(entry->stat);
memset(entry, 0, sizeof(*entry));
return entry;
@@ -392,36 +175,38 @@ struct archive_entry *
archive_entry_clone(struct archive_entry *entry)
{
struct archive_entry *entry2;
- struct ae_acl *ap, *ap2;
struct ae_xattr *xp;
+ struct ae_sparse *sp;
+ size_t s;
+ const void *p;
/* Allocate new structure and copy over all of the fields. */
- entry2 = (struct archive_entry *)malloc(sizeof(*entry2));
+ /* TODO: Should we copy the archive over? Or require a new archive
+ * as an argument? */
+ entry2 = archive_entry_new2(entry->archive);
if (entry2 == NULL)
return (NULL);
- memset(entry2, 0, sizeof(*entry2));
entry2->ae_stat = entry->ae_stat;
entry2->ae_fflags_set = entry->ae_fflags_set;
entry2->ae_fflags_clear = entry->ae_fflags_clear;
- aes_copy(&entry2->ae_fflags_text, &entry->ae_fflags_text);
- aes_copy(&entry2->ae_gname, &entry->ae_gname);
- aes_copy(&entry2->ae_hardlink, &entry->ae_hardlink);
- aes_copy(&entry2->ae_pathname, &entry->ae_pathname);
- aes_copy(&entry2->ae_sourcepath, &entry->ae_sourcepath);
- aes_copy(&entry2->ae_symlink, &entry->ae_symlink);
+ /* TODO: XXX If clone can have a different archive, what do we do here if
+ * character sets are different? XXX */
+ archive_mstring_copy(&entry2->ae_fflags_text, &entry->ae_fflags_text);
+ archive_mstring_copy(&entry2->ae_gname, &entry->ae_gname);
+ archive_mstring_copy(&entry2->ae_hardlink, &entry->ae_hardlink);
+ archive_mstring_copy(&entry2->ae_pathname, &entry->ae_pathname);
+ archive_mstring_copy(&entry2->ae_sourcepath, &entry->ae_sourcepath);
+ archive_mstring_copy(&entry2->ae_symlink, &entry->ae_symlink);
entry2->ae_set = entry->ae_set;
- aes_copy(&entry2->ae_uname, &entry->ae_uname);
+ archive_mstring_copy(&entry2->ae_uname, &entry->ae_uname);
/* Copy ACL data over. */
- ap = entry->acl_head;
- while (ap != NULL) {
- ap2 = acl_new_entry(entry2,
- ap->type, ap->permset, ap->tag, ap->id);
- if (ap2 != NULL)
- aes_copy(&ap2->name, &ap->name);
- ap = ap->next;
- }
+ archive_acl_copy(&entry2->acl, &entry->acl);
+
+ /* Copy Mac OS metadata. */
+ p = archive_entry_mac_metadata(entry, &s);
+ archive_entry_copy_mac_metadata(entry2, p, s);
/* Copy xattr data over. */
xp = entry->xattr_head;
@@ -431,6 +216,14 @@ archive_entry_clone(struct archive_entry *entry)
xp = xp->next;
}
+ /* Copy sparse data over. */
+ sp = entry->sparse_head;
+ while (sp != NULL) {
+ archive_entry_sparse_add_entry(entry2,
+ sp->offset, sp->length);
+ sp = sp->next;
+ }
+
return (entry2);
}
@@ -444,12 +237,19 @@ archive_entry_free(struct archive_entry *entry)
struct archive_entry *
archive_entry_new(void)
{
+ return archive_entry_new2(NULL);
+}
+
+struct archive_entry *
+archive_entry_new2(struct archive *a)
+{
struct archive_entry *entry;
entry = (struct archive_entry *)malloc(sizeof(*entry));
if (entry == NULL)
return (NULL);
memset(entry, 0, sizeof(*entry));
+ entry->archive = a;
return (entry);
}
@@ -521,6 +321,12 @@ archive_entry_dev(struct archive_entry *entry)
return (entry->ae_stat.aest_dev);
}
+int
+archive_entry_dev_is_set(struct archive_entry *entry)
+{
+ return (entry->ae_set & AE_SET_DEV);
+}
+
dev_t
archive_entry_devmajor(struct archive_entry *entry)
{
@@ -542,7 +348,7 @@ archive_entry_devminor(struct archive_entry *entry)
mode_t
archive_entry_filetype(struct archive_entry *entry)
{
- return (AE_IFMT & entry->ae_stat.aest_mode);
+ return (AE_IFMT & entry->acl.mode);
}
void
@@ -568,8 +374,8 @@ archive_entry_fflags_text(struct archive_entry *entry)
const char *f;
char *p;
- f = aes_get_mbs(&entry->ae_fflags_text);
- if (f != NULL)
+ if (archive_mstring_get_mbs(entry->archive,
+ &entry->ae_fflags_text, &f) == 0 && f != NULL)
return (f);
if (entry->ae_fflags_set == 0 && entry->ae_fflags_clear == 0)
@@ -579,13 +385,15 @@ archive_entry_fflags_text(struct archive_entry *entry)
if (p == NULL)
return (NULL);
- aes_copy_mbs(&entry->ae_fflags_text, p);
+ archive_mstring_copy_mbs(&entry->ae_fflags_text, p);
free(p);
- f = aes_get_mbs(&entry->ae_fflags_text);
- return (f);
+ if (archive_mstring_get_mbs(entry->archive,
+ &entry->ae_fflags_text, &f) == 0)
+ return (f);
+ return (NULL);
}
-gid_t
+int64_t
archive_entry_gid(struct archive_entry *entry)
{
return (entry->ae_stat.aest_gid);
@@ -594,37 +402,72 @@ archive_entry_gid(struct archive_entry *entry)
const char *
archive_entry_gname(struct archive_entry *entry)
{
- return (aes_get_mbs(&entry->ae_gname));
+ const char *p;
+ if (archive_mstring_get_mbs(entry->archive, &entry->ae_gname, &p) == 0)
+ return (p);
+ return (NULL);
}
const wchar_t *
archive_entry_gname_w(struct archive_entry *entry)
{
- return (aes_get_wcs(&entry->ae_gname));
+ const wchar_t *p;
+ if (archive_mstring_get_wcs(entry->archive, &entry->ae_gname, &p) == 0)
+ return (p);
+ return (NULL);
+}
+
+int
+_archive_entry_gname_l(struct archive_entry *entry,
+ const char **p, size_t *len, struct archive_string_conv *sc)
+{
+ return (archive_mstring_get_mbs_l(&entry->ae_gname, p, len, sc));
}
const char *
archive_entry_hardlink(struct archive_entry *entry)
{
- if (entry->ae_set & AE_SET_HARDLINK)
- return (aes_get_mbs(&entry->ae_hardlink));
+ const char *p;
+ if ((entry->ae_set & AE_SET_HARDLINK) && archive_mstring_get_mbs(
+ entry->archive, &entry->ae_hardlink, &p) == 0)
+ return (p);
return (NULL);
}
const wchar_t *
archive_entry_hardlink_w(struct archive_entry *entry)
{
- if (entry->ae_set & AE_SET_HARDLINK)
- return (aes_get_wcs(&entry->ae_hardlink));
+ const wchar_t *p;
+ if ((entry->ae_set & AE_SET_HARDLINK) && archive_mstring_get_wcs(
+ entry->archive, &entry->ae_hardlink, &p) == 0)
+ return (p);
return (NULL);
}
-ino_t
+int
+_archive_entry_hardlink_l(struct archive_entry *entry,
+ const char **p, size_t *len, struct archive_string_conv *sc)
+{
+ if ((entry->ae_set & AE_SET_HARDLINK) == 0) {
+ *p = NULL;
+ *len = 0;
+ return (0);
+ }
+ return (archive_mstring_get_mbs_l(&entry->ae_hardlink, p, len, sc));
+}
+
+int64_t
archive_entry_ino(struct archive_entry *entry)
{
return (entry->ae_stat.aest_ino);
}
+int
+archive_entry_ino_is_set(struct archive_entry *entry)
+{
+ return (entry->ae_set & AE_SET_INO);
+}
+
int64_t
archive_entry_ino64(struct archive_entry *entry)
{
@@ -634,7 +477,7 @@ archive_entry_ino64(struct archive_entry *entry)
mode_t
archive_entry_mode(struct archive_entry *entry)
{
- return (entry->ae_stat.aest_mode);
+ return (entry->acl.mode);
}
time_t
@@ -664,13 +507,34 @@ archive_entry_nlink(struct archive_entry *entry)
const char *
archive_entry_pathname(struct archive_entry *entry)
{
- return (aes_get_mbs(&entry->ae_pathname));
+ const char *p;
+ if (archive_mstring_get_mbs(
+ entry->archive, &entry->ae_pathname, &p) == 0)
+ return (p);
+ return (NULL);
}
const wchar_t *
archive_entry_pathname_w(struct archive_entry *entry)
{
- return (aes_get_wcs(&entry->ae_pathname));
+ const wchar_t *p;
+ if (archive_mstring_get_wcs(
+ entry->archive, &entry->ae_pathname, &p) == 0)
+ return (p);
+ return (NULL);
+}
+
+int
+_archive_entry_pathname_l(struct archive_entry *entry,
+ const char **p, size_t *len, struct archive_string_conv *sc)
+{
+ return (archive_mstring_get_mbs_l(&entry->ae_pathname, p, len, sc));
+}
+
+mode_t
+archive_entry_perm(struct archive_entry *entry)
+{
+ return (~AE_IFMT & entry->acl.mode);
}
dev_t
@@ -716,26 +580,56 @@ archive_entry_size_is_set(struct archive_entry *entry)
const char *
archive_entry_sourcepath(struct archive_entry *entry)
{
- return (aes_get_mbs(&entry->ae_sourcepath));
+ const char *p;
+ if (archive_mstring_get_mbs(
+ entry->archive, &entry->ae_sourcepath, &p) == 0)
+ return (p);
+ return (NULL);
+}
+
+const wchar_t *
+archive_entry_sourcepath_w(struct archive_entry *entry)
+{
+ const wchar_t *p;
+ if (archive_mstring_get_wcs(
+ entry->archive, &entry->ae_sourcepath, &p) == 0)
+ return (p);
+ return (NULL);
}
const char *
archive_entry_symlink(struct archive_entry *entry)
{
- if (entry->ae_set & AE_SET_SYMLINK)
- return (aes_get_mbs(&entry->ae_symlink));
+ const char *p;
+ if ((entry->ae_set & AE_SET_SYMLINK) && archive_mstring_get_mbs(
+ entry->archive, &entry->ae_symlink, &p) == 0)
+ return (p);
return (NULL);
}
const wchar_t *
archive_entry_symlink_w(struct archive_entry *entry)
{
- if (entry->ae_set & AE_SET_SYMLINK)
- return (aes_get_wcs(&entry->ae_symlink));
+ const wchar_t *p;
+ if ((entry->ae_set & AE_SET_SYMLINK) && archive_mstring_get_wcs(
+ entry->archive, &entry->ae_symlink, &p) == 0)
+ return (p);
return (NULL);
}
-uid_t
+int
+_archive_entry_symlink_l(struct archive_entry *entry,
+ const char **p, size_t *len, struct archive_string_conv *sc)
+{
+ if ((entry->ae_set & AE_SET_SYMLINK) == 0) {
+ *p = NULL;
+ *len = 0;
+ return (0);
+ }
+ return (archive_mstring_get_mbs_l( &entry->ae_symlink, p, len, sc));
+}
+
+int64_t
archive_entry_uid(struct archive_entry *entry)
{
return (entry->ae_stat.aest_uid);
@@ -744,13 +638,26 @@ archive_entry_uid(struct archive_entry *entry)
const char *
archive_entry_uname(struct archive_entry *entry)
{
- return (aes_get_mbs(&entry->ae_uname));
+ const char *p;
+ if (archive_mstring_get_mbs(entry->archive, &entry->ae_uname, &p) == 0)
+ return (p);
+ return (NULL);
}
const wchar_t *
archive_entry_uname_w(struct archive_entry *entry)
{
- return (aes_get_wcs(&entry->ae_uname));
+ const wchar_t *p;
+ if (archive_mstring_get_wcs(entry->archive, &entry->ae_uname, &p) == 0)
+ return (p);
+ return (NULL);
+}
+
+int
+_archive_entry_uname_l(struct archive_entry *entry,
+ const char **p, size_t *len, struct archive_string_conv *sc)
+{
+ return (archive_mstring_get_mbs_l(&entry->ae_uname, p, len, sc));
}
/*
@@ -761,15 +668,15 @@ void
archive_entry_set_filetype(struct archive_entry *entry, unsigned int type)
{
entry->stat_valid = 0;
- entry->ae_stat.aest_mode &= ~AE_IFMT;
- entry->ae_stat.aest_mode |= AE_IFMT & type;
+ entry->acl.mode &= ~AE_IFMT;
+ entry->acl.mode |= AE_IFMT & type;
}
void
archive_entry_set_fflags(struct archive_entry *entry,
unsigned long set, unsigned long clear)
{
- aes_clean(&entry->ae_fflags_text);
+ archive_mstring_clean(&entry->ae_fflags_text);
entry->ae_fflags_set = set;
entry->ae_fflags_clear = clear;
}
@@ -778,7 +685,7 @@ const char *
archive_entry_copy_fflags_text(struct archive_entry *entry,
const char *flags)
{
- aes_copy_mbs(&entry->ae_fflags_text, flags);
+ archive_mstring_copy_mbs(&entry->ae_fflags_text, flags);
return (ae_strtofflags(flags,
&entry->ae_fflags_set, &entry->ae_fflags_clear));
}
@@ -787,13 +694,13 @@ const wchar_t *
archive_entry_copy_fflags_text_w(struct archive_entry *entry,
const wchar_t *flags)
{
- aes_copy_wcs(&entry->ae_fflags_text, flags);
+ archive_mstring_copy_wcs(&entry->ae_fflags_text, flags);
return (ae_wcstofflags(flags,
&entry->ae_fflags_set, &entry->ae_fflags_clear));
}
void
-archive_entry_set_gid(struct archive_entry *entry, gid_t g)
+archive_entry_set_gid(struct archive_entry *entry, int64_t g)
{
entry->stat_valid = 0;
entry->ae_stat.aest_gid = g;
@@ -802,31 +709,42 @@ archive_entry_set_gid(struct archive_entry *entry, gid_t g)
void
archive_entry_set_gname(struct archive_entry *entry, const char *name)
{
- aes_set_mbs(&entry->ae_gname, name);
+ archive_mstring_copy_mbs(&entry->ae_gname, name);
}
void
archive_entry_copy_gname(struct archive_entry *entry, const char *name)
{
- aes_copy_mbs(&entry->ae_gname, name);
+ archive_mstring_copy_mbs(&entry->ae_gname, name);
}
void
archive_entry_copy_gname_w(struct archive_entry *entry, const wchar_t *name)
{
- aes_copy_wcs(&entry->ae_gname, name);
+ archive_mstring_copy_wcs(&entry->ae_gname, name);
}
int
archive_entry_update_gname_utf8(struct archive_entry *entry, const char *name)
{
- return (aes_update_utf8(&entry->ae_gname, name));
+ if (archive_mstring_update_utf8(entry->archive,
+ &entry->ae_gname, name) == 0)
+ return (1);
+ return (0);
+}
+
+int
+_archive_entry_copy_gname_l(struct archive_entry *entry,
+ const char *name, size_t len, struct archive_string_conv *sc)
+{
+ return (archive_mstring_copy_mbs_len_l(&entry->ae_gname, name, len, sc));
}
void
-archive_entry_set_ino(struct archive_entry *entry, unsigned long ino)
+archive_entry_set_ino(struct archive_entry *entry, int64_t ino)
{
entry->stat_valid = 0;
+ entry->ae_set |= AE_SET_INO;
entry->ae_stat.aest_ino = ino;
}
@@ -834,13 +752,14 @@ void
archive_entry_set_ino64(struct archive_entry *entry, int64_t ino)
{
entry->stat_valid = 0;
+ entry->ae_set |= AE_SET_INO;
entry->ae_stat.aest_ino = ino;
}
void
archive_entry_set_hardlink(struct archive_entry *entry, const char *target)
{
- aes_set_mbs(&entry->ae_hardlink, target);
+ archive_mstring_copy_mbs(&entry->ae_hardlink, target);
if (target != NULL)
entry->ae_set |= AE_SET_HARDLINK;
else
@@ -850,7 +769,7 @@ archive_entry_set_hardlink(struct archive_entry *entry, const char *target)
void
archive_entry_copy_hardlink(struct archive_entry *entry, const char *target)
{
- aes_copy_mbs(&entry->ae_hardlink, target);
+ archive_mstring_copy_mbs(&entry->ae_hardlink, target);
if (target != NULL)
entry->ae_set |= AE_SET_HARDLINK;
else
@@ -860,7 +779,7 @@ archive_entry_copy_hardlink(struct archive_entry *entry, const char *target)
void
archive_entry_copy_hardlink_w(struct archive_entry *entry, const wchar_t *target)
{
- aes_copy_wcs(&entry->ae_hardlink, target);
+ archive_mstring_copy_wcs(&entry->ae_hardlink, target);
if (target != NULL)
entry->ae_set |= AE_SET_HARDLINK;
else
@@ -874,12 +793,31 @@ archive_entry_update_hardlink_utf8(struct archive_entry *entry, const char *targ
entry->ae_set |= AE_SET_HARDLINK;
else
entry->ae_set &= ~AE_SET_HARDLINK;
- return (aes_update_utf8(&entry->ae_hardlink, target));
+ if (archive_mstring_update_utf8(entry->archive,
+ &entry->ae_hardlink, target) == 0)
+ return (1);
+ return (0);
+}
+
+int
+_archive_entry_copy_hardlink_l(struct archive_entry *entry,
+ const char *target, size_t len, struct archive_string_conv *sc)
+{
+ int r;
+
+ r = archive_mstring_copy_mbs_len_l(&entry->ae_hardlink,
+ target, len, sc);
+ if (target != NULL && r == 0)
+ entry->ae_set |= AE_SET_HARDLINK;
+ else
+ entry->ae_set &= ~AE_SET_HARDLINK;
+ return (r);
}
void
archive_entry_set_atime(struct archive_entry *entry, time_t t, long ns)
{
+ FIX_NS(t, ns);
entry->stat_valid = 0;
entry->ae_set |= AE_SET_ATIME;
entry->ae_stat.aest_atime = t;
@@ -894,11 +832,12 @@ archive_entry_unset_atime(struct archive_entry *entry)
}
void
-archive_entry_set_birthtime(struct archive_entry *entry, time_t m, long ns)
+archive_entry_set_birthtime(struct archive_entry *entry, time_t t, long ns)
{
+ FIX_NS(t, ns);
entry->stat_valid = 0;
entry->ae_set |= AE_SET_BIRTHTIME;
- entry->ae_stat.aest_birthtime = m;
+ entry->ae_stat.aest_birthtime = t;
entry->ae_stat.aest_birthtime_nsec = ns;
}
@@ -912,6 +851,7 @@ archive_entry_unset_birthtime(struct archive_entry *entry)
void
archive_entry_set_ctime(struct archive_entry *entry, time_t t, long ns)
{
+ FIX_NS(t, ns);
entry->stat_valid = 0;
entry->ae_set |= AE_SET_CTIME;
entry->ae_stat.aest_ctime = t;
@@ -929,6 +869,7 @@ void
archive_entry_set_dev(struct archive_entry *entry, dev_t d)
{
entry->stat_valid = 0;
+ entry->ae_set |= AE_SET_DEV;
entry->ae_stat.aest_dev_is_broken_down = 0;
entry->ae_stat.aest_dev = d;
}
@@ -937,6 +878,7 @@ void
archive_entry_set_devmajor(struct archive_entry *entry, dev_t m)
{
entry->stat_valid = 0;
+ entry->ae_set |= AE_SET_DEV;
entry->ae_stat.aest_dev_is_broken_down = 1;
entry->ae_stat.aest_devmajor = m;
}
@@ -945,6 +887,7 @@ void
archive_entry_set_devminor(struct archive_entry *entry, dev_t m)
{
entry->stat_valid = 0;
+ entry->ae_set |= AE_SET_DEV;
entry->ae_stat.aest_dev_is_broken_down = 1;
entry->ae_stat.aest_devminor = m;
}
@@ -954,9 +897,9 @@ void
archive_entry_set_link(struct archive_entry *entry, const char *target)
{
if (entry->ae_set & AE_SET_SYMLINK)
- aes_set_mbs(&entry->ae_symlink, target);
+ archive_mstring_copy_mbs(&entry->ae_symlink, target);
else
- aes_set_mbs(&entry->ae_hardlink, target);
+ archive_mstring_copy_mbs(&entry->ae_hardlink, target);
}
/* Set symlink if symlink is already set, else set hardlink. */
@@ -964,9 +907,9 @@ void
archive_entry_copy_link(struct archive_entry *entry, const char *target)
{
if (entry->ae_set & AE_SET_SYMLINK)
- aes_copy_mbs(&entry->ae_symlink, target);
+ archive_mstring_copy_mbs(&entry->ae_symlink, target);
else
- aes_copy_mbs(&entry->ae_hardlink, target);
+ archive_mstring_copy_mbs(&entry->ae_hardlink, target);
}
/* Set symlink if symlink is already set, else set hardlink. */
@@ -974,33 +917,53 @@ void
archive_entry_copy_link_w(struct archive_entry *entry, const wchar_t *target)
{
if (entry->ae_set & AE_SET_SYMLINK)
- aes_copy_wcs(&entry->ae_symlink, target);
+ archive_mstring_copy_wcs(&entry->ae_symlink, target);
else
- aes_copy_wcs(&entry->ae_hardlink, target);
+ archive_mstring_copy_wcs(&entry->ae_hardlink, target);
}
int
archive_entry_update_link_utf8(struct archive_entry *entry, const char *target)
{
+ int r;
+ if (entry->ae_set & AE_SET_SYMLINK)
+ r = archive_mstring_update_utf8(entry->archive,
+ &entry->ae_symlink, target);
+ else
+ r = archive_mstring_update_utf8(entry->archive,
+ &entry->ae_hardlink, target);
+ return ((r == 0)? 1: 0);
+}
+
+int
+_archive_entry_copy_link_l(struct archive_entry *entry,
+ const char *target, size_t len, struct archive_string_conv *sc)
+{
+ int r;
+
if (entry->ae_set & AE_SET_SYMLINK)
- return (aes_update_utf8(&entry->ae_symlink, target));
+ r = archive_mstring_copy_mbs_len_l(&entry->ae_symlink,
+ target, len, sc);
else
- return (aes_update_utf8(&entry->ae_hardlink, target));
+ r = archive_mstring_copy_mbs_len_l(&entry->ae_hardlink,
+ target, len, sc);
+ return (r);
}
void
archive_entry_set_mode(struct archive_entry *entry, mode_t m)
{
entry->stat_valid = 0;
- entry->ae_stat.aest_mode = m;
+ entry->acl.mode = m;
}
void
-archive_entry_set_mtime(struct archive_entry *entry, time_t m, long ns)
+archive_entry_set_mtime(struct archive_entry *entry, time_t t, long ns)
{
+ FIX_NS(t, ns);
entry->stat_valid = 0;
entry->ae_set |= AE_SET_MTIME;
- entry->ae_stat.aest_mtime = m;
+ entry->ae_stat.aest_mtime = t;
entry->ae_stat.aest_mtime_nsec = ns;
}
@@ -1021,33 +984,44 @@ archive_entry_set_nlink(struct archive_entry *entry, unsigned int nlink)
void
archive_entry_set_pathname(struct archive_entry *entry, const char *name)
{
- aes_set_mbs(&entry->ae_pathname, name);
+ archive_mstring_copy_mbs(&entry->ae_pathname, name);
}
void
archive_entry_copy_pathname(struct archive_entry *entry, const char *name)
{
- aes_copy_mbs(&entry->ae_pathname, name);
+ archive_mstring_copy_mbs(&entry->ae_pathname, name);
}
void
archive_entry_copy_pathname_w(struct archive_entry *entry, const wchar_t *name)
{
- aes_copy_wcs(&entry->ae_pathname, name);
+ archive_mstring_copy_wcs(&entry->ae_pathname, name);
}
int
archive_entry_update_pathname_utf8(struct archive_entry *entry, const char *name)
{
- return (aes_update_utf8(&entry->ae_pathname, name));
+ if (archive_mstring_update_utf8(entry->archive,
+ &entry->ae_pathname, name) == 0)
+ return (1);
+ return (0);
+}
+
+int
+_archive_entry_copy_pathname_l(struct archive_entry *entry,
+ const char *name, size_t len, struct archive_string_conv *sc)
+{
+ return (archive_mstring_copy_mbs_len_l(&entry->ae_pathname,
+ name, len, sc));
}
void
archive_entry_set_perm(struct archive_entry *entry, mode_t p)
{
entry->stat_valid = 0;
- entry->ae_stat.aest_mode &= AE_IFMT;
- entry->ae_stat.aest_mode |= ~AE_IFMT & p;
+ entry->acl.mode &= AE_IFMT;
+ entry->acl.mode |= ~AE_IFMT & p;
}
void
@@ -1092,13 +1066,19 @@ archive_entry_unset_size(struct archive_entry *entry)
void
archive_entry_copy_sourcepath(struct archive_entry *entry, const char *path)
{
- aes_set_mbs(&entry->ae_sourcepath, path);
+ archive_mstring_copy_mbs(&entry->ae_sourcepath, path);
+}
+
+void
+archive_entry_copy_sourcepath_w(struct archive_entry *entry, const wchar_t *path)
+{
+ archive_mstring_copy_wcs(&entry->ae_sourcepath, path);
}
void
archive_entry_set_symlink(struct archive_entry *entry, const char *linkname)
{
- aes_set_mbs(&entry->ae_symlink, linkname);
+ archive_mstring_copy_mbs(&entry->ae_symlink, linkname);
if (linkname != NULL)
entry->ae_set |= AE_SET_SYMLINK;
else
@@ -1108,7 +1088,7 @@ archive_entry_set_symlink(struct archive_entry *entry, const char *linkname)
void
archive_entry_copy_symlink(struct archive_entry *entry, const char *linkname)
{
- aes_copy_mbs(&entry->ae_symlink, linkname);
+ archive_mstring_copy_mbs(&entry->ae_symlink, linkname);
if (linkname != NULL)
entry->ae_set |= AE_SET_SYMLINK;
else
@@ -1118,7 +1098,7 @@ archive_entry_copy_symlink(struct archive_entry *entry, const char *linkname)
void
archive_entry_copy_symlink_w(struct archive_entry *entry, const wchar_t *linkname)
{
- aes_copy_wcs(&entry->ae_symlink, linkname);
+ archive_mstring_copy_wcs(&entry->ae_symlink, linkname);
if (linkname != NULL)
entry->ae_set |= AE_SET_SYMLINK;
else
@@ -1132,11 +1112,29 @@ archive_entry_update_symlink_utf8(struct archive_entry *entry, const char *linkn
entry->ae_set |= AE_SET_SYMLINK;
else
entry->ae_set &= ~AE_SET_SYMLINK;
- return (aes_update_utf8(&entry->ae_symlink, linkname));
+ if (archive_mstring_update_utf8(entry->archive,
+ &entry->ae_symlink, linkname) == 0)
+ return (1);
+ return (0);
+}
+
+int
+_archive_entry_copy_symlink_l(struct archive_entry *entry,
+ const char *linkname, size_t len, struct archive_string_conv *sc)
+{
+ int r;
+
+ r = archive_mstring_copy_mbs_len_l(&entry->ae_symlink,
+ linkname, len, sc);
+ if (linkname != NULL && r == 0)
+ entry->ae_set |= AE_SET_SYMLINK;
+ else
+ entry->ae_set &= ~AE_SET_SYMLINK;
+ return (r);
}
void
-archive_entry_set_uid(struct archive_entry *entry, uid_t u)
+archive_entry_set_uid(struct archive_entry *entry, int64_t u)
{
entry->stat_valid = 0;
entry->ae_stat.aest_uid = u;
@@ -1145,25 +1143,60 @@ archive_entry_set_uid(struct archive_entry *entry, uid_t u)
void
archive_entry_set_uname(struct archive_entry *entry, const char *name)
{
- aes_set_mbs(&entry->ae_uname, name);
+ archive_mstring_copy_mbs(&entry->ae_uname, name);
}
void
archive_entry_copy_uname(struct archive_entry *entry, const char *name)
{
- aes_copy_mbs(&entry->ae_uname, name);
+ archive_mstring_copy_mbs(&entry->ae_uname, name);
}
void
archive_entry_copy_uname_w(struct archive_entry *entry, const wchar_t *name)
{
- aes_copy_wcs(&entry->ae_uname, name);
+ archive_mstring_copy_wcs(&entry->ae_uname, name);
}
int
archive_entry_update_uname_utf8(struct archive_entry *entry, const char *name)
{
- return (aes_update_utf8(&entry->ae_uname, name));
+ if (archive_mstring_update_utf8(entry->archive,
+ &entry->ae_uname, name) == 0)
+ return (1);
+ return (0);
+}
+
+int
+_archive_entry_copy_uname_l(struct archive_entry *entry,
+ const char *name, size_t len, struct archive_string_conv *sc)
+{
+ return (archive_mstring_copy_mbs_len_l(&entry->ae_uname,
+ name, len, sc));
+}
+
+const void *
+archive_entry_mac_metadata(struct archive_entry *entry, size_t *s)
+{
+ *s = entry->mac_metadata_size;
+ return entry->mac_metadata;
+}
+
+void
+archive_entry_copy_mac_metadata(struct archive_entry *entry,
+ const void *p, size_t s)
+{
+ free(entry->mac_metadata);
+ if (p == NULL || s == 0) {
+ entry->mac_metadata = NULL;
+ entry->mac_metadata_size = 0;
+ } else {
+ entry->mac_metadata_size = s;
+ entry->mac_metadata = malloc(s);
+ if (entry->mac_metadata == NULL)
+ abort();
+ memcpy(entry->mac_metadata, p, s);
+ }
}
/*
@@ -1175,148 +1208,37 @@ archive_entry_update_uname_utf8(struct archive_entry *entry, const char *name)
* uninitiated.
*/
+struct archive_acl *
+archive_entry_acl(struct archive_entry *entry)
+{
+ return &entry->acl;
+}
+
void
archive_entry_acl_clear(struct archive_entry *entry)
{
- struct ae_acl *ap;
-
- while (entry->acl_head != NULL) {
- ap = entry->acl_head->next;
- aes_clean(&entry->acl_head->name);
- free(entry->acl_head);
- entry->acl_head = ap;
- }
- if (entry->acl_text_w != NULL) {
- free(entry->acl_text_w);
- entry->acl_text_w = NULL;
- }
- entry->acl_p = NULL;
- entry->acl_state = 0; /* Not counting. */
+ archive_acl_clear(&entry->acl);
}
/*
* Add a single ACL entry to the internal list of ACL data.
*/
-void
+int
archive_entry_acl_add_entry(struct archive_entry *entry,
int type, int permset, int tag, int id, const char *name)
{
- struct ae_acl *ap;
-
- if (acl_special(entry, type, permset, tag) == 0)
- return;
- ap = acl_new_entry(entry, type, permset, tag, id);
- if (ap == NULL) {
- /* XXX Error XXX */
- return;
- }
- if (name != NULL && *name != '\0')
- aes_copy_mbs(&ap->name, name);
- else
- aes_clean(&ap->name);
+ return archive_acl_add_entry(&entry->acl, type, permset, tag, id, name);
}
/*
* As above, but with a wide-character name.
*/
-void
+int
archive_entry_acl_add_entry_w(struct archive_entry *entry,
int type, int permset, int tag, int id, const wchar_t *name)
{
- archive_entry_acl_add_entry_w_len(entry, type, permset, tag, id, name, wcslen(name));
-}
-
-static void
-archive_entry_acl_add_entry_w_len(struct archive_entry *entry,
- int type, int permset, int tag, int id, const wchar_t *name, size_t len)
-{
- struct ae_acl *ap;
-
- if (acl_special(entry, type, permset, tag) == 0)
- return;
- ap = acl_new_entry(entry, type, permset, tag, id);
- if (ap == NULL) {
- /* XXX Error XXX */
- return;
- }
- if (name != NULL && *name != L'\0' && len > 0)
- aes_copy_wcs_len(&ap->name, name, len);
- else
- aes_clean(&ap->name);
-}
-
-/*
- * If this ACL entry is part of the standard POSIX permissions set,
- * store the permissions in the stat structure and return zero.
- */
-static int
-acl_special(struct archive_entry *entry, int type, int permset, int tag)
-{
- if (type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS) {
- switch (tag) {
- case ARCHIVE_ENTRY_ACL_USER_OBJ:
- entry->ae_stat.aest_mode &= ~0700;
- entry->ae_stat.aest_mode |= (permset & 7) << 6;
- return (0);
- case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
- entry->ae_stat.aest_mode &= ~0070;
- entry->ae_stat.aest_mode |= (permset & 7) << 3;
- return (0);
- case ARCHIVE_ENTRY_ACL_OTHER:
- entry->ae_stat.aest_mode &= ~0007;
- entry->ae_stat.aest_mode |= permset & 7;
- return (0);
- }
- }
- return (1);
-}
-
-/*
- * Allocate and populate a new ACL entry with everything but the
- * name.
- */
-static struct ae_acl *
-acl_new_entry(struct archive_entry *entry,
- int type, int permset, int tag, int id)
-{
- struct ae_acl *ap, *aq;
-
- if (type != ARCHIVE_ENTRY_ACL_TYPE_ACCESS &&
- type != ARCHIVE_ENTRY_ACL_TYPE_DEFAULT)
- return (NULL);
- if (entry->acl_text_w != NULL) {
- free(entry->acl_text_w);
- entry->acl_text_w = NULL;
- }
-
- /* XXX TODO: More sanity-checks on the arguments XXX */
-
- /* If there's a matching entry already in the list, overwrite it. */
- ap = entry->acl_head;
- aq = NULL;
- while (ap != NULL) {
- if (ap->type == type && ap->tag == tag && ap->id == id) {
- ap->permset = permset;
- return (ap);
- }
- aq = ap;
- ap = ap->next;
- }
-
- /* Add a new entry to the end of the list. */
- ap = (struct ae_acl *)malloc(sizeof(*ap));
- if (ap == NULL)
- return (NULL);
- memset(ap, 0, sizeof(*ap));
- if (aq == NULL)
- entry->acl_head = ap;
- else
- aq->next = ap;
- ap->type = type;
- ap->tag = tag;
- ap->id = id;
- ap->permset = permset;
- return (ap);
+ return archive_acl_add_entry_w_len(&entry->acl,
+ type, permset, tag, id, name, wcslen(name));
}
/*
@@ -1325,20 +1247,7 @@ acl_new_entry(struct archive_entry *entry,
int
archive_entry_acl_count(struct archive_entry *entry, int want_type)
{
- int count;
- struct ae_acl *ap;
-
- count = 0;
- ap = entry->acl_head;
- while (ap != NULL) {
- if ((ap->type & want_type) != 0)
- count++;
- ap = ap->next;
- }
-
- if (count > 0 && ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0))
- count += 3;
- return (count);
+ return archive_acl_count(&entry->acl, want_type);
}
/*
@@ -1349,93 +1258,18 @@ archive_entry_acl_count(struct archive_entry *entry, int want_type)
int
archive_entry_acl_reset(struct archive_entry *entry, int want_type)
{
- int count, cutoff;
-
- count = archive_entry_acl_count(entry, want_type);
-
- /*
- * If the only entries are the three standard ones,
- * then don't return any ACL data. (In this case,
- * client can just use chmod(2) to set permissions.)
- */
- if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0)
- cutoff = 3;
- else
- cutoff = 0;
-
- if (count > cutoff)
- entry->acl_state = ARCHIVE_ENTRY_ACL_USER_OBJ;
- else
- entry->acl_state = 0;
- entry->acl_p = entry->acl_head;
- return (count);
+ return archive_acl_reset(&entry->acl, want_type);
}
/*
* Return the next ACL entry in the list. Fake entries for the
* standard permissions and include them in the returned list.
*/
-
int
archive_entry_acl_next(struct archive_entry *entry, int want_type, int *type,
int *permset, int *tag, int *id, const char **name)
{
- *name = NULL;
- *id = -1;
-
- /*
- * The acl_state is either zero (no entries available), -1
- * (reading from list), or an entry type (retrieve that type
- * from ae_stat.aest_mode).
- */
- if (entry->acl_state == 0)
- return (ARCHIVE_WARN);
-
- /* The first three access entries are special. */
- if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
- switch (entry->acl_state) {
- case ARCHIVE_ENTRY_ACL_USER_OBJ:
- *permset = (entry->ae_stat.aest_mode >> 6) & 7;
- *type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
- *tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
- entry->acl_state = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
- return (ARCHIVE_OK);
- case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
- *permset = (entry->ae_stat.aest_mode >> 3) & 7;
- *type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
- *tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
- entry->acl_state = ARCHIVE_ENTRY_ACL_OTHER;
- return (ARCHIVE_OK);
- case ARCHIVE_ENTRY_ACL_OTHER:
- *permset = entry->ae_stat.aest_mode & 7;
- *type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
- *tag = ARCHIVE_ENTRY_ACL_OTHER;
- entry->acl_state = -1;
- entry->acl_p = entry->acl_head;
- return (ARCHIVE_OK);
- default:
- break;
- }
- }
-
- while (entry->acl_p != NULL && (entry->acl_p->type & want_type) == 0)
- entry->acl_p = entry->acl_p->next;
- if (entry->acl_p == NULL) {
- entry->acl_state = 0;
- *type = 0;
- *permset = 0;
- *tag = 0;
- *id = -1;
- *name = NULL;
- return (ARCHIVE_EOF); /* End of ACL entries. */
- }
- *type = entry->acl_p->type;
- *permset = entry->acl_p->permset;
- *tag = entry->acl_p->tag;
- *id = entry->acl_p->id;
- *name = aes_get_mbs(&entry->acl_p->name);
- entry->acl_p = entry->acl_p->next;
- return (ARCHIVE_OK);
+ return archive_acl_next(entry->archive, &entry->acl, want_type, type, permset, tag, id, name);
}
/*
@@ -1445,412 +1279,27 @@ archive_entry_acl_next(struct archive_entry *entry, int want_type, int *type,
const wchar_t *
archive_entry_acl_text_w(struct archive_entry *entry, int flags)
{
- int count;
- size_t length;
- const wchar_t *wname;
- const wchar_t *prefix;
- wchar_t separator;
- struct ae_acl *ap;
- int id;
- wchar_t *wp;
-
- if (entry->acl_text_w != NULL) {
- free (entry->acl_text_w);
- entry->acl_text_w = NULL;
- }
-
- separator = L',';
- count = 0;
- length = 0;
- ap = entry->acl_head;
- while (ap != NULL) {
- if ((ap->type & flags) != 0) {
- count++;
- if ((flags & ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT) &&
- (ap->type & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT))
- length += 8; /* "default:" */
- length += 5; /* tag name */
- length += 1; /* colon */
- wname = aes_get_wcs(&ap->name);
- if (wname != NULL)
- length += wcslen(wname);
- else
- length += sizeof(uid_t) * 3 + 1;
- length ++; /* colon */
- length += 3; /* rwx */
- length += 1; /* colon */
- length += max(sizeof(uid_t), sizeof(gid_t)) * 3 + 1;
- length ++; /* newline */
- }
- ap = ap->next;
- }
-
- if (count > 0 && ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0)) {
- length += 10; /* "user::rwx\n" */
- length += 11; /* "group::rwx\n" */
- length += 11; /* "other::rwx\n" */
- }
-
- if (count == 0)
- return (NULL);
-
- /* Now, allocate the string and actually populate it. */
- wp = entry->acl_text_w = (wchar_t *)malloc(length * sizeof(wchar_t));
- if (wp == NULL)
- __archive_errx(1, "No memory to generate the text version of the ACL");
- count = 0;
- if ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
- append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_USER_OBJ, NULL,
- entry->ae_stat.aest_mode & 0700, -1);
- *wp++ = ',';
- append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_GROUP_OBJ, NULL,
- entry->ae_stat.aest_mode & 0070, -1);
- *wp++ = ',';
- append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_OTHER, NULL,
- entry->ae_stat.aest_mode & 0007, -1);
- count += 3;
-
- ap = entry->acl_head;
- while (ap != NULL) {
- if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
- wname = aes_get_wcs(&ap->name);
- *wp++ = separator;
- if (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID)
- id = ap->id;
- else
- id = -1;
- append_entry_w(&wp, NULL, ap->tag, wname,
- ap->permset, id);
- count++;
- }
- ap = ap->next;
- }
- }
-
-
- if ((flags & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0) {
- if (flags & ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT)
- prefix = L"default:";
- else
- prefix = NULL;
- ap = entry->acl_head;
- count = 0;
- while (ap != NULL) {
- if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0) {
- wname = aes_get_wcs(&ap->name);
- if (count > 0)
- *wp++ = separator;
- if (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID)
- id = ap->id;
- else
- id = -1;
- append_entry_w(&wp, prefix, ap->tag,
- wname, ap->permset, id);
- count ++;
- }
- ap = ap->next;
- }
- }
-
- return (entry->acl_text_w);
-}
-
-static void
-append_id_w(wchar_t **wp, int id)
-{
- if (id < 0)
- id = 0;
- if (id > 9)
- append_id_w(wp, id / 10);
- *(*wp)++ = L"0123456789"[id % 10];
+ return archive_acl_text_w(entry->archive, &entry->acl, flags);
}
-static void
-append_entry_w(wchar_t **wp, const wchar_t *prefix, int tag,
- const wchar_t *wname, int perm, int id)
+const char *
+archive_entry_acl_text(struct archive_entry *entry, int flags)
{
- if (prefix != NULL) {
- wcscpy(*wp, prefix);
- *wp += wcslen(*wp);
- }
- switch (tag) {
- case ARCHIVE_ENTRY_ACL_USER_OBJ:
- wname = NULL;
- id = -1;
- /* FALLTHROUGH */
- case ARCHIVE_ENTRY_ACL_USER:
- wcscpy(*wp, L"user");
- break;
- case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
- wname = NULL;
- id = -1;
- /* FALLTHROUGH */
- case ARCHIVE_ENTRY_ACL_GROUP:
- wcscpy(*wp, L"group");
- break;
- case ARCHIVE_ENTRY_ACL_MASK:
- wcscpy(*wp, L"mask");
- wname = NULL;
- id = -1;
- break;
- case ARCHIVE_ENTRY_ACL_OTHER:
- wcscpy(*wp, L"other");
- wname = NULL;
- id = -1;
- break;
- }
- *wp += wcslen(*wp);
- *(*wp)++ = L':';
- if (wname != NULL) {
- wcscpy(*wp, wname);
- *wp += wcslen(*wp);
- } else if (tag == ARCHIVE_ENTRY_ACL_USER
- || tag == ARCHIVE_ENTRY_ACL_GROUP) {
- append_id_w(wp, id);
- id = -1;
- }
- *(*wp)++ = L':';
- *(*wp)++ = (perm & 0444) ? L'r' : L'-';
- *(*wp)++ = (perm & 0222) ? L'w' : L'-';
- *(*wp)++ = (perm & 0111) ? L'x' : L'-';
- if (id != -1) {
- *(*wp)++ = L':';
- append_id_w(wp, id);
- }
- **wp = L'\0';
+ const char *p;
+ if (archive_acl_text_l(&entry->acl, flags, &p, NULL, NULL) != 0
+ && errno == ENOMEM)
+ return (NULL);
+ return (p);
}
-/*
- * Parse a textual ACL. This automatically recognizes and supports
- * extensions described above. The 'type' argument is used to
- * indicate the type that should be used for any entries not
- * explicitly marked as "default:".
- */
int
-__archive_entry_acl_parse_w(struct archive_entry *entry,
- const wchar_t *text, int default_type)
-{
- struct {
- const wchar_t *start;
- const wchar_t *end;
- } field[4], name;
-
- int fields, n;
- int type, tag, permset, id;
- wchar_t sep;
-
- while (text != NULL && *text != L'\0') {
- /*
- * Parse the fields out of the next entry,
- * advance 'text' to start of next entry.
- */
- fields = 0;
- do {
- const wchar_t *start, *end;
- next_field_w(&text, &start, &end, &sep);
- if (fields < 4) {
- field[fields].start = start;
- field[fields].end = end;
- }
- ++fields;
- } while (sep == L':');
-
- /* Set remaining fields to blank. */
- for (n = fields; n < 4; ++n)
- field[n].start = field[n].end = NULL;
-
- /* Check for a numeric ID in field 1 or 3. */
- id = -1;
- isint_w(field[1].start, field[1].end, &id);
- /* Field 3 is optional. */
- if (id == -1 && fields > 3)
- isint_w(field[3].start, field[3].end, &id);
-
- /*
- * Solaris extension: "defaultuser::rwx" is the
- * default ACL corresponding to "user::rwx", etc.
- */
- if (field[0].end - field[0].start > 7
- && wmemcmp(field[0].start, L"default", 7) == 0) {
- type = ARCHIVE_ENTRY_ACL_TYPE_DEFAULT;
- field[0].start += 7;
- } else
- type = default_type;
-
- name.start = name.end = NULL;
- if (prefix_w(field[0].start, field[0].end, L"user")) {
- if (!ismode_w(field[2].start, field[2].end, &permset))
- return (ARCHIVE_WARN);
- if (id != -1 || field[1].start < field[1].end) {
- tag = ARCHIVE_ENTRY_ACL_USER;
- name = field[1];
- } else
- tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
- } else if (prefix_w(field[0].start, field[0].end, L"group")) {
- if (!ismode_w(field[2].start, field[2].end, &permset))
- return (ARCHIVE_WARN);
- if (id != -1 || field[1].start < field[1].end) {
- tag = ARCHIVE_ENTRY_ACL_GROUP;
- name = field[1];
- } else
- tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
- } else if (prefix_w(field[0].start, field[0].end, L"other")) {
- if (fields == 2
- && field[1].start < field[1].end
- && ismode_w(field[1].start, field[1].end, &permset)) {
- /* This is Solaris-style "other:rwx" */
- } else if (fields == 3
- && field[1].start == field[1].end
- && field[2].start < field[2].end
- && ismode_w(field[2].start, field[2].end, &permset)) {
- /* This is FreeBSD-style "other::rwx" */
- } else
- return (ARCHIVE_WARN);
- tag = ARCHIVE_ENTRY_ACL_OTHER;
- } else if (prefix_w(field[0].start, field[0].end, L"mask")) {
- if (fields == 2
- && field[1].start < field[1].end
- && ismode_w(field[1].start, field[1].end, &permset)) {
- /* This is Solaris-style "mask:rwx" */
- } else if (fields == 3
- && field[1].start == field[1].end
- && field[2].start < field[2].end
- && ismode_w(field[2].start, field[2].end, &permset)) {
- /* This is FreeBSD-style "mask::rwx" */
- } else
- return (ARCHIVE_WARN);
- tag = ARCHIVE_ENTRY_ACL_MASK;
- } else
- return (ARCHIVE_WARN);
-
- /* Add entry to the internal list. */
- archive_entry_acl_add_entry_w_len(entry, type, permset,
- tag, id, name.start, name.end - name.start);
- }
- return (ARCHIVE_OK);
-}
-
-/*
- * Parse a string to a positive decimal integer. Returns true if
- * the string is non-empty and consists only of decimal digits,
- * false otherwise.
- */
-static int
-isint_w(const wchar_t *start, const wchar_t *end, int *result)
-{
- int n = 0;
- if (start >= end)
- return (0);
- while (start < end) {
- if (*start < '0' || *start > '9')
- return (0);
- if (n > (INT_MAX / 10))
- n = INT_MAX;
- else {
- n *= 10;
- n += *start - '0';
- }
- start++;
- }
- *result = n;
- return (1);
-}
-
-/*
- * Parse a string as a mode field. Returns true if
- * the string is non-empty and consists only of mode characters,
- * false otherwise.
- */
-static int
-ismode_w(const wchar_t *start, const wchar_t *end, int *permset)
+_archive_entry_acl_text_l(struct archive_entry *entry, int flags,
+ const char **acl_text, size_t *len, struct archive_string_conv *sc)
{
- const wchar_t *p;
-
- if (start >= end)
- return (0);
- p = start;
- *permset = 0;
- while (p < end) {
- switch (*p++) {
- case 'r': case 'R':
- *permset |= ARCHIVE_ENTRY_ACL_READ;
- break;
- case 'w': case 'W':
- *permset |= ARCHIVE_ENTRY_ACL_WRITE;
- break;
- case 'x': case 'X':
- *permset |= ARCHIVE_ENTRY_ACL_EXECUTE;
- break;
- case '-':
- break;
- default:
- return (0);
- }
- }
- return (1);
+ return (archive_acl_text_l(&entry->acl, flags, acl_text, len, sc));
}
/*
- * Match "[:whitespace:]*(.*)[:whitespace:]*[:,\n]". *wp is updated
- * to point to just after the separator. *start points to the first
- * character of the matched text and *end just after the last
- * character of the matched identifier. In particular *end - *start
- * is the length of the field body, not including leading or trailing
- * whitespace.
- */
-static void
-next_field_w(const wchar_t **wp, const wchar_t **start,
- const wchar_t **end, wchar_t *sep)
-{
- /* Skip leading whitespace to find start of field. */
- while (**wp == L' ' || **wp == L'\t' || **wp == L'\n') {
- (*wp)++;
- }
- *start = *wp;
-
- /* Scan for the separator. */
- while (**wp != L'\0' && **wp != L',' && **wp != L':' &&
- **wp != L'\n') {
- (*wp)++;
- }
- *sep = **wp;
-
- /* Trim trailing whitespace to locate end of field. */
- *end = *wp - 1;
- while (**end == L' ' || **end == L'\t' || **end == L'\n') {
- (*end)--;
- }
- (*end)++;
-
- /* Adjust scanner location. */
- if (**wp != L'\0')
- (*wp)++;
-}
-
-/*
- * Return true if the characters [start...end) are a prefix of 'test'.
- * This makes it easy to handle the obvious abbreviations: 'u' for 'user', etc.
- */
-static int
-prefix_w(const wchar_t *start, const wchar_t *end, const wchar_t *test)
-{
- if (start == end)
- return (0);
-
- if (*start++ != *test++)
- return (0);
-
- while (start < end && *start++ == *test++)
- ;
-
- if (start < end)
- return (0);
-
- return (1);
-}
-
-
-/*
* Following code is modified from UC Berkeley sources, and
* is subject to the following copyright notice.
*/
diff --git a/libarchive/archive_entry.h b/libarchive/archive_entry.h
index d5728179eb7d..7a1e389eb061 100644
--- a/libarchive/archive_entry.h
+++ b/libarchive/archive_entry.h
@@ -28,6 +28,9 @@
#ifndef ARCHIVE_ENTRY_H_INCLUDED
#define ARCHIVE_ENTRY_H_INCLUDED
+/* Note: Compiler will complain if this does not match archive.h! */
+#define ARCHIVE_VERSION_NUMBER 3000003
+
/*
* Note: archive_entry.h is for use outside of libarchive; the
* configuration headers (config.h, archive_platform.h, etc.) are
@@ -49,30 +52,31 @@
#if defined(_WIN32) && !defined(__CYGWIN__)
#define __LA_INT64_T __int64
# if defined(__BORLANDC__)
-# define __LA_UID_T uid_t
-# define __LA_GID_T gid_t
+# define __LA_UID_T uid_t /* Remove in libarchive 3.2 */
+# define __LA_GID_T gid_t /* Remove in libarchive 3.2 */
# define __LA_DEV_T dev_t
# define __LA_MODE_T mode_t
# else
-# define __LA_UID_T short
-# define __LA_GID_T short
+# define __LA_UID_T short /* Remove in libarchive 3.2 */
+# define __LA_GID_T short /* Remove in libarchive 3.2 */
# define __LA_DEV_T unsigned int
# define __LA_MODE_T unsigned short
# endif
#else
#include <unistd.h>
-#define __LA_INT64_T int64_t
-#define __LA_UID_T uid_t
-#define __LA_GID_T gid_t
-#define __LA_DEV_T dev_t
-#define __LA_MODE_T mode_t
+# if defined(_SCO_DS)
+# define __LA_INT64_T long long
+# else
+# define __LA_INT64_T int64_t
+# endif
+# define __LA_UID_T uid_t /* Remove in libarchive 3.2 */
+# define __LA_GID_T gid_t /* Remove in libarchive 3.2 */
+# define __LA_DEV_T dev_t
+# define __LA_MODE_T mode_t
#endif
/*
- * XXX Is this defined for all Windows compilers? If so, in what
- * header? It would be nice to remove the __LA_INO_T indirection and
- * just use plain ino_t everywhere. Likewise for the other types just
- * above.
+ * Remove this for libarchive 3.2, since ino_t is no longer used.
*/
#define __LA_INO_T ino_t
@@ -91,7 +95,7 @@
# endif
# else
# ifdef __GNUC__
-# define __LA_DECL __attribute__((dllimport)) extern
+# define __LA_DECL
# else
# define __LA_DECL __declspec(dllimport)
# endif
@@ -121,6 +125,7 @@ extern "C" {
* applications (e.g., a package manager could attach special
* package-management attributes to each entry).
*/
+struct archive;
struct archive_entry;
/*
@@ -164,6 +169,15 @@ __LA_DECL void archive_entry_free(struct archive_entry *);
__LA_DECL struct archive_entry *archive_entry_new(void);
/*
+ * This form of archive_entry_new2() will pull character-set
+ * conversion information from the specified archive handle. The
+ * older archive_entry_new(void) form is equivalent to calling
+ * archive_entry_new2(NULL) and will result in the use of an internal
+ * default character-set conversion.
+ */
+__LA_DECL struct archive_entry *archive_entry_new2(struct archive *);
+
+/*
* Retrieve fields from an archive_entry.
*
* There are a number of implicit conversions among these fields. For
@@ -192,6 +206,7 @@ __LA_DECL time_t archive_entry_ctime(struct archive_entry *);
__LA_DECL long archive_entry_ctime_nsec(struct archive_entry *);
__LA_DECL int archive_entry_ctime_is_set(struct archive_entry *);
__LA_DECL dev_t archive_entry_dev(struct archive_entry *);
+__LA_DECL int archive_entry_dev_is_set(struct archive_entry *);
__LA_DECL dev_t archive_entry_devmajor(struct archive_entry *);
__LA_DECL dev_t archive_entry_devminor(struct archive_entry *);
__LA_DECL __LA_MODE_T archive_entry_filetype(struct archive_entry *);
@@ -199,13 +214,14 @@ __LA_DECL void archive_entry_fflags(struct archive_entry *,
unsigned long * /* set */,
unsigned long * /* clear */);
__LA_DECL const char *archive_entry_fflags_text(struct archive_entry *);
-__LA_DECL __LA_GID_T archive_entry_gid(struct archive_entry *);
+__LA_DECL __LA_INT64_T archive_entry_gid(struct archive_entry *);
__LA_DECL const char *archive_entry_gname(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_gname_w(struct archive_entry *);
__LA_DECL const char *archive_entry_hardlink(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_hardlink_w(struct archive_entry *);
-__LA_DECL __LA_INO_T archive_entry_ino(struct archive_entry *);
+__LA_DECL __LA_INT64_T archive_entry_ino(struct archive_entry *);
__LA_DECL __LA_INT64_T archive_entry_ino64(struct archive_entry *);
+__LA_DECL int archive_entry_ino_is_set(struct archive_entry *);
__LA_DECL __LA_MODE_T archive_entry_mode(struct archive_entry *);
__LA_DECL time_t archive_entry_mtime(struct archive_entry *);
__LA_DECL long archive_entry_mtime_nsec(struct archive_entry *);
@@ -213,35 +229,34 @@ __LA_DECL int archive_entry_mtime_is_set(struct archive_entry *);
__LA_DECL unsigned int archive_entry_nlink(struct archive_entry *);
__LA_DECL const char *archive_entry_pathname(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_pathname_w(struct archive_entry *);
+__LA_DECL __LA_MODE_T archive_entry_perm(struct archive_entry *);
__LA_DECL dev_t archive_entry_rdev(struct archive_entry *);
__LA_DECL dev_t archive_entry_rdevmajor(struct archive_entry *);
__LA_DECL dev_t archive_entry_rdevminor(struct archive_entry *);
__LA_DECL const char *archive_entry_sourcepath(struct archive_entry *);
+__LA_DECL const wchar_t *archive_entry_sourcepath_w(struct archive_entry *);
__LA_DECL __LA_INT64_T archive_entry_size(struct archive_entry *);
__LA_DECL int archive_entry_size_is_set(struct archive_entry *);
__LA_DECL const char *archive_entry_strmode(struct archive_entry *);
__LA_DECL const char *archive_entry_symlink(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_symlink_w(struct archive_entry *);
-__LA_DECL __LA_UID_T archive_entry_uid(struct archive_entry *);
+__LA_DECL __LA_INT64_T archive_entry_uid(struct archive_entry *);
__LA_DECL const char *archive_entry_uname(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_uname_w(struct archive_entry *);
/*
* Set fields in an archive_entry.
*
- * Note that string 'set' functions do not copy the string, only the pointer.
- * In contrast, 'copy' functions do copy the object pointed to.
- *
- * Note: As of libarchive 2.4, 'set' functions do copy the string and
- * are therefore exact synonyms for the 'copy' versions. The 'copy'
- * names will be retired in libarchive 3.0.
+ * Note: Before libarchive 2.4, there were 'set' and 'copy' versions
+ * of the string setters. 'copy' copied the actual string, 'set' just
+ * stored the pointer. In libarchive 2.4 and later, strings are
+ * always copied.
*/
__LA_DECL void archive_entry_set_atime(struct archive_entry *, time_t, long);
__LA_DECL void archive_entry_unset_atime(struct archive_entry *);
#if defined(_WIN32) && !defined(__CYGWIN__)
-__LA_DECL void archive_entry_copy_bhfi(struct archive_entry *,
- BY_HANDLE_FILE_INFORMATION *);
+__LA_DECL void archive_entry_copy_bhfi(struct archive_entry *, BY_HANDLE_FILE_INFORMATION *);
#endif
__LA_DECL void archive_entry_set_birthtime(struct archive_entry *, time_t, long);
__LA_DECL void archive_entry_unset_birthtime(struct archive_entry *);
@@ -259,7 +274,7 @@ __LA_DECL const char *archive_entry_copy_fflags_text(struct archive_entry *,
const char *);
__LA_DECL const wchar_t *archive_entry_copy_fflags_text_w(struct archive_entry *,
const wchar_t *);
-__LA_DECL void archive_entry_set_gid(struct archive_entry *, __LA_GID_T);
+__LA_DECL void archive_entry_set_gid(struct archive_entry *, __LA_INT64_T);
__LA_DECL void archive_entry_set_gname(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_gname(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_gname_w(struct archive_entry *, const wchar_t *);
@@ -268,12 +283,7 @@ __LA_DECL void archive_entry_set_hardlink(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_hardlink(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_hardlink_w(struct archive_entry *, const wchar_t *);
__LA_DECL int archive_entry_update_hardlink_utf8(struct archive_entry *, const char *);
-#if ARCHIVE_VERSION_NUMBER >= 3000000
-/* Starting with libarchive 3.0, this will be synonym for ino64. */
__LA_DECL void archive_entry_set_ino(struct archive_entry *, __LA_INT64_T);
-#else
-__LA_DECL void archive_entry_set_ino(struct archive_entry *, unsigned long);
-#endif
__LA_DECL void archive_entry_set_ino64(struct archive_entry *, __LA_INT64_T);
__LA_DECL void archive_entry_set_link(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_link(struct archive_entry *, const char *);
@@ -294,11 +304,12 @@ __LA_DECL void archive_entry_set_rdevminor(struct archive_entry *, dev_t);
__LA_DECL void archive_entry_set_size(struct archive_entry *, __LA_INT64_T);
__LA_DECL void archive_entry_unset_size(struct archive_entry *);
__LA_DECL void archive_entry_copy_sourcepath(struct archive_entry *, const char *);
+__LA_DECL void archive_entry_copy_sourcepath_w(struct archive_entry *, const wchar_t *);
__LA_DECL void archive_entry_set_symlink(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_symlink(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_symlink_w(struct archive_entry *, const wchar_t *);
__LA_DECL int archive_entry_update_symlink_utf8(struct archive_entry *, const char *);
-__LA_DECL void archive_entry_set_uid(struct archive_entry *, __LA_UID_T);
+__LA_DECL void archive_entry_set_uid(struct archive_entry *, __LA_INT64_T);
__LA_DECL void archive_entry_set_uname(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_uname(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_uname_w(struct archive_entry *, const wchar_t *);
@@ -315,6 +326,15 @@ __LA_DECL int archive_entry_update_uname_utf8(struct archive_entry *, const char
__LA_DECL const struct stat *archive_entry_stat(struct archive_entry *);
__LA_DECL void archive_entry_copy_stat(struct archive_entry *, const struct stat *);
+/*
+ * Storage for Mac OS-specific AppleDouble metadata information.
+ * Apple-format tar files store a separate binary blob containing
+ * encoded metadata with ACL, extended attributes, etc.
+ * This provides a place to store that blob.
+ */
+
+__LA_DECL const void * archive_entry_mac_metadata(struct archive_entry *, size_t *);
+__LA_DECL void archive_entry_copy_mac_metadata(struct archive_entry *, const void *, size_t);
/*
* ACL routines. This used to simply store and return text-format ACL
@@ -326,32 +346,95 @@ __LA_DECL void archive_entry_copy_stat(struct archive_entry *, const struct stat
*
* This last point, in particular, forces me to implement a reasonably
* complete set of ACL support routines.
- *
- * TODO: Extend this to support NFSv4/NTFS permissions. That should
- * allow full ACL support on Mac OS, in particular, which uses
- * POSIX.1e-style interfaces to manipulate NFSv4/NTFS permissions.
*/
/*
- * Permission bits mimic POSIX.1e. Note that I've not followed POSIX.1e's
- * "permset"/"perm" abstract type nonsense. A permset is just a simple
- * bitmap, following long-standing Unix tradition.
+ * Permission bits.
*/
-#define ARCHIVE_ENTRY_ACL_EXECUTE 1
-#define ARCHIVE_ENTRY_ACL_WRITE 2
-#define ARCHIVE_ENTRY_ACL_READ 4
+#define ARCHIVE_ENTRY_ACL_EXECUTE 0x00000001
+#define ARCHIVE_ENTRY_ACL_WRITE 0x00000002
+#define ARCHIVE_ENTRY_ACL_READ 0x00000004
+#define ARCHIVE_ENTRY_ACL_READ_DATA 0x00000008
+#define ARCHIVE_ENTRY_ACL_LIST_DIRECTORY 0x00000008
+#define ARCHIVE_ENTRY_ACL_WRITE_DATA 0x00000010
+#define ARCHIVE_ENTRY_ACL_ADD_FILE 0x00000010
+#define ARCHIVE_ENTRY_ACL_APPEND_DATA 0x00000020
+#define ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY 0x00000020
+#define ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS 0x00000040
+#define ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS 0x00000080
+#define ARCHIVE_ENTRY_ACL_DELETE_CHILD 0x00000100
+#define ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES 0x00000200
+#define ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES 0x00000400
+#define ARCHIVE_ENTRY_ACL_DELETE 0x00000800
+#define ARCHIVE_ENTRY_ACL_READ_ACL 0x00001000
+#define ARCHIVE_ENTRY_ACL_WRITE_ACL 0x00002000
+#define ARCHIVE_ENTRY_ACL_WRITE_OWNER 0x00004000
+#define ARCHIVE_ENTRY_ACL_SYNCHRONIZE 0x00008000
+
+#define ARCHIVE_ENTRY_ACL_PERMS_POSIX1E \
+ (ARCHIVE_ENTRY_ACL_EXECUTE \
+ | ARCHIVE_ENTRY_ACL_WRITE \
+ | ARCHIVE_ENTRY_ACL_READ)
+
+#define ARCHIVE_ENTRY_ACL_PERMS_NFS4 \
+ (ARCHIVE_ENTRY_ACL_EXECUTE \
+ | ARCHIVE_ENTRY_ACL_READ_DATA \
+ | ARCHIVE_ENTRY_ACL_LIST_DIRECTORY \
+ | ARCHIVE_ENTRY_ACL_WRITE_DATA \
+ | ARCHIVE_ENTRY_ACL_ADD_FILE \
+ | ARCHIVE_ENTRY_ACL_APPEND_DATA \
+ | ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY \
+ | ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS \
+ | ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS \
+ | ARCHIVE_ENTRY_ACL_DELETE_CHILD \
+ | ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES \
+ | ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES \
+ | ARCHIVE_ENTRY_ACL_DELETE \
+ | ARCHIVE_ENTRY_ACL_READ_ACL \
+ | ARCHIVE_ENTRY_ACL_WRITE_ACL \
+ | ARCHIVE_ENTRY_ACL_WRITE_OWNER \
+ | ARCHIVE_ENTRY_ACL_SYNCHRONIZE)
-/* We need to be able to specify either or both of these. */
-#define ARCHIVE_ENTRY_ACL_TYPE_ACCESS 256
-#define ARCHIVE_ENTRY_ACL_TYPE_DEFAULT 512
+/*
+ * Inheritance values (NFS4 ACLs only); included in permset.
+ */
+#define ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT 0x02000000
+#define ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT 0x04000000
+#define ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT 0x08000000
+#define ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY 0x10000000
+#define ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS 0x20000000
+#define ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS 0x40000000
+
+#define ARCHIVE_ENTRY_ACL_INHERITANCE_NFS4 \
+ (ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT \
+ | ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT \
+ | ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT \
+ | ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY \
+ | ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS \
+ | ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS)
+
+/* We need to be able to specify combinations of these. */
+#define ARCHIVE_ENTRY_ACL_TYPE_ACCESS 256 /* POSIX.1e only */
+#define ARCHIVE_ENTRY_ACL_TYPE_DEFAULT 512 /* POSIX.1e only */
+#define ARCHIVE_ENTRY_ACL_TYPE_ALLOW 1024 /* NFS4 only */
+#define ARCHIVE_ENTRY_ACL_TYPE_DENY 2048 /* NFS4 only */
+#define ARCHIVE_ENTRY_ACL_TYPE_AUDIT 4096 /* NFS4 only */
+#define ARCHIVE_ENTRY_ACL_TYPE_ALARM 8192 /* NFS4 only */
+#define ARCHIVE_ENTRY_ACL_TYPE_POSIX1E (ARCHIVE_ENTRY_ACL_TYPE_ACCESS \
+ | ARCHIVE_ENTRY_ACL_TYPE_DEFAULT)
+#define ARCHIVE_ENTRY_ACL_TYPE_NFS4 (ARCHIVE_ENTRY_ACL_TYPE_ALLOW \
+ | ARCHIVE_ENTRY_ACL_TYPE_DENY \
+ | ARCHIVE_ENTRY_ACL_TYPE_AUDIT \
+ | ARCHIVE_ENTRY_ACL_TYPE_ALARM)
/* Tag values mimic POSIX.1e */
#define ARCHIVE_ENTRY_ACL_USER 10001 /* Specified user. */
#define ARCHIVE_ENTRY_ACL_USER_OBJ 10002 /* User who owns the file. */
#define ARCHIVE_ENTRY_ACL_GROUP 10003 /* Specified group. */
#define ARCHIVE_ENTRY_ACL_GROUP_OBJ 10004 /* Group who owns the file. */
-#define ARCHIVE_ENTRY_ACL_MASK 10005 /* Modify group access. */
-#define ARCHIVE_ENTRY_ACL_OTHER 10006 /* Public. */
+#define ARCHIVE_ENTRY_ACL_MASK 10005 /* Modify group access (POSIX.1e only) */
+#define ARCHIVE_ENTRY_ACL_OTHER 10006 /* Public (POSIX.1e only) */
+#define ARCHIVE_ENTRY_ACL_EVERYONE 10107 /* Everyone (NFS4 only) */
/*
* Set the ACL by clearing it and adding entries one at a time.
@@ -363,17 +446,17 @@ __LA_DECL void archive_entry_copy_stat(struct archive_entry *, const struct stat
* default and access information in a single ACL list.
*/
__LA_DECL void archive_entry_acl_clear(struct archive_entry *);
-__LA_DECL void archive_entry_acl_add_entry(struct archive_entry *,
+__LA_DECL int archive_entry_acl_add_entry(struct archive_entry *,
int /* type */, int /* permset */, int /* tag */,
int /* qual */, const char * /* name */);
-__LA_DECL void archive_entry_acl_add_entry_w(struct archive_entry *,
+__LA_DECL int archive_entry_acl_add_entry_w(struct archive_entry *,
int /* type */, int /* permset */, int /* tag */,
int /* qual */, const wchar_t * /* name */);
/*
* To retrieve the ACL, first "reset", then repeatedly ask for the
* "next" entry. The want_type parameter allows you to request only
- * access entries or only default entries.
+ * certain types of entries.
*/
__LA_DECL int archive_entry_acl_reset(struct archive_entry *, int /* want_type */);
__LA_DECL int archive_entry_acl_next(struct archive_entry *, int /* want_type */,
@@ -387,36 +470,29 @@ __LA_DECL int archive_entry_acl_next_w(struct archive_entry *, int /* want_type
* Construct a text-format ACL. The flags argument is a bitmask that
* can include any of the following:
*
- * ARCHIVE_ENTRY_ACL_TYPE_ACCESS - Include access entries.
- * ARCHIVE_ENTRY_ACL_TYPE_DEFAULT - Include default entries.
+ * ARCHIVE_ENTRY_ACL_TYPE_ACCESS - Include POSIX.1e "access" entries.
+ * ARCHIVE_ENTRY_ACL_TYPE_DEFAULT - Include POSIX.1e "default" entries.
+ * ARCHIVE_ENTRY_ACL_TYPE_NFS4 - Include NFS4 entries.
* ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID - Include extra numeric ID field in
- * each ACL entry. (As used by 'star'.)
+ * each ACL entry. ('star' introduced this for POSIX.1e, this flag
+ * also applies to NFS4.)
* ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT - Include "default:" before each
- * default ACL entry.
+ * default ACL entry, as used in old Solaris ACLs.
*/
#define ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID 1024
#define ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT 2048
__LA_DECL const wchar_t *archive_entry_acl_text_w(struct archive_entry *,
int /* flags */);
+__LA_DECL const char *archive_entry_acl_text(struct archive_entry *,
+ int /* flags */);
/* Return a count of entries matching 'want_type' */
__LA_DECL int archive_entry_acl_count(struct archive_entry *, int /* want_type */);
-/*
- * Private ACL parser. This is private because it handles some
- * very weird formats that clients should not be messing with.
- * Clients should only deal with their platform-native formats.
- * Because of the need to support many formats cleanly, new arguments
- * are likely to get added on a regular basis. Clients who try to use
- * this interface are likely to be surprised when it changes.
- *
- * You were warned!
- *
- * TODO: Move this declaration out of the public header and into
- * a private header. Warnings above are silly.
- */
-__LA_DECL int __archive_entry_acl_parse_w(struct archive_entry *,
- const wchar_t *, int /* type */);
+/* Return an opaque ACL object. */
+/* There's not yet anything clients can actually do with this... */
+struct archive_acl;
+__LA_DECL struct archive_acl *archive_entry_acl(struct archive_entry *);
/*
* extended attributes
@@ -438,6 +514,24 @@ __LA_DECL int archive_entry_xattr_next(struct archive_entry *,
const char ** /* name */, const void ** /* value */, size_t *);
/*
+ * sparse
+ */
+
+__LA_DECL void archive_entry_sparse_clear(struct archive_entry *);
+__LA_DECL void archive_entry_sparse_add_entry(struct archive_entry *,
+ __LA_INT64_T /* offset */, __LA_INT64_T /* length */);
+
+/*
+ * To retrieve the xattr list, first "reset", then repeatedly ask for the
+ * "next" entry.
+ */
+
+__LA_DECL int archive_entry_sparse_count(struct archive_entry *);
+__LA_DECL int archive_entry_sparse_reset(struct archive_entry *);
+__LA_DECL int archive_entry_sparse_next(struct archive_entry *,
+ __LA_INT64_T * /* offset */, __LA_INT64_T * /* length */);
+
+/*
* Utility to match up hardlinks.
*
* The 'struct archive_entry_linkresolver' is a cache of archive entries
@@ -449,7 +543,7 @@ __LA_DECL int archive_entry_xattr_next(struct archive_entry *,
* be written.
* 4. Call archive_entry_linkify(resolver, NULL) until
* no more entries are returned.
- * 5. Call archive_entry_link_resolver_free(resolver) to free resources.
+ * 5. Call archive_entry_linkresolver_free(resolver) to free resources.
*
* The entries returned have their hardlink and size fields updated
* appropriately. If an entry is passed in that does not refer to
@@ -499,7 +593,7 @@ struct archive_entry_linkresolver;
* linkify(l2) => l1
* linkify(NULL) => l2 (at end, you retrieve remaining links)
* As the name suggests, this strategy is used by newer cpio variants.
- * It's noticably more complex for the archiver, slightly more complex
+ * It's noticeably more complex for the archiver, slightly more complex
* for the dearchiver than the tar strategy, but makes it straightforward
* to restore a file using any link by simply continuing to scan until
* you see a link that is stored with a body. In contrast, the tar
@@ -513,6 +607,8 @@ __LA_DECL void archive_entry_linkresolver_set_strategy(
__LA_DECL void archive_entry_linkresolver_free(struct archive_entry_linkresolver *);
__LA_DECL void archive_entry_linkify(struct archive_entry_linkresolver *,
struct archive_entry **, struct archive_entry **);
+__LA_DECL struct archive_entry *archive_entry_partial_links(
+ struct archive_entry_linkresolver *res, unsigned int *links);
#ifdef __cplusplus
}
diff --git a/libarchive/archive_entry_acl.3 b/libarchive/archive_entry_acl.3
new file mode 100644
index 000000000000..8c4f0cd64ef1
--- /dev/null
+++ b/libarchive/archive_entry_acl.3
@@ -0,0 +1,233 @@
+.\" Copyright (c) 2010 Joerg Sonnenberger
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd February 21, 2010
+.Dt ARCHIVE_ENTRY_ACL 3
+.Os
+.Sh NAME
+.Nm archive_entry_acl_add_entry ,
+.Nm archive_entry_acl_add_entry_w ,
+.Nm archive_entry_acl_clear ,
+.Nm archive_entry_acl_count ,
+.Nm archive_entry_acl_next ,
+.Nm archive_entry_acl_next_w ,
+.Nm archive_entry_acl_reset ,
+.Nm archive_entry_acl_text_w
+.Nd functions for manipulating Access Control Lists in archive entry descriptions
+.Sh SYNOPSIS
+.In archive_entry.h
+.Ft void
+.Fo archive_entry_acl_add_entry
+.Fa "struct archive_entry *a"
+.Fa "int type"
+.Fa "int permset"
+.Fa "int tag"
+.Fa "int qualifier"
+.Fa "const char *name"
+.Fc
+.Ft void
+.Fo archive_entry_acl_add_entry_w
+.Fa "struct archive_entry *a"
+.Fa "int type"
+.Fa "int permset"
+.Fa "int tag"
+.Fa "int qualifier"
+.Fa "const wchar_t *name"
+.Fc
+.Ft void
+.Fn archive_entry_acl_clear "struct archive_entry *a"
+.Ft int
+.Fn archive_entry_acl_count "struct archive_entry *a" "int type"
+.Ft int
+.Fo archive_entry_acl_next
+.Fa "struct archive_entry *a"
+.Fa "int type"
+.Fa "int *ret_type"
+.Fa "int *ret_permset"
+.Fa "int *ret_tag"
+.Fa "int *ret_qual"
+.Fa "const char **ret_name"
+.Fc
+.Ft int
+.Fo archive_entry_acl_next_w
+.Fa "struct archive_entry *a"
+.Fa "int type"
+.Fa "int *ret_type"
+.Fa "int *ret_permset"
+.Fa "int *ret_tag"
+.Fa "int *ret_qual"
+.Fa "const wchar_t **ret_name"
+.Fc
+.Ft int
+.Fn archive_entry_acl_reset "struct archive_entry *a" "int type"
+.Ft const wchar_t *
+.Fn archive_entry_acl_text_w "struct archive_entry *a" "int flags"
+.\" enum?
+.Sh DESCRIPTION
+An
+.Dq Access Control List
+is a generalisation of the classic Unix permission system.
+The ACL interface of
+.Nm libarchive
+is derived from the POSIX.1e draft, but restricted to simplify dealing
+with practical implementations in various Operating Systems and archive formats.
+.Pp
+An ACL consists of a number of independent entries.
+Each entry specifies the permission set as bitmask of basic permissions.
+Valid permissions are:
+.Bl -tag -offset indent -compact -width "ARCHIVE_ENTRY_ACL_EXECUTE"
+.It Dv ARCHIVE_ENTRY_ACL_EXECUTE
+.It Dv ARCHIVE_ENTRY_ACL_WRITE
+.It Dv ARCHIVE_ENTRY_ACL_READ
+.El
+The permissions correspond to the normal Unix permissions.
+.Pp
+The tag specifies the principal to which the permission applies.
+Valid values are:
+.Bl -tag -offset indent -compact -width "ARCHIVE_ENTRY_ACL_GROUP_OBJ"
+.It Dv ARCHIVE_ENTRY_ACL_USER
+The user specified by the name field.
+.It Dv ARCHIVE_ENTRY_ACL_USER_OBJ
+The owner of the file.
+.It Dv ARCHIVE_ENTRY_ACL_GROUP
+The group specied by the name field.
+.It Dv ARCHIVE_ENTRY_ACL_GROUP_OBJ
+The group who owns the file.
+.It Dv ARCHIVE_ENTRY_ACL_MASK
+The maximum permissions to be obtained via group permissions.
+.It Dv ARCHIVE_ENTRY_ACL_OTHER
+Any principal who doesn't have a user or group entry.
+.El
+The principals
+.Dv ARCHIVE_ENTRY_ACL_USER_OBJ ,
+.Dv ARCHIVE_ENTRY_ACL_GROUP_OBJ
+and
+.Dv ARCHIVE_ENTRY_ACL_OTHER
+are equivalent to user, group and other in the classic Unix permission
+model and specify non-extended ACL entries.
+.Pp
+All files have an access ACL
+.Pq Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS .
+This specifies the permissions required for access to the file itself.
+Directories have an additional ACL
+.Pq Dv ARCHIVE_ENTRY_ACL_TYPE_DEFAULT ,
+which controls the initial access ACL for newly created directory entries.
+.Pp
+.Fn archive_entry_acl_add_entry
+and
+.Fn archive_entry_acl_add_entry_w
+add a single ACL entry.
+For the access ACL and non-extended principals, the classic Unix permissions
+are updated.
+.Pp
+.Fn archive_entry_acl_clear
+removes all ACL entries and resets the enumeration pointer.
+.Pp
+.Fn archive_entry_acl_count
+counts the ACL entries that have the given type mask.
+.Fa type
+can be the bitwise-or of
+.Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS
+and
+.Dv ARCHIVE_ENTRY_ACL_TYPE_DEFAULT .
+If
+.Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS
+is included and at least one extended ACL entry is found,
+the three non-extened ACLs are added.
+.Pp
+.Fn archive_entry_acl_next
+and
+.Fn archive_entry_acl_next_w
+return the next entry of the ACL list.
+This functions may only be called after
+.Fn archive_entry_acl_reset
+has indicated the presence of extended ACL entries.
+.Pp
+.Fn archive_entry_acl_reset
+prepare reading the list of ACL entries with
+.Fn archive_entry_acl_next
+or
+.Fn archive_entry_acl_next_w .
+The function returns either 0, if no non-extended ACLs are found.
+In this case, the access permissions should be obtained by
+.Xr archive_entry_mode 3
+or set using
+.Xr chmod 2 .
+Otherwise, the function returns the same value as
+.Fn archive_entry_acl_count .
+.Pp
+.Fn archive_entry_acl_text_w
+converts the ACL entries for the given type mask into a wide string.
+In addition to the normal type flags,
+.Dv ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID
+and
+.Dv ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT
+can be specified to further customize the result.
+The returned long string is valid until the next call to
+.Fn archive_entry_acl_clear ,
+.Fn archive_entry_acl_add_entry ,
+.Fn archive_entry_acl_add_entry_w
+or
+.Fn archive_entry_acl_text_w .
+.Sh RETURN VALUES
+.Fn archive_entry_acl_count
+and
+.Fn archive_entry_acl_reset
+returns the number of ACL entries that match the given type mask.
+If the type mask includes
+.Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS
+and at least one extended ACL entry exists, the three classic Unix
+permissions are counted.
+.Pp
+.Fn archive_entry_acl_next
+and
+.Fn archive_entry_acl_next_w
+return
+.Dv ARCHIVE_OK
+on success,
+.Dv ARCHIVE_EOF
+if no more ACL entries exist
+and
+.Dv ARCHIVE_WARN
+if
+.Fn archive_entry_acl_reset
+has not been called first.
+.Pp
+.Fn archive_entry_text_w
+returns a wide string representation of the ACL entrise matching the
+given type mask.
+The returned long string is valid until the next call to
+.Fn archive_entry_acl_clear ,
+.Fn archive_entry_acl_add_entry ,
+.Fn archive_entry_acl_add_entry_w
+or
+.Fn archive_entry_acl_text_w .
+.Sh SEE ALSO
+.Xr archive 3 ,
+.Xr archive_entry 3
+.Sh BUGS
+.Dv ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID
+and
+.Dv ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT
+are not documented.
diff --git a/libarchive/archive_entry_copy_bhfi.c b/libarchive/archive_entry_copy_bhfi.c
index 8339032c5c35..7a4bc9cd0526 100644
--- a/libarchive/archive_entry_copy_bhfi.c
+++ b/libarchive/archive_entry_copy_bhfi.c
@@ -63,12 +63,13 @@ archive_entry_copy_bhfi(struct archive_entry *entry,
archive_entry_set_mtime(entry, secs, nsecs);
fileTimeToUtc(&bhfi->ftCreationTime, &secs, &nsecs);
archive_entry_set_birthtime(entry, secs, nsecs);
+ archive_entry_set_ctime(entry, secs, nsecs);
archive_entry_set_dev(entry, bhfi->dwVolumeSerialNumber);
archive_entry_set_ino64(entry, (((int64_t)bhfi->nFileIndexHigh) << 32)
+ bhfi->nFileIndexLow);
archive_entry_set_nlink(entry, bhfi->nNumberOfLinks);
archive_entry_set_size(entry, (((int64_t)bhfi->nFileSizeHigh) << 32)
+ bhfi->nFileSizeLow);
-// archive_entry_set_mode(entry, st->st_mode);
+ /* archive_entry_set_mode(entry, st->st_mode); */
}
#endif
diff --git a/libarchive/archive_entry_copy_stat.c b/libarchive/archive_entry_copy_stat.c
index ef59a5e78a04..37d4d6edbd86 100644
--- a/libarchive/archive_entry_copy_stat.c
+++ b/libarchive/archive_entry_copy_stat.c
@@ -30,6 +30,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_entry_copy_stat.c 189466 2009-03
#include <sys/stat.h>
#endif
+#include "archive.h"
#include "archive_entry.h"
void
@@ -59,12 +60,13 @@ archive_entry_copy_stat(struct archive_entry *entry, const struct stat *st)
archive_entry_set_atime(entry, st->st_atime, 0);
archive_entry_set_ctime(entry, st->st_ctime, 0);
archive_entry_set_mtime(entry, st->st_mtime, 0);
-#if HAVE_STRUCT_STAT_ST_BIRTHTIME
- archive_entry_set_birthtime(entry, st->st_birthtime, 0);
-#endif
#endif
#if HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC
archive_entry_set_birthtime(entry, st->st_birthtime, st->st_birthtimespec.tv_nsec);
+#elif HAVE_STRUCT_STAT_ST_BIRTHTIME
+ archive_entry_set_birthtime(entry, st->st_birthtime, 0);
+#else
+ archive_entry_unset_birthtime(entry);
#endif
archive_entry_set_dev(entry, st->st_dev);
archive_entry_set_gid(entry, st->st_gid);
diff --git a/libarchive/archive_entry_link_resolver.c b/libarchive/archive_entry_link_resolver.c
index 3b13e19c8bf7..a18144dd5c01 100644
--- a/libarchive/archive_entry_link_resolver.c
+++ b/libarchive/archive_entry_link_resolver.c
@@ -70,10 +70,10 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_entry_link_resolver.c 201100 200
struct links_entry {
struct links_entry *next;
struct links_entry *previous;
- int links; /* # links not yet seen */
- int hash;
struct archive_entry *canonical;
struct archive_entry *entry;
+ size_t hash;
+ unsigned int links; /* # links not yet seen */
};
struct archive_entry_linkresolver {
@@ -84,32 +84,37 @@ struct archive_entry_linkresolver {
int strategy;
};
+#define NEXT_ENTRY_DEFERRED 1
+#define NEXT_ENTRY_PARTIAL 2
+#define NEXT_ENTRY_ALL (NEXT_ENTRY_DEFERRED | NEXT_ENTRY_PARTIAL)
+
static struct links_entry *find_entry(struct archive_entry_linkresolver *,
struct archive_entry *);
static void grow_hash(struct archive_entry_linkresolver *);
static struct links_entry *insert_entry(struct archive_entry_linkresolver *,
struct archive_entry *);
-static struct links_entry *next_entry(struct archive_entry_linkresolver *);
+static struct links_entry *next_entry(struct archive_entry_linkresolver *,
+ int);
struct archive_entry_linkresolver *
archive_entry_linkresolver_new(void)
{
struct archive_entry_linkresolver *res;
- size_t i;
- res = malloc(sizeof(struct archive_entry_linkresolver));
+ /* Check for positive power-of-two */
+ if (links_cache_initial_size == 0 ||
+ (links_cache_initial_size & (links_cache_initial_size - 1)) != 0)
+ return (NULL);
+
+ res = calloc(1, sizeof(struct archive_entry_linkresolver));
if (res == NULL)
return (NULL);
- memset(res, 0, sizeof(struct archive_entry_linkresolver));
res->number_buckets = links_cache_initial_size;
- res->buckets = malloc(res->number_buckets *
- sizeof(res->buckets[0]));
+ res->buckets = calloc(res->number_buckets, sizeof(res->buckets[0]));
if (res->buckets == NULL) {
free(res);
return (NULL);
}
- for (i = 0; i < res->number_buckets; i++)
- res->buckets[i] = NULL;
return (res);
}
@@ -120,6 +125,11 @@ archive_entry_linkresolver_set_strategy(struct archive_entry_linkresolver *res,
int fmtbase = fmt & ARCHIVE_FORMAT_BASE_MASK;
switch (fmtbase) {
+ case ARCHIVE_FORMAT_7ZIP:
+ case ARCHIVE_FORMAT_AR:
+ case ARCHIVE_FORMAT_ZIP:
+ res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_OLD_CPIO;
+ break;
case ARCHIVE_FORMAT_CPIO:
switch (fmt) {
case ARCHIVE_FORMAT_CPIO_SVR4_NOCRC:
@@ -134,11 +144,14 @@ archive_entry_linkresolver_set_strategy(struct archive_entry_linkresolver *res,
case ARCHIVE_FORMAT_MTREE:
res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_MTREE;
break;
+ case ARCHIVE_FORMAT_ISO9660:
+ case ARCHIVE_FORMAT_SHAR:
case ARCHIVE_FORMAT_TAR:
+ case ARCHIVE_FORMAT_XAR:
res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_TAR;
break;
default:
- res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_TAR;
+ res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_OLD_CPIO;
break;
}
}
@@ -151,12 +164,9 @@ archive_entry_linkresolver_free(struct archive_entry_linkresolver *res)
if (res == NULL)
return;
- if (res->buckets != NULL) {
- while ((le = next_entry(res)) != NULL)
- archive_entry_free(le->entry);
- free(res->buckets);
- res->buckets = NULL;
- }
+ while ((le = next_entry(res, NEXT_ENTRY_ALL)) != NULL)
+ archive_entry_free(le->entry);
+ free(res->buckets);
free(res);
}
@@ -170,7 +180,7 @@ archive_entry_linkify(struct archive_entry_linkresolver *res,
*f = NULL; /* Default: Don't return a second entry. */
if (*e == NULL) {
- le = next_entry(res);
+ le = next_entry(res, NEXT_ENTRY_DEFERRED);
if (le != NULL) {
*e = le->entry;
le->entry = NULL;
@@ -249,7 +259,7 @@ find_entry(struct archive_entry_linkresolver *res,
struct archive_entry *entry)
{
struct links_entry *le;
- int hash, bucket;
+ size_t hash, bucket;
dev_t dev;
int64_t ino;
@@ -261,16 +271,12 @@ find_entry(struct archive_entry_linkresolver *res,
res->spare = NULL;
}
- /* If the links cache overflowed and got flushed, don't bother. */
- if (res->buckets == NULL)
- return (NULL);
-
dev = archive_entry_dev(entry);
ino = archive_entry_ino64(entry);
- hash = (int)(dev ^ ino);
+ hash = (size_t)(dev ^ ino);
/* Try to locate this entry in the links cache. */
- bucket = hash % res->number_buckets;
+ bucket = hash & (res->number_buckets - 1);
for (le = res->buckets[bucket]; le != NULL; le = le->next) {
if (le->hash == hash
&& dev == archive_entry_dev(le->canonical)
@@ -301,7 +307,7 @@ find_entry(struct archive_entry_linkresolver *res,
}
static struct links_entry *
-next_entry(struct archive_entry_linkresolver *res)
+next_entry(struct archive_entry_linkresolver *res, int mode)
{
struct links_entry *le;
size_t bucket;
@@ -309,22 +315,27 @@ next_entry(struct archive_entry_linkresolver *res)
/* Free a held entry. */
if (res->spare != NULL) {
archive_entry_free(res->spare->canonical);
+ archive_entry_free(res->spare->entry);
free(res->spare);
res->spare = NULL;
}
- /* If the links cache overflowed and got flushed, don't bother. */
- if (res->buckets == NULL)
- return (NULL);
-
/* Look for next non-empty bucket in the links cache. */
for (bucket = 0; bucket < res->number_buckets; bucket++) {
- le = res->buckets[bucket];
- if (le != NULL) {
+ for (le = res->buckets[bucket]; le != NULL; le = le->next) {
+ if (le->entry != NULL &&
+ (mode & NEXT_ENTRY_DEFERRED) == 0)
+ continue;
+ if (le->entry == NULL &&
+ (mode & NEXT_ENTRY_PARTIAL) == 0)
+ continue;
/* Remove it from this hash bucket. */
if (le->next != NULL)
le->next->previous = le->previous;
- res->buckets[bucket] = le->next;
+ if (le->previous != NULL)
+ le->previous->next = le->next;
+ else
+ res->buckets[bucket] = le->next;
res->number_entries--;
/* Defer freeing this entry. */
res->spare = le;
@@ -339,13 +350,12 @@ insert_entry(struct archive_entry_linkresolver *res,
struct archive_entry *entry)
{
struct links_entry *le;
- int hash, bucket;
+ size_t hash, bucket;
/* Add this entry to the links cache. */
- le = malloc(sizeof(struct links_entry));
+ le = calloc(1, sizeof(struct links_entry));
if (le == NULL)
return (NULL);
- memset(le, 0, sizeof(*le));
le->canonical = archive_entry_clone(entry);
/* If the links cache is getting too full, enlarge the hash table. */
@@ -353,7 +363,7 @@ insert_entry(struct archive_entry_linkresolver *res,
grow_hash(res);
hash = archive_entry_dev(entry) ^ archive_entry_ino64(entry);
- bucket = hash % res->number_buckets;
+ bucket = hash & (res->number_buckets - 1);
/* If we could allocate the entry, record it. */
if (res->buckets[bucket] != NULL)
@@ -376,30 +386,59 @@ grow_hash(struct archive_entry_linkresolver *res)
/* Try to enlarge the bucket list. */
new_size = res->number_buckets * 2;
- new_buckets = malloc(new_size * sizeof(struct links_entry *));
-
- if (new_buckets != NULL) {
- memset(new_buckets, 0,
- new_size * sizeof(struct links_entry *));
- for (i = 0; i < res->number_buckets; i++) {
- while (res->buckets[i] != NULL) {
- /* Remove entry from old bucket. */
- le = res->buckets[i];
- res->buckets[i] = le->next;
-
- /* Add entry to new bucket. */
- bucket = le->hash % new_size;
-
- if (new_buckets[bucket] != NULL)
- new_buckets[bucket]->previous =
- le;
- le->next = new_buckets[bucket];
- le->previous = NULL;
- new_buckets[bucket] = le;
- }
+ if (new_size < res->number_buckets)
+ return;
+ new_buckets = calloc(new_size, sizeof(struct links_entry *));
+
+ if (new_buckets == NULL)
+ return;
+
+ for (i = 0; i < res->number_buckets; i++) {
+ while (res->buckets[i] != NULL) {
+ /* Remove entry from old bucket. */
+ le = res->buckets[i];
+ res->buckets[i] = le->next;
+
+ /* Add entry to new bucket. */
+ bucket = le->hash & (new_size - 1);
+
+ if (new_buckets[bucket] != NULL)
+ new_buckets[bucket]->previous = le;
+ le->next = new_buckets[bucket];
+ le->previous = NULL;
+ new_buckets[bucket] = le;
}
- free(res->buckets);
- res->buckets = new_buckets;
- res->number_buckets = new_size;
}
+ free(res->buckets);
+ res->buckets = new_buckets;
+ res->number_buckets = new_size;
+}
+
+struct archive_entry *
+archive_entry_partial_links(struct archive_entry_linkresolver *res,
+ unsigned int *links)
+{
+ struct archive_entry *e;
+ struct links_entry *le;
+
+ /* Free a held entry. */
+ if (res->spare != NULL) {
+ archive_entry_free(res->spare->canonical);
+ archive_entry_free(res->spare->entry);
+ free(res->spare);
+ res->spare = NULL;
+ }
+
+ le = next_entry(res, NEXT_ENTRY_PARTIAL);
+ if (le != NULL) {
+ e = le->canonical;
+ if (links != NULL)
+ *links = le->links;
+ le->canonical = NULL;
+ } else {
+ e = NULL;
+ if (links != NULL)
+ *links = 0;
+ }
+ return (e);
}
diff --git a/libarchive/archive_entry_linkify.3 b/libarchive/archive_entry_linkify.3
new file mode 100644
index 000000000000..a34b095e7474
--- /dev/null
+++ b/libarchive/archive_entry_linkify.3
@@ -0,0 +1,224 @@
+.\" Copyright (c) 2010 Joerg Sonnenberger
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd February 20, 2010
+.Dt ARCHIVE_ENTRY_LINKIFY 3
+.Os
+.Sh NAME
+.Nm archive_entry_linkresolver ,
+.Nm archive_entry_linkresolver_new ,
+.Nm archive_entry_linkresolver_set_strategy ,
+.Nm archive_entry_linkresolver_free ,
+.Nm archive_entry_linkify
+.Nd hardlink resolver functions
+.Sh LIBRARY
+.Lb libarchive
+.Sh SYNOPSIS
+.In archive_entry.h
+.Ft struct archive_entry_linkresolver *
+.Fn archive_entry_linkresolver_new void
+.Ft void
+.Fo archive_entry_linkresolver_set_strategy
+.Fa "struct archive_entry_linkresolver *resolver"
+.Fa "int format"
+.Fc
+.Ft void
+.Fo archive_entry_linkresolver_free
+.Fa "struct archive_entry_linkresolver *resolver"
+.Fc
+.Ft void
+.Fo archive_entry_linkify
+.Fa "struct archive_entry_linkresolver *resolver"
+.Fa "struct archive_entry **entry"
+.Fa "struct archive_entry **sparse"
+.Fc
+.Sh DESCRIPTION
+Programs that want to create archives have to deal with hardlinks.
+Hardlinks are handled in different ways by the archive formats.
+The basic strategies are:
+.Bl -enum
+.It
+Ignore hardlinks and store the body for each reference (old cpio, zip).
+.It
+Store the body the first time an inode is seen (ustar, pax).
+.It
+Store the body the last time an inode is seen (new cpio).
+.El
+.Pp
+The
+.Nm
+functions help by providing a unified interface and handling the complexity
+behind the scene.
+.Pp
+The
+.Nm
+functions assume that
+.Vt archive_entry
+instances have valid nlinks, inode and device values.
+The inode and device value is used to match entries.
+The nlinks value is used to determined if all references have been found and
+if the internal references can be recycled.
+.Pp
+The
+.Fn archive_entry_linkresolver_new
+function allocates a new link resolver.
+The instance can be freed using
+.Fn archive_entry_linkresolver_free .
+All deferred entries are flushed and the internal storage is freed.
+.Pp
+The
+.Fn archive_entry_linkresolver_set_strategy
+function selects the optimal hardlink strategy for the given format.
+The format code can be obtained from
+.Xr archive_format 3 .
+The function can be called more than once, but it is recommended to
+flush all deferred entries first.
+.Pp
+The
+.Fn archive_entry_linkify
+function is the core of
+.Nm .
+The
+.Fn entry
+argument points to the
+.Vt archive_entry
+that should be written.
+Depending on the strategy one of the following actions is taken:
+.Bl -enum
+.It
+For the simple archive formats
+.Va *entry
+is left unmodified and
+.Va *sparse
+is set to
+.Dv NULL .
+.It
+For tar like archive formats,
+.Va *sparse
+is set to
+.Dv NULL .
+If
+.Va *entry
+is
+.Dv NULL ,
+no action is taken.
+If the hardlink count of
+.Va *entry
+is larger than 1 and the file type is a regular file or symbolic link,
+the internal list is searched for a matching inode.
+If such an inode is found, the link count is decremented and the file size
+of
+.Va *entry
+is set to 0 to notify that no body should be written.
+If no such inode is found, a copy of the entry is added to the internal cache
+with a link count reduced by one.
+.It
+For new cpio like archive formats a value for
+.Va *entry
+of
+.Dv NULL
+is used to flush deferred entries.
+In that case
+.Va *entry
+is set to an arbitrary deferred entry and the entry itself is removed from the
+internal list.
+If the internal list is empty,
+.Va *entry
+is set to
+.Dv NULL .
+In either case,
+.Va *sparse
+is set to
+.Dv NULL
+and the function returns.
+If the hardlink count of
+.Va *entry
+is one or the file type is a directory or device,
+.Va *sparse
+is set to
+.Dv NULL
+and no further action is taken.
+Otherwise, the internal list is searched for a matching inode.
+If such an inode is not found, the entry is added to the internal list,
+both
+.Va *entry
+and
+.Va *sparse
+are set to
+.Dv NULL
+and the function returns.
+If such an inode is found, the link count is decremented.
+If it remains larger than one, the existing entry on the internal list
+is swapped with
+.Va *entry
+after retaining the link count.
+The existing entry is returned in
+.Va *entry .
+If the link count reached one, the new entry is also removed from the
+internal list and returned in
+.Va *sparse .
+Otherwise
+.Va *sparse
+is set to
+.Dv NULL .
+.El
+.Pp
+The general usage is therefore:
+.Bl -enum
+.It
+For each new archive entry, call
+.Fn archive_entry_linkify .
+.It
+Keep in mind that the entries returned may have a size of 0 now.
+.It
+If
+.Va *entry
+is not
+.Dv NULL ,
+archive it.
+.It
+If
+.Va *sparse
+is not
+.Dv NULL ,
+archive it.
+.It
+After all entries have been written to disk, call
+.Fn archive_entry_linkify
+with
+.Va *entry
+set to
+.Dv NULL
+and archive the returned entry as long as it is not
+.Dv NULL .
+.El
+.Sh RETURN VALUES
+.Fn archive_entry_linkresolver_new
+returns
+.Dv NULL
+on
+.Xr malloc 3
+failures.
+.Sh SEE ALSO
+.Xr archive_entry 3
diff --git a/libarchive/archive_entry_locale.h b/libarchive/archive_entry_locale.h
new file mode 100644
index 000000000000..02e024ae20c1
--- /dev/null
+++ b/libarchive/archive_entry_locale.h
@@ -0,0 +1,88 @@
+/*-
+ * Copyright (c) 2011 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
+#ifndef ARCHIVE_ENTRY_LOCALE_H_INCLUDED
+#define ARCHIVE_ENTRY_LOCALE_H_INCLUDED
+
+struct archive_entry;
+struct archive_string_conv;
+
+/*
+ * Utility functions to set and get entry attributes by translating
+ * character-set. These are designed for use in format readers and writers.
+ *
+ * The return code and interface of these are quite different from other
+ * functions for archive_entry defined in archive_entry.h.
+ * Common return code are:
+ * Return 0 if the string conversion succeeded.
+ * Return -1 if the string conversion failed.
+ */
+
+#define archive_entry_gname_l _archive_entry_gname_l
+int _archive_entry_gname_l(struct archive_entry *,
+ const char **, size_t *, struct archive_string_conv *);
+#define archive_entry_hardlink_l _archive_entry_hardlink_l
+int _archive_entry_hardlink_l(struct archive_entry *,
+ const char **, size_t *, struct archive_string_conv *);
+#define archive_entry_pathname_l _archive_entry_pathname_l
+int _archive_entry_pathname_l(struct archive_entry *,
+ const char **, size_t *, struct archive_string_conv *);
+#define archive_entry_symlink_l _archive_entry_symlink_l
+int _archive_entry_symlink_l(struct archive_entry *,
+ const char **, size_t *, struct archive_string_conv *);
+#define archive_entry_uname_l _archive_entry_uname_l
+int _archive_entry_uname_l(struct archive_entry *,
+ const char **, size_t *, struct archive_string_conv *);
+#define archive_entry_acl_text_l _archive_entry_acl_text_l
+int _archive_entry_acl_text_l(struct archive_entry *, int,
+ const char **, size_t *, struct archive_string_conv *);
+
+
+#define archive_entry_copy_gname_l _archive_entry_copy_gname_l
+int _archive_entry_copy_gname_l(struct archive_entry *,
+ const char *, size_t, struct archive_string_conv *);
+#define archive_entry_copy_hardlink_l _archive_entry_copy_hardlink_l
+int _archive_entry_copy_hardlink_l(struct archive_entry *,
+ const char *, size_t, struct archive_string_conv *);
+#define archive_entry_copy_link_l _archive_entry_copy_link_l
+int _archive_entry_copy_link_l(struct archive_entry *,
+ const char *, size_t, struct archive_string_conv *);
+#define archive_entry_copy_pathname_l _archive_entry_copy_pathname_l
+int _archive_entry_copy_pathname_l(struct archive_entry *,
+ const char *, size_t, struct archive_string_conv *);
+#define archive_entry_copy_symlink_l _archive_entry_copy_symlink_l
+int _archive_entry_copy_symlink_l(struct archive_entry *,
+ const char *, size_t, struct archive_string_conv *);
+#define archive_entry_copy_uname_l _archive_entry_copy_uname_l
+int _archive_entry_copy_uname_l(struct archive_entry *,
+ const char *, size_t, struct archive_string_conv *);
+
+#endif /* ARCHIVE_ENTRY_LOCALE_H_INCLUDED */
diff --git a/libarchive/archive_entry_paths.3 b/libarchive/archive_entry_paths.3
new file mode 100644
index 000000000000..621f65518e1d
--- /dev/null
+++ b/libarchive/archive_entry_paths.3
@@ -0,0 +1,151 @@
+.\" Copyright (c) 2010 Joerg Sonnenberger
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd February 22, 2010
+.Dt ARCHIVE_ENTRY_PATHS 3
+.Os
+.Sh NAME
+.Nm archive_entry_hardlink ,
+.Nm archive_entry_hardlink_w ,
+.Nm archive_entry_set_hardlink ,
+.Nm archive_entry_copy_hardlink ,
+.Nm archive_entry_copy_hardlink_w ,
+.Nm archve_entry_update_hardlink_utf8 ,
+.Nm archive_entry_set_link ,
+.Nm archive_entry_copy_link ,
+.Nm archive_entry_copy_link_w ,
+.Nm archve_entry_update_link_utf8 ,
+.Nm archive_entry_pathname ,
+.Nm archive_entry_pathname_w ,
+.Nm archive_entry_set_pathname ,
+.Nm archive_entry_copy_pathname ,
+.Nm archive_entry_copy_pathname_w ,
+.Nm archve_entry_update_pathname_utf8 ,
+.Nm archive_entry_sourcepath ,
+.Nm archive_entry_copy_sourcepath ,
+.Nm archive_entry_symlink,
+.Nm archive_entry_symlink_w,
+.Nm archive_entry_set_symlink ,
+.Nm archive_entry_copy_symlink ,
+.Nm archive_entry_copy_symlink_w ,
+.Nm archve_entry_update_symlink_utf8
+.Nd functions for manipulating path names in archive entry descriptions
+.Sh SYNOPSIS
+.In archive_entry.h
+.Ft const char *
+.Fn archive_entry_hardlink "struct archive_entry *a"
+.Ft const wchar_t *
+.Fn archive_entry_hardlink_w "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_hardlink "struct archive_entry *a" "const char *path"
+.Ft void
+.Fn archive_entry_copy_hardlink "struct archive_entry *a" "const char *path"
+.Ft void
+.Fn archive_entry_copy_hardlink_w "struct archive_entry *a "const wchar_t *path"
+.Ft int
+.Fn archive_entry_update_hardlink_utf8 "struct archive_entry *a" "const char *path"
+.Ft void
+.Fn archive_entry_set_link "struct archive_entry *a" "const char *path"
+.Ft void
+.Fn archive_entry_copy_link "struct archive_entry *a" " const char *path"
+.Ft void
+.Fn archive_entry_copy_link_w "struct archive_entry *a" " const wchar_t *path"
+.Ft int
+.Fn archive_entry_update_link_utf8 "struct archive_entry *a" " const char *path"
+.Ft const char *
+.Fn archive_entry_pathname "struct archive_entry *a"
+.Ft const wchar_t *
+.Fn archive_entry_pathname_w "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_pathname "struct archive_entry *a" "const char *path"
+.Ft void
+.Fn archive_entry_copy_pathname "struct archive_entry *a" "const char *path"
+.Ft void
+.Fn archive_entry_copy_pathname_w "struct archive_entry *a" "const wchar_t *path"
+.Ft int
+.Fn archive_entry_update_pathname_utf8 "struct archive_entry *a" "const char *path"
+.Ft const char *
+.Fn archive_entry_sourcepath "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_copy_sourcepath "struct archive_entry *a" "const char *path"
+.Ft const char *
+.Fn archive_entry_symlink "struct archive_entry *a"
+.Ft const wchar_t *
+.Fn archive_entry_symlink_w "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_symlink "struct archive_entry *a" "const char *path"
+.Ft void
+.Fn archive_entry_copy_symlink "struct archive_entry *a" "const char *path"
+.Ft void
+.Fn archive_entry_copy_symlink_w "struct archive_entry *a" "const wchar_t *path"
+.Ft int
+.Fn archive_entry_update_symlink_utf8 "struct archive_entry *a" "const char *path"
+.Sh DESCRIPTION
+Path names supported by
+.Xr archive_entry 3 :
+.Bl -tag -width "sourcepath" -compact
+.It hardlink
+Destination of the hardlink.
+.It link
+Update only.
+For a symlink, update the destination.
+Otherwise, make the entry a hardlink and alter
+the destination for that.
+.It pathname
+Path in the archive
+.It sourcepath
+Path on the disk for use by
+.Xr archive_read_disk 3 .
+.It symlink
+Destination of the symbolic link.
+.El
+.Pp
+Path names can be provided in one of three different ways:
+.Bl -tag -width "wchar_t *"
+.It char *
+Multibyte strings in the current locale.
+.It wchar_t *
+Wide character strings in the current locale.
+The accessor functions are named
+.Fn XXX_w .
+.It UTF-8
+Unicode strings encoded as UTF-8.
+This are convience functions to update both the multibyte and wide
+character strings at the same time.
+.El
+.Pp
+The sourcepath is a pure filesystem concept and never stored in an
+archive directly.
+.Pp
+For that reason, it is only available as multibyte string.
+The link path is a convience function for conditionally setting
+hardlink or symlink destination.
+It doesn't have a corresponding get accessor function.
+.Pp
+.Fn archive_entry_set_XXX
+is an alias for
+.Fn archive_entry_copy_XXX .
+.Sh SEE ALSO
+.Xr archive 3 ,
+.Xr archive_entry 3
diff --git a/libarchive/archive_entry_perms.3 b/libarchive/archive_entry_perms.3
new file mode 100644
index 000000000000..164af9731dc7
--- /dev/null
+++ b/libarchive/archive_entry_perms.3
@@ -0,0 +1,207 @@
+.\" Copyright (c) 2003-2007 Tim Kientzle
+.\" Copyright (c) 2010 Joerg Sonnenberger
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd February 22, 2010
+.Dt ARCHIVE_ENTRY_PERMS 3
+.Os
+.Sh NAME
+.Nm archive_entry_gid ,
+.Nm archive_entry_set_gid ,
+.Nm archive_entry_uid ,
+.Nm archive_entry_set_uid ,
+.Nm archive_entry_perm ,
+.Nm archive_entry_set_perm ,
+.Nm archive_entry_strmode ,
+.Nm archive_entry_uname
+.Nm archive_entry_uname_w
+.Nm archive_entry_set_uname ,
+.Nm archive_entry_copy_uname ,
+.Nm archive_entry_copy_uname_w ,
+.Nm archive_entry_update_uname_utf8 ,
+.Nm archive_entry_gname ,
+.Nm archive_entry_gname_w ,
+.Nm archive_entry_set_gname ,
+.Nm archive_entry_copy_gname ,
+.Nm archive_entry_copy_gname_w ,
+.Nm archive_entry_update_gname_utf8 ,
+.Nm archive_entry_fflags ,
+.Nm archive_entry_fflags_text ,
+.Nm archive_entry_set_fflags ,
+.Nm archive_entry_copy_fflags_text ,
+.Nm archive_entry_copy_fflags_text_w
+.Nd functions for manipulating ownership and permissions in archive entry descriptions
+.Sh SYNOPSIS
+.In archive_entry.h
+.Ft gid_t
+.Fn archive_entry_gid "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_gid "struct archive_entry *a" "gid_t gid"
+.Ft uid_t
+.Fn archive_entry_uid "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_uid "struct archive_entry *a" "uid_t uid"
+.Ft mode_t
+.Fn archive_entry_perm "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_perm "struct archive_entry *a" "mode_t mode"
+.Ft const char *
+.Fn archive_entry_strmode "struct archive_entry *a"
+.Ft const char *
+.Fn archive_entry_gname "struct archive_entry *a"
+.Ft const wchar_t *
+.Fn archive_entry_gname_w "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_gname "struct archive_entry *a" "const char *a"
+.Ft void
+.Fn archive_entry_copy_gname "struct archive_entry *a" "const char *name"
+.Ft void
+.Fn archive_entry_copy_gname_w "struct archive_entry *a" "const wchar_t *name"
+.Ft int
+.Fn archive_entry_update_gname_utf8 "struct archive_entry *a" "const char *name"
+.Ft const char *
+.Fn archive_entry_uname "struct archive_entry *a"
+.Ft const wchar_t *
+.Fn archive_entry_uname_w "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_uname "struct archive_entry *a" "const char *name"
+.Ft void
+.Fn archive_entry_copy_uname "struct archive_entry *a" "const char *name"
+.Ft void
+.Fn archive_entry_copy_uname_w "struct archive_entry *a" "const wchar_t *name"
+.Ft int
+.Fn archive_entry_update_uname_utf8 "struct archive_entry *a" "const char *name"
+.Ft void
+.Fo archive_entry_fflags
+.Fa "struct archive_entry *a"
+.Fa "unsigned long *set_bits"
+.Fa "unsigned long *clear_bits"
+.Fc
+.Ft const char *
+.Fn archive_entry_fflags_text "struct archive_entry *a"
+.Ft void
+.Fo archive_entry_set_fflags
+.Fa "struct archive_entry *a"
+.Fa "unsigned long set_bits"
+.Fa "unsigned long clear_bits"
+.Fc
+.Ft const char *
+.Fn archive_entry_copy_fflags_text "struct archive_entry *a" "const char *text"
+.Ft const wchar_t *
+.Fn archive_entry_copy_fflags_text_w "struct archive_entry *a" "const wchar_t *text"
+.Sh DESCRIPTION
+.Ss User id, group id and mode
+The functions
+.Fn archive_entry_uid ,
+.Fn archive_entry_gid ,
+and
+.Fn archive_entry_perm
+can be used to extract the user id, group id and permission from the given entry.
+The corresponding functions
+.Fn archive_entry_set_uid ,
+.Fn archive_entry_set_gid ,
+and
+.Fn archive_entry_set_perm
+store the given user id, group id and permission in the entry.
+The permission is also set as side effect of calling
+.Fn archive_entry_set_mode .
+.Pp
+.Fn archive_entry_strmode
+returns a string representation of the permission as used by the long mode of
+.Xr ls 1 .
+.Ss User and group name
+User and group names can be provided in one of three different ways:
+.Bl -tag -width "wchar_t *"
+.It char *
+Multibyte strings in the current locale.
+.It wchar_t *
+Wide character strings in the current locale.
+The accessor functions are named
+.Fn XXX_w .
+.It UTF-8
+Unicode strings encoded as UTF-8.
+This are convience functions to update both the multibyte and wide
+character strings at the same time.
+.El
+.Pp
+.Fn archive_entry_set_XXX
+is an alias for
+.Fn archive_entry_copy_XXX .
+.Ss File Flags
+File flags are transparently converted between a bitmap
+representation and a textual format.
+For example, if you set the bitmap and ask for text, the library
+will build a canonical text format.
+However, if you set a text format and request a text format,
+you will get back the same text, even if it is ill-formed.
+If you need to canonicalize a textual flags string, you should first set the
+text form, then request the bitmap form, then use that to set the bitmap form.
+Setting the bitmap format will clear the internal text representation
+and force it to be reconstructed when you next request the text form.
+.Pp
+The bitmap format consists of two integers, one containing bits
+that should be set, the other specifying bits that should be
+cleared.
+Bits not mentioned in either bitmap will be ignored.
+Usually, the bitmap of bits to be cleared will be set to zero.
+In unusual circumstances, you can force a fully-specified set
+of file flags by setting the bitmap of flags to clear to the complement
+of the bitmap of flags to set.
+(This differs from
+.Xr fflagstostr 3 ,
+which only includes names for set bits.)
+Converting a bitmap to a textual string is a platform-specific
+operation; bits that are not meaningful on the current platform
+will be ignored.
+.Pp
+The canonical text format is a comma-separated list of flag names.
+The
+.Fn archive_entry_copy_fflags_text
+and
+.Fn archive_entry_copy_fflags_text_w
+functions parse the provided text and sets the internal bitmap values.
+This is a platform-specific operation; names that are not meaningful
+on the current platform will be ignored.
+The function returns a pointer to the start of the first name that was not
+recognized, or NULL if every name was recognized.
+Note that every name \(em including names that follow an unrecognized
+name \(em will be evaluated, and the bitmaps will be set to reflect
+every name that is recognized.
+(In particular, this differs from
+.Xr strtofflags 3 ,
+which stops parsing at the first unrecognized name.)
+.Sh SEE ALSO
+.Xr archive 3 ,
+.Xr archive_entry 3 ,
+.Xr archive_entry_acl 3 ,
+.Xr archive_read_disk 3 ,
+.Xr archive_write_disk 3
+.Sh BUGS
+The platform types
+.Vt uid_t
+and
+.Vt gid_t
+are often 16 or 32 bit wide.
+In this case it is possible that the ids can not be correctly restored
+from archives and get truncated.
diff --git a/libarchive/archive_entry_private.h b/libarchive/archive_entry_private.h
index 5ab4f75f0bce..e3547c3e3187 100644
--- a/libarchive/archive_entry_private.h
+++ b/libarchive/archive_entry_private.h
@@ -32,36 +32,9 @@
#ifndef ARCHIVE_ENTRY_PRIVATE_H_INCLUDED
#define ARCHIVE_ENTRY_PRIVATE_H_INCLUDED
+#include "archive_acl_private.h"
#include "archive_string.h"
-/*
- * Handle wide character (i.e., Unicode) and non-wide character
- * strings transparently.
- */
-
-struct aes {
- struct archive_string aes_mbs;
- struct archive_string aes_utf8;
- const wchar_t *aes_wcs;
- /* Bitmap of which of the above are valid. Because we're lazy
- * about malloc-ing and reusing the underlying storage, we
- * can't rely on NULL pointers to indicate whether a string
- * has been set. */
- int aes_set;
-#define AES_SET_MBS 1
-#define AES_SET_UTF8 2
-#define AES_SET_WCS 4
-};
-
-struct ae_acl {
- struct ae_acl *next;
- int type; /* E.g., access or default */
- int tag; /* E.g., user/group/other/mask */
- int permset; /* r/w/x bits */
- int id; /* uid/gid for user/group */
- struct aes name; /* uname/gname */
-};
-
struct ae_xattr {
struct ae_xattr *next;
@@ -70,6 +43,13 @@ struct ae_xattr {
size_t size;
};
+struct ae_sparse {
+ struct ae_sparse *next;
+
+ int64_t offset;
+ int64_t length;
+};
+
/*
* Description of an archive entry.
*
@@ -91,6 +71,8 @@ struct ae_xattr {
* TODO: Design a good API for handling sparse files.
*/
struct archive_entry {
+ struct archive *archive;
+
/*
* Note that ae_stat.st_mode & AE_IFMT can be 0!
*
@@ -101,10 +83,15 @@ struct archive_entry {
*/
/*
- * Read archive_entry_copy_stat.c for an explanation of why I
- * don't just use "struct stat" instead of "struct aest" here
- * and why I have this odd pointer to a separately-allocated
- * struct stat.
+ * We have a "struct aest" for holding file metadata rather than just
+ * a "struct stat" because on some platforms the "struct stat" has
+ * fields which are too narrow to hold the range of possible values;
+ * we don't want to lose information if we read an archive and write
+ * out another (e.g., in "tar -cf new.tar @old.tar").
+ *
+ * The "stat" pointer points to some form of platform-specific struct
+ * stat; it is declared as a void * rather than a struct stat * as
+ * some platforms have multiple varieties of stat structures.
*/
void *stat;
int stat_valid; /* Set to 0 whenever a field in aest changes. */
@@ -118,12 +105,11 @@ struct archive_entry {
uint32_t aest_mtime_nsec;
int64_t aest_birthtime;
uint32_t aest_birthtime_nsec;
- gid_t aest_gid;
+ int64_t aest_gid;
int64_t aest_ino;
- mode_t aest_mode;
uint32_t aest_nlink;
uint64_t aest_size;
- uid_t aest_uid;
+ int64_t aest_uid;
/*
* Because converting between device codes and
* major/minor values is platform-specific and
@@ -150,35 +136,41 @@ struct archive_entry {
#define AE_SET_MTIME 16
#define AE_SET_BIRTHTIME 32
#define AE_SET_SIZE 64
+#define AE_SET_INO 128
+#define AE_SET_DEV 256
/*
* Use aes here so that we get transparent mbs<->wcs conversions.
*/
- struct aes ae_fflags_text; /* Text fflags per fflagstostr(3) */
+ struct archive_mstring ae_fflags_text; /* Text fflags per fflagstostr(3) */
unsigned long ae_fflags_set; /* Bitmap fflags */
unsigned long ae_fflags_clear;
- struct aes ae_gname; /* Name of owning group */
- struct aes ae_hardlink; /* Name of target for hardlink */
- struct aes ae_pathname; /* Name of entry */
- struct aes ae_symlink; /* symlink contents */
- struct aes ae_uname; /* Name of owner */
+ struct archive_mstring ae_gname; /* Name of owning group */
+ struct archive_mstring ae_hardlink; /* Name of target for hardlink */
+ struct archive_mstring ae_pathname; /* Name of entry */
+ struct archive_mstring ae_symlink; /* symlink contents */
+ struct archive_mstring ae_uname; /* Name of owner */
/* Not used within libarchive; useful for some clients. */
- struct aes ae_sourcepath; /* Path this entry is sourced from. */
+ struct archive_mstring ae_sourcepath; /* Path this entry is sourced from. */
+
+ void *mac_metadata;
+ size_t mac_metadata_size;
/* ACL support. */
- struct ae_acl *acl_head;
- struct ae_acl *acl_p;
- int acl_state; /* See acl_next for details. */
- wchar_t *acl_text_w;
+ struct archive_acl acl;
/* extattr support. */
struct ae_xattr *xattr_head;
struct ae_xattr *xattr_p;
+ /* sparse support. */
+ struct ae_sparse *sparse_head;
+ struct ae_sparse *sparse_tail;
+ struct ae_sparse *sparse_p;
+
/* Miscellaneous. */
char strmode[12];
};
-
#endif /* ARCHIVE_ENTRY_PRIVATE_H_INCLUDED */
diff --git a/libarchive/archive_entry_sparse.c b/libarchive/archive_entry_sparse.c
new file mode 100644
index 000000000000..10c54474a379
--- /dev/null
+++ b/libarchive/archive_entry_sparse.c
@@ -0,0 +1,156 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2010-2011 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+__FBSDID("$FreeBSD$");
+
+#include "archive.h"
+#include "archive_entry.h"
+#include "archive_private.h"
+#include "archive_entry_private.h"
+
+/*
+ * sparse handling
+ */
+
+void
+archive_entry_sparse_clear(struct archive_entry *entry)
+{
+ struct ae_sparse *sp;
+
+ while (entry->sparse_head != NULL) {
+ sp = entry->sparse_head->next;
+ free(entry->sparse_head);
+ entry->sparse_head = sp;
+ }
+ entry->sparse_tail = NULL;
+}
+
+void
+archive_entry_sparse_add_entry(struct archive_entry *entry,
+ int64_t offset, int64_t length)
+{
+ struct ae_sparse *sp;
+
+ if (offset < 0 || length < 0)
+ /* Invalid value */
+ return;
+ if (offset + length < 0 ||
+ offset + length > archive_entry_size(entry))
+ /* A value of "length" parameter is too large. */
+ return;
+ if ((sp = entry->sparse_tail) != NULL) {
+ if (sp->offset + sp->length > offset)
+ /* Invalid value. */
+ return;
+ if (sp->offset + sp->length == offset) {
+ if (sp->offset + sp->length + length < 0)
+ /* A value of "length" parameter is
+ * too large. */
+ return;
+ /* Expand existing sparse block size. */
+ sp->length += length;
+ return;
+ }
+ }
+
+ if ((sp = (struct ae_sparse *)malloc(sizeof(*sp))) == NULL)
+ /* XXX Error XXX */
+ return;
+
+ sp->offset = offset;
+ sp->length = length;
+ sp->next = NULL;
+
+ if (entry->sparse_head == NULL)
+ entry->sparse_head = entry->sparse_tail = sp;
+ else {
+ /* Add a new sparse block to the tail of list. */
+ if (entry->sparse_tail != NULL)
+ entry->sparse_tail->next = sp;
+ entry->sparse_tail = sp;
+ }
+}
+
+
+/*
+ * returns number of the sparse entries
+ */
+int
+archive_entry_sparse_count(struct archive_entry *entry)
+{
+ struct ae_sparse *sp;
+ int count = 0;
+
+ for (sp = entry->sparse_head; sp != NULL; sp = sp->next)
+ count++;
+
+ /*
+ * Sanity check if this entry is exactly sparse.
+ * If amount of sparse blocks is just one and it indicates the whole
+ * file data, we should remove it and return zero.
+ */
+ if (count == 1) {
+ sp = entry->sparse_head;
+ if (sp->offset == 0 &&
+ sp->length >= archive_entry_size(entry)) {
+ count = 0;
+ archive_entry_sparse_clear(entry);
+ }
+ }
+
+ return (count);
+}
+
+int
+archive_entry_sparse_reset(struct archive_entry * entry)
+{
+ entry->sparse_p = entry->sparse_head;
+
+ return archive_entry_sparse_count(entry);
+}
+
+int
+archive_entry_sparse_next(struct archive_entry * entry,
+ int64_t *offset, int64_t *length)
+{
+ if (entry->sparse_p) {
+ *offset = entry->sparse_p->offset;
+ *length = entry->sparse_p->length;
+
+ entry->sparse_p = entry->sparse_p->next;
+
+ return (ARCHIVE_OK);
+ } else {
+ *offset = 0;
+ *length = 0;
+ return (ARCHIVE_WARN);
+ }
+}
+
+/*
+ * end of sparse handling
+ */
diff --git a/libarchive/archive_entry_stat.3 b/libarchive/archive_entry_stat.3
new file mode 100644
index 000000000000..36a7efb2322a
--- /dev/null
+++ b/libarchive/archive_entry_stat.3
@@ -0,0 +1,272 @@
+.\" Copyright (c) 2010 Joerg Sonnenberger
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd May 12, 2008
+.Dt ARCHIVE_ENTRY 3
+.Os
+.Sh NAME
+.Nm archive_entry_stat ,
+.Nm archive_entry_copy_stat ,
+.Nm archive_entry_filetype ,
+.Nm archive_entry_set_filetype ,
+.Nm archive_entry_mode ,
+.Nm archive_entry_set_mode ,
+.Nm archive_entry_size ,
+.Nm archive_entry_size_is_set ,
+.Nm archive_entry_set_size ,
+.Nm archive_entry_unset_size ,
+.Nm archive_entry_dev ,
+.Nm archive_entry_set_dev ,
+.Nm archive_entry_dev_is_set ,
+.Nm archive_entry_devmajor ,
+.Nm archive_entry_set_devmajor ,
+.Nm archive_entry_devminor ,
+.Nm archive_entry_set_devminor ,
+.Nm archive_entry_ino ,
+.Nm archive_entry_set_ino ,
+.Nm archive_entry_ino_is_set ,
+.Nm archive_entry_ino64 ,
+.Nm archive_entry_set_ino64 ,
+.Nm archive_entry_nlink ,
+.Nm archive_entry_rdev ,
+.Nm archive_entry_set_rdev ,
+.Nm archive_entry_rdevmajor ,
+.Nm archive_entry_set_rdevmajor ,
+.Nm archive_entry_rdevminor ,
+.Nm archive_entry_set_rdevminor ,
+.Nd accessor functions for manipulating archive entry descriptions
+.Sh SYNOPSIS
+.In archive_entry.h
+.Ft const struct stat *
+.Fn archive_entry_stat "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_copy_stat "struct archive_entry *a" "const struct stat *sb"
+.Ft mode_t
+.Fn archive_entry_filetype "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_filetype "struct archive_entry *a" "unsigned int type"
+.Ft mode_t
+.Fn archive_entry_mode "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_mode "struct archive_entry *a" "mode_t mode"
+.Ft int64_t
+.Fn archive_entry_size "struct archive_entry *a"
+.Ft int
+.Fn archive_entry_size_is_set "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_size "struct archive_entry *a" "int64_t size"
+.Ft void
+.Fn archive_entry_unset_size "struct archive_entry *a"
+.Ft dev_t
+.Fn archive_entry_dev "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_dev "struct archive_entry *a" "dev_t dev"
+.Ft int
+.Fn archive_entry_dev_is_set "struct archive_entry *a"
+.Ft dev_t
+.Fn archive_entry_devmajor "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_devmajor "struct archive_entry *a" "dev_t major"
+.Ft dev_t
+.Fn archive_entry_devminor "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_devminor "struct archive_entry *a" "dev_t minor"
+.Ft ino_t
+.Fn archive_entry_ino "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_ino "struct archive_entry *a" "unsigned long ino"
+.Ft int
+.Fn archive_entry_ino_is_set "struct archive_entry *a"
+.Ft int64_t
+.Fn archive_entry_ino64 "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_ino64 "struct archive_entry *a" "int64_t ino"
+.Ft unsigned int
+.Fn archive_entry_nlink "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_nlink "struct archive_entry *a" "unsigned int count"
+.Ft dev_t
+.Fn archive_entry_rdev "struct archive_entry *a"
+.Ft dev_t
+.Fn archive_entry_rdevmajor "struct archive_entry *a"
+.Ft dev_t
+.Fn archive_entry_rdevminor "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_rdev "struct archive_entry *a" "dev_t dev"
+.Ft void
+.Fn archive_entry_set_rdevmajor "struct archive_entry *a" "dev_t major"
+.Ft void
+.Fn archive_entry_set_rdevminor "struct archive_entry *a" "dev_t minor"
+.Sh DESCRIPTION
+.Ss Copying to and from Vt struct stat
+The function
+.Fn archive_entry_stat
+converts the various fields stored in the archive entry to the format
+used by
+.Xr stat 2 .
+The return value remains valid until either
+.Fn archive_entry_clear
+or
+.Fn archive_entry_free
+is called.
+It is not affected by calls to the set accessor functions.
+It currently sets the following values in
+.Vt struct stat :
+.Vt st_atime ,
+.Vt st_ctime ,
+.Vt st_dev ,
+.Vt st_gid ,
+.Vt st_ino ,
+.Vt st_mode ,
+.Vt st_mtime ,
+.Vt st_nlink ,
+.Vt st_rdev ,
+.Vt st_size ,
+.Vt st_uid .
+In addition,
+.Vt st_birthtime
+and high-precision information for time-related fields
+will be included on platforms that support it.
+.Pp
+The function
+.Fn archive_entry_copy_stat
+copies fields from the platform's
+.Vt struct stat .
+Fields not provided by
+.Vt struct stat
+are unchanged.
+.Ss General accessor functions
+The functions
+.Fn archive_entry_filetype
+and
+.Fn archive_entry_set_filetype
+get respectively set the filetype.
+The file type is one of the following constants:
+.Bl -tag -width "AE_IFSOCK" -compact -offset indent
+.It AE_IFREG
+Regular file
+.It AE_IFLNK
+Symbolic link
+.It AE_IFSOCK
+Socket
+.It AE_IFCHR
+Character device
+.It AE_IFBLK
+Block device
+.It AE_IFDIR
+Directory
+.It AE_IFIFO
+Named pipe (fifo)
+.El
+Not all file types are supported by all platforms.
+The constants used by
+.Xr stat 2
+may have different numeric values from the
+corresponding constants above.
+.Pp
+The functions
+.Fn archive_entry_mode
+and
+.Fn archive_entry_set_mode
+get/set a combination of file type and permissions and provide the
+equivalent of
+.Va st_mode .
+Use of
+.Fn archive_entry_filetype
+and
+.Fn archive_entry_perm
+for getting and
+.Fn archive_entry_set_filetype
+and
+.Fn archive_entry_set_perm
+for setting is recommended.
+.Pp
+The function
+.Fn archive_entry_size
+returns the file size, if it has been set, and 0 otherwise.
+.Fn archive_entry_size
+can be used to query that status.
+.Fn archive_entry_set_size
+and
+.Fn archive_entry_unset_size
+set and unset the size, respectively.
+.Pp
+The number of references (hardlinks) can be obtained by calling
+.Fn archive_entry_nlinks
+and set with
+.Fn archive_entry_set_nlinks .
+.Ss Identifying unique files
+The functions
+.Fn archive_entry_dev
+and
+.Fn archive_entry_ino64
+are used by
+.Xr archive_entry_linkify 3
+to find hardlinks.
+The pair of device and inode is suppossed to identify hardlinked files.
+.Pp
+The device major and minor number can be obtained independently using
+.Fn archive_entry_devmajor
+and
+.Fn archive_entry_devminor .
+The device can be set either via
+.Fn archive_entry_set_dev
+or by the combination of major and minor number using
+.Fn archive_entry_set_devmajor
+and
+.Fn archive_entry_set_devminor .
+.Pp
+The inode number can be obtained using
+.Fn archive_entry_ino .
+This is a legacy interface that uses the platform
+.Vt ino_t ,
+which may be very small.
+To set the inode number,
+.Fn archive_entry_set_ino64
+is the preferred interface.
+.Ss Accessor functions for block and character devices
+Block and character devices are characterised either using a device number
+or a pair of major and minor number.
+The combined device number can be obtained with
+.Fn archive_device_rdev
+and set with
+.Fn archive_device_set_rdev .
+The major and minor numbers are accessed by
+.Fn archive_device_rdevmajor ,
+.Fn archive_device_rdevminor
+.Fn archive_device_set_rdevmajor
+and
+.Fn archive_device_set_rdevminor .
+.Pp
+The process of splitting the combined device number into major and
+minor number and the reverse process of combing them differs between
+platforms.
+Some archive formats use the combined form, while other formats use
+the split form.
+.Sh SEE ALSO
+.Xr archive 3 ,
+.Xr archive_entry_acl 3 ,
+.Xr archive_entry_perms 3 ,
+.Xr archive_entry_time 3 ,
+.Xr stat 2
diff --git a/libarchive/archive_entry_stat.c b/libarchive/archive_entry_stat.c
index ad772c9564b6..65ff1cf92d07 100644
--- a/libarchive/archive_entry_stat.c
+++ b/libarchive/archive_entry_stat.c
@@ -41,7 +41,7 @@ archive_entry_stat(struct archive_entry *entry)
{
struct stat *st;
if (entry->stat == NULL) {
- entry->stat = malloc(sizeof(*st));
+ entry->stat = calloc(1, sizeof(*st));
if (entry->stat == NULL)
return (NULL);
entry->stat_valid = 0;
@@ -110,7 +110,7 @@ archive_entry_stat(struct archive_entry *entry)
/*
* TODO: On Linux, store 32 or 64 here depending on whether
* the cached stat structure is a stat32 or a stat64. This
- * will allow us to support both variants interchangably.
+ * will allow us to support both variants interchangeably.
*/
entry->stat_valid = 1;
diff --git a/libarchive/archive_entry_time.3 b/libarchive/archive_entry_time.3
new file mode 100644
index 000000000000..85a8209e89c0
--- /dev/null
+++ b/libarchive/archive_entry_time.3
@@ -0,0 +1,127 @@
+.\" Copyright (c) 2003-2007 Tim Kientzle
+.\" Copyright (c) 2010 Joerg Sonnenberger
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD: src/lib/libarchive/archive_entry.3,v 1.18 2008/05/26 17:00:22 kientzle Exp $
+.\"
+.Dd February 21, 2010
+.Dt ARCHIVE_ENTRY_TIME 3
+.Os
+.Sh NAME
+.Nm archive_entry_atime ,
+.Nm archive_entry_atime_nsec ,
+.Nm archive_entry_atime_is_set ,
+.Nm archive_entry_set_atime ,
+.Nm archive_entry_unset_atime ,
+.Nm archive_entry_birthtime ,
+.Nm archive_entry_birthtime_nsec ,
+.Nm archive_entry_birthtime_is_set ,
+.Nm archive_entry_set_birthtime ,
+.Nm archive_entry_unset_birthtime ,
+.Nm archive_entry_ctime ,
+.Nm archive_entry_ctime_nsec ,
+.Nm archive_entry_ctime_is_set ,
+.Nm archive_entry_set_ctime ,
+.Nm archive_entry_unset_ctime ,
+.Nm archive_entry_mtime ,
+.Nm archive_entry_mtime_nsec ,
+.Nm archive_entry_mtime_is_set ,
+.Nm archive_entry_set_mtime ,
+.Nm archive_entry_unset_mtime ,
+.Nd functions for manipulating times in archive entry descriptions
+.Sh SYNOPSIS
+.In archive_entry.h
+.Ft time_t
+.Fn archive_entry_atime "struct archive_entry *a"
+.Ft long
+.Fn archive_entry_atime_nsec "struct archive_entry *a"
+.Ft int
+.Fn archive_entry_atime_is_set "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_atime "struct archive_entry *a" "time_t sec" "long nanosec"
+.Ft void
+.Fn archive_entry_unset_atime "struct archive_entry *a"
+.Ft time_t
+.Fn archive_entry_birthtime "struct archive_entry *a"
+.Ft long
+.Fn archive_entry_birthtime_nsec "struct archive_entry *a"
+.Ft int
+.Fn archive_entry_birthtime_is_set "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_birthtime "struct archive_entry *a" "time_t sec" "long nanosec"
+.Ft void
+.Fn archive_entry_unset_birthtime "struct archive_entry *a"
+.Ft time_t
+.Fn archive_entry_ctime "struct archive_entry *a"
+.Ft long
+.Fn archive_entry_ctime_nsec "struct archive_entry *a"
+.Ft int
+.Fn archive_entry_ctime_is_set "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_ctime "struct archive_entry *a" "time_t sec" "long nanosec"
+.Ft void
+.Fn archive_entry_unset_ctime "struct archive_entry *a"
+.Ft time_t
+.Fn archive_entry_mtime "struct archive_entry *a"
+.Ft long
+.Fn archive_entry_mtime_nsec "struct archive_entry *a"
+.Ft int
+.Fn archive_entry_mtime_is_set "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_mtime "struct archive_entry *a" "time_t sec" "long nanosec"
+.Ft void
+.Fn archive_entry_unset_mtime "struct archive_entry *a"
+.Sh DESCRIPTION
+These functions create and manipulate the time fields in an
+.Vt archive_entry .
+Supported time fields are atime (access time), birthtime (creation time),
+ctime (last time an inode property was changed) and mtime (modification time).
+.Pp
+.Xr libarchive 3
+provides a high-resolution interface.
+The timestamps are truncated automatically depending on the archive format
+(for archiving) or the filesystem capabilities (for restoring).
+.Pp
+All timestamp fields are optional.
+The
+.Fn XXX_unset
+functions can be used to mark the corresponding field as missing.
+The current state can be queried using
+.Fn XXX_is_set .
+Unset time fields have a second and nanosecond field of 0.
+.Sh SEE ALSO
+.Xr archive 3 ,
+.Xr archive_entry 3
+.Sh HISTORY
+The
+.Nm libarchive
+library first appeared in
+.Fx 5.3 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm libarchive
+library was written by
+.An Tim Kientzle Aq kientzle@acm.org .
+.\" .Sh BUGS
diff --git a/libarchive/archive_hash.h b/libarchive/archive_hash.h
deleted file mode 100644
index da67a3026d6b..000000000000
--- a/libarchive/archive_hash.h
+++ /dev/null
@@ -1,309 +0,0 @@
-/*-
- * Copyright (c) 2009 Joerg Sonnenberger
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD: head/lib/libarchive/archive_hash.h 201171 2009-12-29 06:39:07Z kientzle $
- */
-
-#ifndef __LIBARCHIVE_BUILD
-#error This header is only to be used internally to libarchive.
-#endif
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-
-/*
- * Hash function support in various Operating Systems:
- *
- * NetBSD:
- * - MD5 and SHA1 in libc: without _ after algorithm name
- * - SHA2 in libc: with _ after algorithm name
- *
- * OpenBSD:
- * - MD5, SHA1 and SHA2 in libc: without _ after algorithm name
- * - OpenBSD 4.4 and earlier have SHA2 in libc with _ after algorithm name
- *
- * DragonFly and FreeBSD (XXX not used yet):
- * - MD5 and SHA1 in libmd: without _ after algorithm name
- * - SHA256: with _ after algorithm name
- *
- * Mac OS X (10.4 and later):
- * - MD5, SHA1 and SHA2 in libSystem: with CC_ prefix and _ after algorithm name
- *
- * OpenSSL:
- * - MD5, SHA1 and SHA2 in libcrypto: with _ after algorithm name
- *
- * Windows:
- * - MD5, SHA1 and SHA2 in archive_windows.c: without algorithm name
- * and with __la_ prefix.
- */
-#if defined(ARCHIVE_HASH_MD5_WIN) ||\
- defined(ARCHIVE_HASH_SHA1_WIN) || defined(ARCHIVE_HASH_SHA256_WIN) ||\
- defined(ARCHIVE_HASH_SHA384_WIN) || defined(ARCHIVE_HASH_SHA512_WIN)
-#include <wincrypt.h>
-typedef struct {
- int valid;
- HCRYPTPROV cryptProv;
- HCRYPTHASH hash;
-} Digest_CTX;
-extern void __la_hash_Init(Digest_CTX *, ALG_ID);
-extern void __la_hash_Final(unsigned char *, size_t, Digest_CTX *);
-extern void __la_hash_Update(Digest_CTX *, const unsigned char *, size_t);
-#endif
-
-#if defined(ARCHIVE_HASH_MD5_LIBC)
-# include <md5.h>
-# define ARCHIVE_HAS_MD5
-typedef MD5_CTX archive_md5_ctx;
-# define archive_md5_init(ctx) MD5Init(ctx)
-# define archive_md5_final(ctx, buf) MD5Final(buf, ctx)
-# define archive_md5_update(ctx, buf, n) MD5Update(ctx, buf, n)
-#elif defined(ARCHIVE_HASH_MD5_LIBMD)
-# include <md5.h>
-# define ARCHIVE_HAS_MD5
-typedef MD5_CTX archive_md5_ctx;
-# define archive_md5_init(ctx) MD5Init(ctx)
-# define archive_md5_final(ctx, buf) MD5Final(buf, ctx)
-# define archive_md5_update(ctx, buf, n) MD5Update(ctx, buf, n)
-#elif defined(ARCHIVE_HASH_MD5_LIBSYSTEM)
-# include <CommonCrypto/CommonDigest.h>
-# define ARCHIVE_HAS_MD5
-typedef CC_MD5_CTX archive_md5_ctx;
-# define archive_md5_init(ctx) CC_MD5_Init(ctx)
-# define archive_md5_final(ctx, buf) CC_MD5_Final(buf, ctx)
-# define archive_md5_update(ctx, buf, n) CC_MD5_Update(ctx, buf, n)
-#elif defined(ARCHIVE_HASH_MD5_OPENSSL)
-# include <openssl/md5.h>
-# define ARCHIVE_HAS_MD5
-typedef MD5_CTX archive_md5_ctx;
-# define archive_md5_init(ctx) MD5_Init(ctx)
-# define archive_md5_final(ctx, buf) MD5_Final(buf, ctx)
-# define archive_md5_update(ctx, buf, n) MD5_Update(ctx, buf, n)
-#elif defined(ARCHIVE_HASH_MD5_WIN)
-# define ARCHIVE_HAS_MD5
-# define MD5_DIGEST_LENGTH 16
-typedef Digest_CTX archive_md5_ctx;
-# define archive_md5_init(ctx) __la_hash_Init(ctx, CALG_MD5)
-# define archive_md5_final(ctx, buf) __la_hash_Final(buf, MD5_DIGEST_LENGTH, ctx)
-# define archive_md5_update(ctx, buf, n) __la_hash_Update(ctx, buf, n)
-#endif
-
-#if defined(ARCHIVE_HASH_RMD160_LIBC)
-# include <rmd160.h>
-# define ARCHIVE_HAS_RMD160
-typedef RMD160_CTX archive_rmd160_ctx;
-# define archive_rmd160_init(ctx) RMD160Init(ctx)
-# define archive_rmd160_final(ctx, buf) RMD160Final(buf, ctx)
-# define archive_rmd160_update(ctx, buf, n) RMD160Update(ctx, buf, n)
-#elif defined(ARCHIVE_HASH_RMD160_OPENSSL)
-# include <openssl/ripemd.h>
-# define ARCHIVE_HAS_RMD160
-typedef RIPEMD160_CTX archive_rmd160_ctx;
-# define archive_rmd160_init(ctx) RIPEMD160_Init(ctx)
-# define archive_rmd160_final(ctx, buf) RIPEMD160_Final(buf, ctx)
-# define archive_rmd160_update(ctx, buf, n) RIPEMD160_Update(ctx, buf, n)
-#endif
-
-#if defined(ARCHIVE_HASH_SHA1_LIBC)
-# include <sha1.h>
-# define ARCHIVE_HAS_SHA1
-typedef SHA1_CTX archive_sha1_ctx;
-# define archive_sha1_init(ctx) SHA1Init(ctx)
-# define archive_sha1_final(ctx, buf) SHA1Final(buf, ctx)
-# define archive_sha1_update(ctx, buf, n) SHA1Update(ctx, buf, n)
-#elif defined(ARCHIVE_HASH_SHA1_LIBMD)
-# include <sha.h>
-# define ARCHIVE_HAS_SHA1
-typedef SHA1_CTX archive_sha1_ctx;
-# define archive_sha1_init(ctx) SHA1_Init(ctx)
-# define archive_sha1_final(ctx, buf) SHA1_Final(buf, ctx)
-# define archive_sha1_update(ctx, buf, n) SHA1_Update(ctx, buf, n)
-#elif defined(ARCHIVE_HASH_SHA1_LIBSYSTEM)
-# include <CommonCrypto/CommonDigest.h>
-# define ARCHIVE_HAS_SHA1
-typedef CC_SHA1_CTX archive_sha1_ctx;
-# define archive_sha1_init(ctx) CC_SHA1_Init(ctx)
-# define archive_sha1_final(ctx, buf) CC_SHA1_Final(buf, ctx)
-# define archive_sha1_update(ctx, buf, n) CC_SHA1_Update(ctx, buf, n)
-#elif defined(ARCHIVE_HASH_SHA1_OPENSSL)
-# include <openssl/sha.h>
-# define ARCHIVE_HAS_SHA1
-typedef SHA_CTX archive_sha1_ctx;
-# define archive_sha1_init(ctx) SHA1_Init(ctx)
-# define archive_sha1_final(ctx, buf) SHA1_Final(buf, ctx)
-# define archive_sha1_update(ctx, buf, n) SHA1_Update(ctx, buf, n)
-#elif defined(ARCHIVE_HASH_SHA1_WIN)
-# define ARCHIVE_HAS_SHA1
-# define SHA1_DIGEST_LENGTH 20
-typedef Digest_CTX archive_sha1_ctx;
-# define archive_sha1_init(ctx) __la_hash_Init(ctx, CALG_SHA1)
-# define archive_sha1_final(ctx, buf) __la_hash_Final(buf, SHA1_DIGEST_LENGTH, ctx)
-# define archive_sha1_update(ctx, buf, n) __la_hash_Update(ctx, buf, n)
-#endif
-
-#if defined(ARCHIVE_HASH_SHA256_LIBC)
-# include <sha2.h>
-# define ARCHIVE_HAS_SHA256
-typedef SHA256_CTX archive_sha256_ctx;
-# define archive_sha256_init(ctx) SHA256_Init(ctx)
-# define archive_sha256_final(ctx, buf) SHA256_Final(buf, ctx)
-# define archive_sha256_update(ctx, buf, n) SHA256_Update(ctx, buf, n)
-#elif defined(ARCHIVE_HASH_SHA256_LIBC2)
-# include <sha2.h>
-# define ARCHIVE_HAS_SHA256
-typedef SHA256_CTX archive_sha256_ctx;
-# define archive_sha256_init(ctx) SHA256Init(ctx)
-# define archive_sha256_final(ctx, buf) SHA256Final(buf, ctx)
-# define archive_sha256_update(ctx, buf, n) SHA256Update(ctx, buf, n)
-#elif defined(ARCHIVE_HASH_SHA256_LIBC3)
-# include <sha2.h>
-# define ARCHIVE_HAS_SHA256
-typedef SHA2_CTX archive_sha256_ctx;
-# define archive_sha256_init(ctx) SHA256Init(ctx)
-# define archive_sha256_final(ctx, buf) SHA256Final(buf, ctx)
-# define archive_sha256_update(ctx, buf, n) SHA256Update(ctx, buf, n)
-#elif defined(ARCHIVE_HASH_SHA256_LIBMD)
-# include <sha256.h>
-# define ARCHIVE_HAS_SHA256
-typedef SHA256_CTX archive_sha256_ctx;
-# define archive_sha256_init(ctx) SHA256_Init(ctx)
-# define archive_sha256_final(ctx, buf) SHA256_Final(buf, ctx)
-# define archive_sha256_update(ctx, buf, n) SHA256_Update(ctx, buf, n)
-#elif defined(ARCHIVE_HASH_SHA256_LIBSYSTEM)
-# include <CommonCrypto/CommonDigest.h>
-# define ARCHIVE_HAS_SHA256
-typedef CC_SHA256_CTX archive_shs256_ctx;
-# define archive_shs256_init(ctx) CC_SHA256_Init(ctx)
-# define archive_shs256_final(ctx, buf) CC_SHA256_Final(buf, ctx)
-# define archive_shs256_update(ctx, buf, n) CC_SHA256_Update(ctx, buf, n)
-#elif defined(ARCHIVE_HASH_SHA256_OPENSSL)
-# include <openssl/sha.h>
-# define ARCHIVE_HAS_SHA256
-typedef SHA256_CTX archive_sha256_ctx;
-# define archive_sha256_init(ctx) SHA256_Init(ctx)
-# define archive_sha256_final(ctx, buf) SHA256_Final(buf, ctx)
-# define archive_sha256_update(ctx, buf, n) SHA256_Update(ctx, buf, n)
-#elif defined(ARCHIVE_HASH_SHA256_WIN)
-# define ARCHIVE_HAS_SHA256
-# define SHA256_DIGEST_LENGTH 32
-typedef Digest_CTX archive_sha256_ctx;
-# define archive_sha256_init(ctx) __la_hash_Init(ctx, CALG_SHA_256)
-# define archive_sha256_final(ctx, buf) __la_hash_Final(buf, SHA256_DIGEST_LENGTH, ctx)
-# define archive_sha256_update(ctx, buf, n) __la_hash_Update(ctx, buf, n)
-#endif
-
-#if defined(ARCHIVE_HASH_SHA384_LIBC)
-# include <sha2.h>
-# define ARCHIVE_HAS_SHA384
-typedef SHA384_CTX archive_sha384_ctx;
-# define archive_sha384_init(ctx) SHA384_Init(ctx)
-# define archive_sha384_final(ctx, buf) SHA384_Final(buf, ctx)
-# define archive_sha384_update(ctx, buf, n) SHA384_Update(ctx, buf, n)
-#elif defined(ARCHIVE_HASH_SHA384_LIBC2)
-# include <sha2.h>
-# define ARCHIVE_HAS_SHA384
-typedef SHA384_CTX archive_sha384_ctx;
-# define archive_sha384_init(ctx) SHA384Init(ctx)
-# define archive_sha384_final(ctx, buf) SHA384Final(buf, ctx)
-# define archive_sha384_update(ctx, buf, n) SHA384Update(ctx, buf, n)
-#elif defined(ARCHIVE_HASH_SHA384_LIBC3)
-# include <sha2.h>
-# define ARCHIVE_HAS_SHA384
-typedef SHA2_CTX archive_sha384_ctx;
-# define archive_sha384_init(ctx) SHA384Init(ctx)
-# define archive_sha384_final(ctx, buf) SHA384Final(buf, ctx)
-# define archive_sha384_update(ctx, buf, n) SHA384Update(ctx, buf, n)
-#elif defined(ARCHIVE_HASH_SHA384_LIBSYSTEM)
-# include <CommonCrypto/CommonDigest.h>
-# define ARCHIVE_HAS_SHA384
-typedef CC_SHA512_CTX archive_shs384_ctx;
-# define archive_shs384_init(ctx) CC_SHA384_Init(ctx)
-# define archive_shs384_final(ctx, buf) CC_SHA384_Final(buf, ctx)
-# define archive_shs384_update(ctx, buf, n) CC_SHA384_Update(ctx, buf, n)
-#elif defined(ARCHIVE_HASH_SHA384_OPENSSL)
-# include <openssl/sha.h>
-# define ARCHIVE_HAS_SHA384
-typedef SHA512_CTX archive_sha384_ctx;
-# define archive_sha384_init(ctx) SHA384_Init(ctx)
-# define archive_sha384_final(ctx, buf) SHA384_Final(buf, ctx)
-# define archive_sha384_update(ctx, buf, n) SHA384_Update(ctx, buf, n)
-#elif defined(ARCHIVE_HASH_SHA384_WIN)
-# define ARCHIVE_HAS_SHA384
-# define SHA384_DIGEST_LENGTH 48
-typedef Digest_CTX archive_sha384_ctx;
-# define archive_sha384_init(ctx) __la_hash_Init(ctx, CALG_SHA_384)
-# define archive_sha384_final(ctx, buf) __la_hash_Final(buf, SHA384_DIGEST_LENGTH, ctx)
-# define archive_sha384_update(ctx, buf, n) __la_hash_Update(ctx, buf, n)
-#endif
-
-#if defined(ARCHIVE_HASH_SHA512_LIBC)
-# include <sha2.h>
-# define ARCHIVE_HAS_SHA512
-typedef SHA512_CTX archive_sha512_ctx;
-# define archive_sha512_init(ctx) SHA512_Init(ctx)
-# define archive_sha512_final(ctx, buf) SHA512_Final(buf, ctx)
-# define archive_sha512_update(ctx, buf, n) SHA512_Update(ctx, buf, n)
-#elif defined(ARCHIVE_HASH_SHA512_LIBC2)
-# include <sha2.h>
-# define ARCHIVE_HAS_SHA512
-typedef SHA512_CTX archive_sha512_ctx;
-# define archive_sha512_init(ctx) SHA512Init(ctx)
-# define archive_sha512_final(ctx, buf) SHA512Final(buf, ctx)
-# define archive_sha512_update(ctx, buf, n) SHA512Update(ctx, buf, n)
-#elif defined(ARCHIVE_HASH_SHA512_LIBC3)
-# include <sha2.h>
-# define ARCHIVE_HAS_SHA512
-typedef SHA2_CTX archive_sha512_ctx;
-# define archive_sha512_init(ctx) SHA512Init(ctx)
-# define archive_sha512_final(ctx, buf) SHA512Final(buf, ctx)
-# define archive_sha512_update(ctx, buf, n) SHA512Update(ctx, buf, n)
-#elif defined(ARCHIVE_HASH_SHA512_LIBMD)
-# include <sha512.h>
-# define ARCHIVE_HAS_SHA512
-typedef SHA512_CTX archive_sha512_ctx;
-# define archive_sha512_init(ctx) SHA512_Init(ctx)
-# define archive_sha512_final(ctx, buf) SHA512_Final(buf, ctx)
-# define archive_sha512_update(ctx, buf, n) SHA512_Update(ctx, buf, n)
-#elif defined(ARCHIVE_HASH_SHA512_LIBSYSTEM)
-# include <CommonCrypto/CommonDigest.h>
-# define ARCHIVE_HAS_SHA512
-typedef CC_SHA512_CTX archive_shs512_ctx;
-# define archive_shs512_init(ctx) CC_SHA512_Init(ctx)
-# define archive_shs512_final(ctx, buf) CC_SHA512_Final(buf, ctx)
-# define archive_shs512_update(ctx, buf, n) CC_SHA512_Update(ctx, buf, n)
-#elif defined(ARCHIVE_HASH_SHA512_OPENSSL)
-# include <openssl/sha.h>
-# define ARCHIVE_HAS_SHA512
-typedef SHA512_CTX archive_sha512_ctx;
-# define archive_sha512_init(ctx) SHA512_Init(ctx)
-# define archive_sha512_final(ctx, buf) SHA512_Final(buf, ctx)
-# define archive_sha512_update(ctx, buf, n) SHA512_Update(ctx, buf, n)
-#elif defined(ARCHIVE_HASH_SHA512_WIN)
-# define ARCHIVE_HAS_SHA512
-# define SHA512_DIGEST_LENGTH 64
-typedef Digest_CTX archive_sha512_ctx;
-# define archive_sha512_init(ctx) __la_hash_Init(ctx, CALG_SHA_512)
-# define archive_sha512_final(ctx, buf) __la_hash_Final(buf, SHA512_DIGEST_LENGTH, ctx)
-# define archive_sha512_update(ctx, buf, n) __la_hash_Update(ctx, buf, n)
-#endif
diff --git a/libarchive/archive_options.c b/libarchive/archive_options.c
new file mode 100644
index 000000000000..962572c765a6
--- /dev/null
+++ b/libarchive/archive_options.c
@@ -0,0 +1,164 @@
+/*-
+ * Copyright (c) 2011 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+__FBSDID("$FreeBSD$");
+
+#include "archive_options_private.h"
+
+static const char *
+parse_option(const char **str,
+ const char **mod, const char **opt, const char **val);
+
+int
+_archive_set_option(struct archive *a,
+ const char *m, const char *o, const char *v,
+ int magic, const char *fn, option_handler use_option)
+{
+ const char *mp, *op, *vp;
+
+ archive_check_magic(a, magic, ARCHIVE_STATE_NEW, fn);
+
+ mp = m != NULL && m[0] == '\0' ? NULL : m;
+ op = o != NULL && o[0] == '\0' ? NULL : o;
+ vp = v != NULL && v[0] == '\0' ? NULL : v;
+
+ if (op == NULL && vp == NULL)
+ return (ARCHIVE_OK);
+ if (op == NULL)
+ return (ARCHIVE_FAILED);
+
+ return use_option(a, mp, op, vp);
+}
+
+int
+_archive_set_either_option(struct archive *a, const char *m, const char *o, const char *v,
+ option_handler use_format_option, option_handler use_filter_option)
+{
+ int r1, r2;
+
+ if (o == NULL && v == NULL)
+ return (ARCHIVE_OK);
+ if (o == NULL)
+ return (ARCHIVE_FAILED);
+
+ r1 = use_format_option(a, m, o, v);
+ if (r1 == ARCHIVE_FATAL)
+ return (ARCHIVE_FATAL);
+
+ r2 = use_filter_option(a, m, o, v);
+ if (r2 == ARCHIVE_FATAL)
+ return (ARCHIVE_FATAL);
+
+ return r1 > r2 ? r1 : r2;
+}
+
+int
+_archive_set_options(struct archive *a, const char *options,
+ int magic, const char *fn, option_handler use_option)
+{
+ int allok = 1, anyok = 0, r;
+ char *data;
+ const char *s, *mod, *opt, *val;
+
+ archive_check_magic(a, magic, ARCHIVE_STATE_NEW, fn);
+
+ if (options == NULL || options[0] == '\0')
+ return ARCHIVE_OK;
+
+ data = (char *)malloc(strlen(options) + 1);
+ strcpy(data, options);
+ s = (const char *)data;
+
+ do {
+ mod = opt = val = NULL;
+
+ parse_option(&s, &mod, &opt, &val);
+
+ r = use_option(a, mod, opt, val);
+ if (r == ARCHIVE_FATAL) {
+ free(data);
+ return (ARCHIVE_FATAL);
+ }
+ if (r == ARCHIVE_OK)
+ anyok = 1;
+ else
+ allok = 0;
+ } while (s != NULL);
+
+ free(data);
+ return allok ? ARCHIVE_OK : anyok ? ARCHIVE_WARN : ARCHIVE_FAILED;
+}
+
+static const char *
+parse_option(const char **s, const char **m, const char **o, const char **v)
+{
+ const char *end, *mod, *opt, *val;
+ char *p;
+
+ end = NULL;
+ mod = NULL;
+ opt = *s;
+ val = "1";
+
+ p = strchr(opt, ',');
+
+ if (p != NULL) {
+ *p = '\0';
+ end = ((const char *)p) + 1;
+ }
+
+ if (0 == strlen(opt)) {
+ *s = end;
+ *m = NULL;
+ *o = NULL;
+ *v = NULL;
+ return end;
+ }
+
+ p = strchr(opt, ':');
+ if (p != NULL) {
+ *p = '\0';
+ mod = opt;
+ opt = ++p;
+ }
+
+ p = strchr(opt, '=');
+ if (p != NULL) {
+ *p = '\0';
+ val = ++p;
+ } else if (opt[0] == '!') {
+ ++opt;
+ val = NULL;
+ }
+
+ *s = end;
+ *m = mod;
+ *o = opt;
+ *v = val;
+
+ return end;
+}
+
diff --git a/libarchive/archive_options_private.h b/libarchive/archive_options_private.h
new file mode 100644
index 000000000000..6ef0165aff68
--- /dev/null
+++ b/libarchive/archive_options_private.h
@@ -0,0 +1,47 @@
+/*-
+ * Copyright (c) 2011 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+__FBSDID("$FreeBSD$");
+
+#include "archive_private.h"
+
+typedef int (*option_handler)(struct archive *a,
+ const char *mod, const char *opt, const char *val);
+
+int
+_archive_set_option(struct archive *a,
+ const char *mod, const char *opt, const char *val,
+ int magic, const char *fn, option_handler use_option);
+
+int
+_archive_set_options(struct archive *a, const char *options,
+ int magic, const char *fn, option_handler use_option);
+
+int
+_archive_set_either_option(struct archive *a,
+ const char *m, const char *o, const char *v,
+ option_handler use_format_option, option_handler use_filter_option);
+
diff --git a/libarchive/archive_ppmd7.c b/libarchive/archive_ppmd7.c
new file mode 100644
index 000000000000..b2e8c3a34922
--- /dev/null
+++ b/libarchive/archive_ppmd7.c
@@ -0,0 +1,1164 @@
+/* Ppmd7.c -- PPMdH codec
+2010-03-12 : Igor Pavlov : Public domain
+This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
+
+#include "archive_platform.h"
+
+#include <memory.h>
+
+#include "archive_ppmd7_private.h"
+
+#ifdef PPMD_32BIT
+ #define Ppmd7_GetPtr(p, ptr) (ptr)
+ #define Ppmd7_GetContext(p, ptr) (ptr)
+ #define Ppmd7_GetStats(p, ctx) ((ctx)->Stats)
+#else
+ #define Ppmd7_GetPtr(p, offs) ((void *)((p)->Base + (offs)))
+ #define Ppmd7_GetContext(p, offs) ((CPpmd7_Context *)Ppmd7_GetPtr((p), (offs)))
+ #define Ppmd7_GetStats(p, ctx) ((CPpmd_State *)Ppmd7_GetPtr((p), ((ctx)->Stats)))
+#endif
+
+#define Ppmd7_GetBinSumm(p) \
+ &p->BinSumm[Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \
+ p->NS2BSIndx[Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \
+ (p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \
+ 2 * p->HB2Flag[Ppmd7Context_OneState(p->MinContext)->Symbol] + \
+ ((p->RunLength >> 26) & 0x20)]
+
+#define kTopValue (1 << 24)
+#define MAX_FREQ 124
+#define UNIT_SIZE 12
+
+#define U2B(nu) ((UInt32)(nu) * UNIT_SIZE)
+#define U2I(nu) (p->Units2Indx[(nu) - 1])
+#define I2U(indx) (p->Indx2Units[indx])
+
+#ifdef PPMD_32BIT
+ #define REF(ptr) (ptr)
+#else
+ #define REF(ptr) ((UInt32)((Byte *)(ptr) - (p)->Base))
+#endif
+
+#define STATS_REF(ptr) ((CPpmd_State_Ref)REF(ptr))
+
+#define CTX(ref) ((CPpmd7_Context *)Ppmd7_GetContext(p, ref))
+#define STATS(ctx) Ppmd7_GetStats(p, ctx)
+#define ONE_STATE(ctx) Ppmd7Context_OneState(ctx)
+#define SUFFIX(ctx) CTX((ctx)->Suffix)
+
+static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051};
+static const Byte PPMD7_kExpEscape[16] = { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 };
+
+typedef CPpmd7_Context * CTX_PTR;
+
+struct CPpmd7_Node_;
+
+typedef
+ #ifdef PPMD_32BIT
+ struct CPpmd7_Node_ *
+ #else
+ UInt32
+ #endif
+ CPpmd7_Node_Ref;
+
+typedef struct CPpmd7_Node_
+{
+ UInt16 Stamp; /* must be at offset 0 as CPpmd7_Context::NumStats. Stamp=0 means free */
+ UInt16 NU;
+ CPpmd7_Node_Ref Next; /* must be at offset >= 4 */
+ CPpmd7_Node_Ref Prev;
+} CPpmd7_Node;
+
+#ifdef PPMD_32BIT
+ #define NODE(ptr) (ptr)
+#else
+ #define NODE(offs) ((CPpmd7_Node *)(p->Base + (offs)))
+#endif
+
+static void Ppmd7_Update1(CPpmd7 *p);
+static void Ppmd7_Update1_0(CPpmd7 *p);
+static void Ppmd7_Update2(CPpmd7 *p);
+static void Ppmd7_UpdateBin(CPpmd7 *p);
+static CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked,
+ UInt32 *scale);
+
+/* ----------- Base ----------- */
+
+static void Ppmd7_Construct(CPpmd7 *p)
+{
+ unsigned i, k, m;
+
+ p->Base = 0;
+
+ for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++)
+ {
+ unsigned step = (i >= 12 ? 4 : (i >> 2) + 1);
+ do { p->Units2Indx[k++] = (Byte)i; } while(--step);
+ p->Indx2Units[i] = (Byte)k;
+ }
+
+ p->NS2BSIndx[0] = (0 << 1);
+ p->NS2BSIndx[1] = (1 << 1);
+ memset(p->NS2BSIndx + 2, (2 << 1), 9);
+ memset(p->NS2BSIndx + 11, (3 << 1), 256 - 11);
+
+ for (i = 0; i < 3; i++)
+ p->NS2Indx[i] = (Byte)i;
+ for (m = i, k = 1; i < 256; i++)
+ {
+ p->NS2Indx[i] = (Byte)m;
+ if (--k == 0)
+ k = (++m) - 2;
+ }
+
+ memset(p->HB2Flag, 0, 0x40);
+ memset(p->HB2Flag + 0x40, 8, 0x100 - 0x40);
+}
+
+static void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc)
+{
+ alloc->Free(alloc, p->Base);
+ p->Size = 0;
+ p->Base = 0;
+}
+
+static Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc)
+{
+ if (p->Base == 0 || p->Size != size)
+ {
+ Ppmd7_Free(p, alloc);
+ p->AlignOffset =
+ #ifdef PPMD_32BIT
+ (4 - size) & 3;
+ #else
+ 4 - (size & 3);
+ #endif
+ if ((p->Base = (Byte *)alloc->Alloc(alloc, p->AlignOffset + size
+ #ifndef PPMD_32BIT
+ + UNIT_SIZE
+ #endif
+ )) == 0)
+ return False;
+ p->Size = size;
+ }
+ return True;
+}
+
+static void InsertNode(CPpmd7 *p, void *node, unsigned indx)
+{
+ *((CPpmd_Void_Ref *)node) = p->FreeList[indx];
+ p->FreeList[indx] = REF(node);
+}
+
+static void *RemoveNode(CPpmd7 *p, unsigned indx)
+{
+ CPpmd_Void_Ref *node = (CPpmd_Void_Ref *)Ppmd7_GetPtr(p, p->FreeList[indx]);
+ p->FreeList[indx] = *node;
+ return node;
+}
+
+static void SplitBlock(CPpmd7 *p, void *ptr, unsigned oldIndx, unsigned newIndx)
+{
+ unsigned i, nu = I2U(oldIndx) - I2U(newIndx);
+ ptr = (Byte *)ptr + U2B(I2U(newIndx));
+ if (I2U(i = U2I(nu)) != nu)
+ {
+ unsigned k = I2U(--i);
+ InsertNode(p, ((Byte *)ptr) + U2B(k), nu - k - 1);
+ }
+ InsertNode(p, ptr, i);
+}
+
+static void GlueFreeBlocks(CPpmd7 *p)
+{
+ #ifdef PPMD_32BIT
+ CPpmd7_Node headItem;
+ CPpmd7_Node_Ref head = &headItem;
+ #else
+ CPpmd7_Node_Ref head = p->AlignOffset + p->Size;
+ #endif
+
+ CPpmd7_Node_Ref n = head;
+ unsigned i;
+
+ p->GlueCount = 255;
+
+ /* create doubly-linked list of free blocks */
+ for (i = 0; i < PPMD_NUM_INDEXES; i++)
+ {
+ UInt16 nu = I2U(i);
+ CPpmd7_Node_Ref next = (CPpmd7_Node_Ref)p->FreeList[i];
+ p->FreeList[i] = 0;
+ while (next != 0)
+ {
+ CPpmd7_Node *node = NODE(next);
+ node->Next = n;
+ n = NODE(n)->Prev = next;
+ next = *(const CPpmd7_Node_Ref *)node;
+ node->Stamp = 0;
+ node->NU = (UInt16)nu;
+ }
+ }
+ NODE(head)->Stamp = 1;
+ NODE(head)->Next = n;
+ NODE(n)->Prev = head;
+ if (p->LoUnit != p->HiUnit)
+ ((CPpmd7_Node *)p->LoUnit)->Stamp = 1;
+
+ /* Glue free blocks */
+ while (n != head)
+ {
+ CPpmd7_Node *node = NODE(n);
+ UInt32 nu = (UInt32)node->NU;
+ for (;;)
+ {
+ CPpmd7_Node *node2 = NODE(n) + nu;
+ nu += node2->NU;
+ if (node2->Stamp != 0 || nu >= 0x10000)
+ break;
+ NODE(node2->Prev)->Next = node2->Next;
+ NODE(node2->Next)->Prev = node2->Prev;
+ node->NU = (UInt16)nu;
+ }
+ n = node->Next;
+ }
+
+ /* Fill lists of free blocks */
+ for (n = NODE(head)->Next; n != head;)
+ {
+ CPpmd7_Node *node = NODE(n);
+ unsigned nu;
+ CPpmd7_Node_Ref next = node->Next;
+ for (nu = node->NU; nu > 128; nu -= 128, node += 128)
+ InsertNode(p, node, PPMD_NUM_INDEXES - 1);
+ if (I2U(i = U2I(nu)) != nu)
+ {
+ unsigned k = I2U(--i);
+ InsertNode(p, node + k, nu - k - 1);
+ }
+ InsertNode(p, node, i);
+ n = next;
+ }
+}
+
+static void *AllocUnitsRare(CPpmd7 *p, unsigned indx)
+{
+ unsigned i;
+ void *retVal;
+ if (p->GlueCount == 0)
+ {
+ GlueFreeBlocks(p);
+ if (p->FreeList[indx] != 0)
+ return RemoveNode(p, indx);
+ }
+ i = indx;
+ do
+ {
+ if (++i == PPMD_NUM_INDEXES)
+ {
+ UInt32 numBytes = U2B(I2U(indx));
+ p->GlueCount--;
+ return ((UInt32)(p->UnitsStart - p->Text) > numBytes) ? (p->UnitsStart -= numBytes) : (NULL);
+ }
+ }
+ while (p->FreeList[i] == 0);
+ retVal = RemoveNode(p, i);
+ SplitBlock(p, retVal, i, indx);
+ return retVal;
+}
+
+static void *AllocUnits(CPpmd7 *p, unsigned indx)
+{
+ UInt32 numBytes;
+ if (p->FreeList[indx] != 0)
+ return RemoveNode(p, indx);
+ numBytes = U2B(I2U(indx));
+ if (numBytes <= (UInt32)(p->HiUnit - p->LoUnit))
+ {
+ void *retVal = p->LoUnit;
+ p->LoUnit += numBytes;
+ return retVal;
+ }
+ return AllocUnitsRare(p, indx);
+}
+
+#define MyMem12Cpy(dest, src, num) \
+ { UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \
+ do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while(--n); }
+
+static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU)
+{
+ unsigned i0 = U2I(oldNU);
+ unsigned i1 = U2I(newNU);
+ if (i0 == i1)
+ return oldPtr;
+ if (p->FreeList[i1] != 0)
+ {
+ void *ptr = RemoveNode(p, i1);
+ MyMem12Cpy(ptr, oldPtr, newNU);
+ InsertNode(p, oldPtr, i0);
+ return ptr;
+ }
+ SplitBlock(p, oldPtr, i0, i1);
+ return oldPtr;
+}
+
+#define SUCCESSOR(p) ((CPpmd_Void_Ref)((p)->SuccessorLow | ((UInt32)(p)->SuccessorHigh << 16)))
+
+static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v)
+{
+ (p)->SuccessorLow = (UInt16)((UInt32)(v) & 0xFFFF);
+ (p)->SuccessorHigh = (UInt16)(((UInt32)(v) >> 16) & 0xFFFF);
+}
+
+static void RestartModel(CPpmd7 *p)
+{
+ unsigned i, k, m;
+
+ memset(p->FreeList, 0, sizeof(p->FreeList));
+ p->Text = p->Base + p->AlignOffset;
+ p->HiUnit = p->Text + p->Size;
+ p->LoUnit = p->UnitsStart = p->HiUnit - p->Size / 8 / UNIT_SIZE * 7 * UNIT_SIZE;
+ p->GlueCount = 0;
+
+ p->OrderFall = p->MaxOrder;
+ p->RunLength = p->InitRL = -(Int32)((p->MaxOrder < 12) ? p->MaxOrder : 12) - 1;
+ p->PrevSuccess = 0;
+
+ p->MinContext = p->MaxContext = (CTX_PTR)(p->HiUnit -= UNIT_SIZE); /* AllocContext(p); */
+ p->MinContext->Suffix = 0;
+ p->MinContext->NumStats = 256;
+ p->MinContext->SummFreq = 256 + 1;
+ p->FoundState = (CPpmd_State *)p->LoUnit; /* AllocUnits(p, PPMD_NUM_INDEXES - 1); */
+ p->LoUnit += U2B(256 / 2);
+ p->MinContext->Stats = REF(p->FoundState);
+ for (i = 0; i < 256; i++)
+ {
+ CPpmd_State *s = &p->FoundState[i];
+ s->Symbol = (Byte)i;
+ s->Freq = 1;
+ SetSuccessor(s, 0);
+ }
+
+ for (i = 0; i < 128; i++)
+ for (k = 0; k < 8; k++)
+ {
+ UInt16 *dest = p->BinSumm[i] + k;
+ UInt16 val = (UInt16)(PPMD_BIN_SCALE - kInitBinEsc[k] / (i + 2));
+ for (m = 0; m < 64; m += 8)
+ dest[m] = val;
+ }
+
+ for (i = 0; i < 25; i++)
+ for (k = 0; k < 16; k++)
+ {
+ CPpmd_See *s = &p->See[i][k];
+ s->Summ = (UInt16)((5 * i + 10) << (s->Shift = PPMD_PERIOD_BITS - 4));
+ s->Count = 4;
+ }
+}
+
+static void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder)
+{
+ p->MaxOrder = maxOrder;
+ RestartModel(p);
+ p->DummySee.Shift = PPMD_PERIOD_BITS;
+ p->DummySee.Summ = 0; /* unused */
+ p->DummySee.Count = 64; /* unused */
+}
+
+static CTX_PTR CreateSuccessors(CPpmd7 *p, Bool skip)
+{
+ CPpmd_State upState;
+ CTX_PTR c = p->MinContext;
+ CPpmd_Byte_Ref upBranch = (CPpmd_Byte_Ref)SUCCESSOR(p->FoundState);
+ CPpmd_State *ps[PPMD7_MAX_ORDER];
+ unsigned numPs = 0;
+
+ if (!skip)
+ ps[numPs++] = p->FoundState;
+
+ while (c->Suffix)
+ {
+ CPpmd_Void_Ref successor;
+ CPpmd_State *s;
+ c = SUFFIX(c);
+ if (c->NumStats != 1)
+ {
+ for (s = STATS(c); s->Symbol != p->FoundState->Symbol; s++);
+ }
+ else
+ s = ONE_STATE(c);
+ successor = SUCCESSOR(s);
+ if (successor != upBranch)
+ {
+ c = CTX(successor);
+ if (numPs == 0)
+ return c;
+ break;
+ }
+ ps[numPs++] = s;
+ }
+
+ upState.Symbol = *(const Byte *)Ppmd7_GetPtr(p, upBranch);
+ SetSuccessor(&upState, upBranch + 1);
+
+ if (c->NumStats == 1)
+ upState.Freq = ONE_STATE(c)->Freq;
+ else
+ {
+ UInt32 cf, s0;
+ CPpmd_State *s;
+ for (s = STATS(c); s->Symbol != upState.Symbol; s++);
+ cf = s->Freq - 1;
+ s0 = c->SummFreq - c->NumStats - cf;
+ upState.Freq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : ((2 * cf + 3 * s0 - 1) / (2 * s0))));
+ }
+
+ do
+ {
+ /* Create Child */
+ CTX_PTR c1; /* = AllocContext(p); */
+ if (p->HiUnit != p->LoUnit)
+ c1 = (CTX_PTR)(p->HiUnit -= UNIT_SIZE);
+ else if (p->FreeList[0] != 0)
+ c1 = (CTX_PTR)RemoveNode(p, 0);
+ else
+ {
+ c1 = (CTX_PTR)AllocUnitsRare(p, 0);
+ if (!c1)
+ return NULL;
+ }
+ c1->NumStats = 1;
+ *ONE_STATE(c1) = upState;
+ c1->Suffix = REF(c);
+ SetSuccessor(ps[--numPs], REF(c1));
+ c = c1;
+ }
+ while (numPs != 0);
+
+ return c;
+}
+
+static void SwapStates(CPpmd_State *t1, CPpmd_State *t2)
+{
+ CPpmd_State tmp = *t1;
+ *t1 = *t2;
+ *t2 = tmp;
+}
+
+static void UpdateModel(CPpmd7 *p)
+{
+ CPpmd_Void_Ref successor, fSuccessor = SUCCESSOR(p->FoundState);
+ CTX_PTR c;
+ unsigned s0, ns;
+
+ if (p->FoundState->Freq < MAX_FREQ / 4 && p->MinContext->Suffix != 0)
+ {
+ c = SUFFIX(p->MinContext);
+
+ if (c->NumStats == 1)
+ {
+ CPpmd_State *s = ONE_STATE(c);
+ if (s->Freq < 32)
+ s->Freq++;
+ }
+ else
+ {
+ CPpmd_State *s = STATS(c);
+ if (s->Symbol != p->FoundState->Symbol)
+ {
+ do { s++; } while (s->Symbol != p->FoundState->Symbol);
+ if (s[0].Freq >= s[-1].Freq)
+ {
+ SwapStates(&s[0], &s[-1]);
+ s--;
+ }
+ }
+ if (s->Freq < MAX_FREQ - 9)
+ {
+ s->Freq += 2;
+ c->SummFreq += 2;
+ }
+ }
+ }
+
+ if (p->OrderFall == 0)
+ {
+ p->MinContext = p->MaxContext = CreateSuccessors(p, True);
+ if (p->MinContext == 0)
+ {
+ RestartModel(p);
+ return;
+ }
+ SetSuccessor(p->FoundState, REF(p->MinContext));
+ return;
+ }
+
+ *p->Text++ = p->FoundState->Symbol;
+ successor = REF(p->Text);
+ if (p->Text >= p->UnitsStart)
+ {
+ RestartModel(p);
+ return;
+ }
+
+ if (fSuccessor)
+ {
+ if (fSuccessor <= successor)
+ {
+ CTX_PTR cs = CreateSuccessors(p, False);
+ if (cs == NULL)
+ {
+ RestartModel(p);
+ return;
+ }
+ fSuccessor = REF(cs);
+ }
+ if (--p->OrderFall == 0)
+ {
+ successor = fSuccessor;
+ p->Text -= (p->MaxContext != p->MinContext);
+ }
+ }
+ else
+ {
+ SetSuccessor(p->FoundState, successor);
+ fSuccessor = REF(p->MinContext);
+ }
+
+ s0 = p->MinContext->SummFreq - (ns = p->MinContext->NumStats) - (p->FoundState->Freq - 1);
+
+ for (c = p->MaxContext; c != p->MinContext; c = SUFFIX(c))
+ {
+ unsigned ns1;
+ UInt32 cf, sf;
+ if ((ns1 = c->NumStats) != 1)
+ {
+ if ((ns1 & 1) == 0)
+ {
+ /* Expand for one UNIT */
+ unsigned oldNU = ns1 >> 1;
+ unsigned i = U2I(oldNU);
+ if (i != U2I(oldNU + 1))
+ {
+ void *ptr = AllocUnits(p, i + 1);
+ void *oldPtr;
+ if (!ptr)
+ {
+ RestartModel(p);
+ return;
+ }
+ oldPtr = STATS(c);
+ MyMem12Cpy(ptr, oldPtr, oldNU);
+ InsertNode(p, oldPtr, i);
+ c->Stats = STATS_REF(ptr);
+ }
+ }
+ c->SummFreq = (UInt16)(c->SummFreq + (2 * ns1 < ns) + 2 * ((4 * ns1 <= ns) & (c->SummFreq <= 8 * ns1)));
+ }
+ else
+ {
+ CPpmd_State *s = (CPpmd_State*)AllocUnits(p, 0);
+ if (!s)
+ {
+ RestartModel(p);
+ return;
+ }
+ *s = *ONE_STATE(c);
+ c->Stats = REF(s);
+ if (s->Freq < MAX_FREQ / 4 - 1)
+ s->Freq <<= 1;
+ else
+ s->Freq = MAX_FREQ - 4;
+ c->SummFreq = (UInt16)(s->Freq + p->InitEsc + (ns > 3));
+ }
+ cf = 2 * (UInt32)p->FoundState->Freq * (c->SummFreq + 6);
+ sf = (UInt32)s0 + c->SummFreq;
+ if (cf < 6 * sf)
+ {
+ cf = 1 + (cf > sf) + (cf >= 4 * sf);
+ c->SummFreq += 3;
+ }
+ else
+ {
+ cf = 4 + (cf >= 9 * sf) + (cf >= 12 * sf) + (cf >= 15 * sf);
+ c->SummFreq = (UInt16)(c->SummFreq + cf);
+ }
+ {
+ CPpmd_State *s = STATS(c) + ns1;
+ SetSuccessor(s, successor);
+ s->Symbol = p->FoundState->Symbol;
+ s->Freq = (Byte)cf;
+ c->NumStats = (UInt16)(ns1 + 1);
+ }
+ }
+ p->MaxContext = p->MinContext = CTX(fSuccessor);
+}
+
+static void Rescale(CPpmd7 *p)
+{
+ unsigned i, adder, sumFreq, escFreq;
+ CPpmd_State *stats = STATS(p->MinContext);
+ CPpmd_State *s = p->FoundState;
+ {
+ CPpmd_State tmp = *s;
+ for (; s != stats; s--)
+ s[0] = s[-1];
+ *s = tmp;
+ }
+ escFreq = p->MinContext->SummFreq - s->Freq;
+ s->Freq += 4;
+ adder = (p->OrderFall != 0);
+ s->Freq = (Byte)((s->Freq + adder) >> 1);
+ sumFreq = s->Freq;
+
+ i = p->MinContext->NumStats - 1;
+ do
+ {
+ escFreq -= (++s)->Freq;
+ s->Freq = (Byte)((s->Freq + adder) >> 1);
+ sumFreq += s->Freq;
+ if (s[0].Freq > s[-1].Freq)
+ {
+ CPpmd_State *s1 = s;
+ CPpmd_State tmp = *s1;
+ do
+ s1[0] = s1[-1];
+ while (--s1 != stats && tmp.Freq > s1[-1].Freq);
+ *s1 = tmp;
+ }
+ }
+ while (--i);
+
+ if (s->Freq == 0)
+ {
+ unsigned numStats = p->MinContext->NumStats;
+ unsigned n0, n1;
+ do { i++; } while ((--s)->Freq == 0);
+ escFreq += i;
+ p->MinContext->NumStats = (UInt16)(p->MinContext->NumStats - i);
+ if (p->MinContext->NumStats == 1)
+ {
+ CPpmd_State tmp = *stats;
+ do
+ {
+ tmp.Freq = (Byte)(tmp.Freq - (tmp.Freq >> 1));
+ escFreq >>= 1;
+ }
+ while (escFreq > 1);
+ InsertNode(p, stats, U2I(((numStats + 1) >> 1)));
+ *(p->FoundState = ONE_STATE(p->MinContext)) = tmp;
+ return;
+ }
+ n0 = (numStats + 1) >> 1;
+ n1 = (p->MinContext->NumStats + 1) >> 1;
+ if (n0 != n1)
+ p->MinContext->Stats = STATS_REF(ShrinkUnits(p, stats, n0, n1));
+ }
+ p->MinContext->SummFreq = (UInt16)(sumFreq + escFreq - (escFreq >> 1));
+ p->FoundState = STATS(p->MinContext);
+}
+
+static CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *escFreq)
+{
+ CPpmd_See *see;
+ unsigned nonMasked = p->MinContext->NumStats - numMasked;
+ if (p->MinContext->NumStats != 256)
+ {
+ see = p->See[p->NS2Indx[nonMasked - 1]] +
+ (nonMasked < (unsigned)SUFFIX(p->MinContext)->NumStats - p->MinContext->NumStats) +
+ 2 * (p->MinContext->SummFreq < 11 * p->MinContext->NumStats) +
+ 4 * (numMasked > nonMasked) +
+ p->HiBitsFlag;
+ {
+ unsigned r = (see->Summ >> see->Shift);
+ see->Summ = (UInt16)(see->Summ - r);
+ *escFreq = r + (r == 0);
+ }
+ }
+ else
+ {
+ see = &p->DummySee;
+ *escFreq = 1;
+ }
+ return see;
+}
+
+static void NextContext(CPpmd7 *p)
+{
+ CTX_PTR c = CTX(SUCCESSOR(p->FoundState));
+ if (p->OrderFall == 0 && (Byte *)c > p->Text)
+ p->MinContext = p->MaxContext = c;
+ else
+ UpdateModel(p);
+}
+
+static void Ppmd7_Update1(CPpmd7 *p)
+{
+ CPpmd_State *s = p->FoundState;
+ s->Freq += 4;
+ p->MinContext->SummFreq += 4;
+ if (s[0].Freq > s[-1].Freq)
+ {
+ SwapStates(&s[0], &s[-1]);
+ p->FoundState = --s;
+ if (s->Freq > MAX_FREQ)
+ Rescale(p);
+ }
+ NextContext(p);
+}
+
+static void Ppmd7_Update1_0(CPpmd7 *p)
+{
+ p->PrevSuccess = (2 * p->FoundState->Freq > p->MinContext->SummFreq);
+ p->RunLength += p->PrevSuccess;
+ p->MinContext->SummFreq += 4;
+ if ((p->FoundState->Freq += 4) > MAX_FREQ)
+ Rescale(p);
+ NextContext(p);
+}
+
+static void Ppmd7_UpdateBin(CPpmd7 *p)
+{
+ p->FoundState->Freq = (Byte)(p->FoundState->Freq + (p->FoundState->Freq < 128 ? 1: 0));
+ p->PrevSuccess = 1;
+ p->RunLength++;
+ NextContext(p);
+}
+
+static void Ppmd7_Update2(CPpmd7 *p)
+{
+ p->MinContext->SummFreq += 4;
+ if ((p->FoundState->Freq += 4) > MAX_FREQ)
+ Rescale(p);
+ p->RunLength = p->InitRL;
+ UpdateModel(p);
+}
+
+/* ---------- Decode ---------- */
+
+static Bool Ppmd_RangeDec_Init(CPpmd7z_RangeDec *p)
+{
+ unsigned i;
+ p->Low = p->Bottom = 0;
+ p->Range = 0xFFFFFFFF;
+ for (i = 0; i < 4; i++)
+ p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
+ return (p->Code < 0xFFFFFFFF);
+}
+
+static Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p)
+{
+ if (p->Stream->Read((void *)p->Stream) != 0)
+ return False;
+ return Ppmd_RangeDec_Init(p);
+}
+
+static Bool PpmdRAR_RangeDec_Init(CPpmd7z_RangeDec *p)
+{
+ if (!Ppmd_RangeDec_Init(p))
+ return False;
+ p->Bottom = 0x8000;
+ return True;
+}
+
+static UInt32 Range_GetThreshold(void *pp, UInt32 total)
+{
+ CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
+ return (p->Code - p->Low) / (p->Range /= total);
+}
+
+static void Range_Normalize(CPpmd7z_RangeDec *p)
+{
+ while (1)
+ {
+ if((p->Low ^ (p->Low + p->Range)) >= kTopValue)
+ {
+ if(p->Range >= p->Bottom)
+ break;
+ else
+ p->Range = -p->Low & (p->Bottom - 1);
+ }
+ p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
+ p->Range <<= 8;
+ p->Low <<= 8;
+ }
+}
+
+static void Range_Decode_7z(void *pp, UInt32 start, UInt32 size)
+{
+ CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
+ p->Code -= start * p->Range;
+ p->Range *= size;
+ Range_Normalize(p);
+}
+
+static void Range_Decode_RAR(void *pp, UInt32 start, UInt32 size)
+{
+ CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
+ p->Low += start * p->Range;
+ p->Range *= size;
+ Range_Normalize(p);
+}
+
+static UInt32 Range_DecodeBit_7z(void *pp, UInt32 size0)
+{
+ CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
+ UInt32 newBound = (p->Range >> 14) * size0;
+ UInt32 symbol;
+ if (p->Code < newBound)
+ {
+ symbol = 0;
+ p->Range = newBound;
+ }
+ else
+ {
+ symbol = 1;
+ p->Code -= newBound;
+ p->Range -= newBound;
+ }
+ Range_Normalize(p);
+ return symbol;
+}
+
+static UInt32 Range_DecodeBit_RAR(void *pp, UInt32 size0)
+{
+ CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
+ UInt32 bit, value = p->p.GetThreshold(p, PPMD_BIN_SCALE);
+ if(value < size0)
+ {
+ bit = 0;
+ p->p.Decode(p, 0, size0);
+ }
+ else
+ {
+ bit = 1;
+ p->p.Decode(p, size0, PPMD_BIN_SCALE - size0);
+ }
+ return bit;
+}
+
+static void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p)
+{
+ p->p.GetThreshold = Range_GetThreshold;
+ p->p.Decode = Range_Decode_7z;
+ p->p.DecodeBit = Range_DecodeBit_7z;
+}
+
+static void PpmdRAR_RangeDec_CreateVTable(CPpmd7z_RangeDec *p)
+{
+ p->p.GetThreshold = Range_GetThreshold;
+ p->p.Decode = Range_Decode_RAR;
+ p->p.DecodeBit = Range_DecodeBit_RAR;
+}
+
+#define MASK(sym) ((signed char *)charMask)[sym]
+
+static int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc)
+{
+ size_t charMask[256 / sizeof(size_t)];
+ if (p->MinContext->NumStats != 1)
+ {
+ CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext);
+ unsigned i;
+ UInt32 count, hiCnt;
+ if ((count = rc->GetThreshold(rc, p->MinContext->SummFreq)) < (hiCnt = s->Freq))
+ {
+ Byte symbol;
+ rc->Decode(rc, 0, s->Freq);
+ p->FoundState = s;
+ symbol = s->Symbol;
+ Ppmd7_Update1_0(p);
+ return symbol;
+ }
+ p->PrevSuccess = 0;
+ i = p->MinContext->NumStats - 1;
+ do
+ {
+ if ((hiCnt += (++s)->Freq) > count)
+ {
+ Byte symbol;
+ rc->Decode(rc, hiCnt - s->Freq, s->Freq);
+ p->FoundState = s;
+ symbol = s->Symbol;
+ Ppmd7_Update1(p);
+ return symbol;
+ }
+ }
+ while (--i);
+ if (count >= p->MinContext->SummFreq)
+ return -2;
+ p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol];
+ rc->Decode(rc, hiCnt, p->MinContext->SummFreq - hiCnt);
+ PPMD_SetAllBitsIn256Bytes(charMask);
+ MASK(s->Symbol) = 0;
+ i = p->MinContext->NumStats - 1;
+ do { MASK((--s)->Symbol) = 0; } while (--i);
+ }
+ else
+ {
+ UInt16 *prob = Ppmd7_GetBinSumm(p);
+ if (rc->DecodeBit(rc, *prob) == 0)
+ {
+ Byte symbol;
+ *prob = (UInt16)PPMD_UPDATE_PROB_0(*prob);
+ symbol = (p->FoundState = Ppmd7Context_OneState(p->MinContext))->Symbol;
+ Ppmd7_UpdateBin(p);
+ return symbol;
+ }
+ *prob = (UInt16)PPMD_UPDATE_PROB_1(*prob);
+ p->InitEsc = PPMD7_kExpEscape[*prob >> 10];
+ PPMD_SetAllBitsIn256Bytes(charMask);
+ MASK(Ppmd7Context_OneState(p->MinContext)->Symbol) = 0;
+ p->PrevSuccess = 0;
+ }
+ for (;;)
+ {
+ CPpmd_State *ps[256], *s;
+ UInt32 freqSum, count, hiCnt;
+ CPpmd_See *see;
+ unsigned i, num, numMasked = p->MinContext->NumStats;
+ do
+ {
+ p->OrderFall++;
+ if (!p->MinContext->Suffix)
+ return -1;
+ p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix);
+ }
+ while (p->MinContext->NumStats == numMasked);
+ hiCnt = 0;
+ s = Ppmd7_GetStats(p, p->MinContext);
+ i = 0;
+ num = p->MinContext->NumStats - numMasked;
+ do
+ {
+ int k = (int)(MASK(s->Symbol));
+ hiCnt += (s->Freq & k);
+ ps[i] = s++;
+ i -= k;
+ }
+ while (i != num);
+
+ see = Ppmd7_MakeEscFreq(p, numMasked, &freqSum);
+ freqSum += hiCnt;
+ count = rc->GetThreshold(rc, freqSum);
+
+ if (count < hiCnt)
+ {
+ Byte symbol;
+ CPpmd_State **pps = ps;
+ for (hiCnt = 0; (hiCnt += (*pps)->Freq) <= count; pps++);
+ s = *pps;
+ rc->Decode(rc, hiCnt - s->Freq, s->Freq);
+ Ppmd_See_Update(see);
+ p->FoundState = s;
+ symbol = s->Symbol;
+ Ppmd7_Update2(p);
+ return symbol;
+ }
+ if (count >= freqSum)
+ return -2;
+ rc->Decode(rc, hiCnt, freqSum - hiCnt);
+ see->Summ = (UInt16)(see->Summ + freqSum);
+ do { MASK(ps[--i]->Symbol) = 0; } while (i != 0);
+ }
+}
+
+/* ---------- Encode ---------- Ppmd7Enc.c */
+
+#define kTopValue (1 << 24)
+
+static void Ppmd7z_RangeEnc_Init(CPpmd7z_RangeEnc *p)
+{
+ p->Low = 0;
+ p->Range = 0xFFFFFFFF;
+ p->Cache = 0;
+ p->CacheSize = 1;
+}
+
+static void RangeEnc_ShiftLow(CPpmd7z_RangeEnc *p)
+{
+ if ((UInt32)p->Low < (UInt32)0xFF000000 || (unsigned)(p->Low >> 32) != 0)
+ {
+ Byte temp = p->Cache;
+ do
+ {
+ p->Stream->Write(p->Stream, (Byte)(temp + (Byte)(p->Low >> 32)));
+ temp = 0xFF;
+ }
+ while(--p->CacheSize != 0);
+ p->Cache = (Byte)((UInt32)p->Low >> 24);
+ }
+ p->CacheSize++;
+ p->Low = (UInt32)p->Low << 8;
+}
+
+static void RangeEnc_Encode(CPpmd7z_RangeEnc *p, UInt32 start, UInt32 size, UInt32 total)
+{
+ p->Low += start * (p->Range /= total);
+ p->Range *= size;
+ while (p->Range < kTopValue)
+ {
+ p->Range <<= 8;
+ RangeEnc_ShiftLow(p);
+ }
+}
+
+static void RangeEnc_EncodeBit_0(CPpmd7z_RangeEnc *p, UInt32 size0)
+{
+ p->Range = (p->Range >> 14) * size0;
+ while (p->Range < kTopValue)
+ {
+ p->Range <<= 8;
+ RangeEnc_ShiftLow(p);
+ }
+}
+
+static void RangeEnc_EncodeBit_1(CPpmd7z_RangeEnc *p, UInt32 size0)
+{
+ UInt32 newBound = (p->Range >> 14) * size0;
+ p->Low += newBound;
+ p->Range -= newBound;
+ while (p->Range < kTopValue)
+ {
+ p->Range <<= 8;
+ RangeEnc_ShiftLow(p);
+ }
+}
+
+static void Ppmd7z_RangeEnc_FlushData(CPpmd7z_RangeEnc *p)
+{
+ unsigned i;
+ for (i = 0; i < 5; i++)
+ RangeEnc_ShiftLow(p);
+}
+
+
+#define MASK(sym) ((signed char *)charMask)[sym]
+
+static void Ppmd7_EncodeSymbol(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol)
+{
+ size_t charMask[256 / sizeof(size_t)];
+ if (p->MinContext->NumStats != 1)
+ {
+ CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext);
+ UInt32 sum;
+ unsigned i;
+ if (s->Symbol == symbol)
+ {
+ RangeEnc_Encode(rc, 0, s->Freq, p->MinContext->SummFreq);
+ p->FoundState = s;
+ Ppmd7_Update1_0(p);
+ return;
+ }
+ p->PrevSuccess = 0;
+ sum = s->Freq;
+ i = p->MinContext->NumStats - 1;
+ do
+ {
+ if ((++s)->Symbol == symbol)
+ {
+ RangeEnc_Encode(rc, sum, s->Freq, p->MinContext->SummFreq);
+ p->FoundState = s;
+ Ppmd7_Update1(p);
+ return;
+ }
+ sum += s->Freq;
+ }
+ while (--i);
+
+ p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol];
+ PPMD_SetAllBitsIn256Bytes(charMask);
+ MASK(s->Symbol) = 0;
+ i = p->MinContext->NumStats - 1;
+ do { MASK((--s)->Symbol) = 0; } while (--i);
+ RangeEnc_Encode(rc, sum, p->MinContext->SummFreq - sum, p->MinContext->SummFreq);
+ }
+ else
+ {
+ UInt16 *prob = Ppmd7_GetBinSumm(p);
+ CPpmd_State *s = Ppmd7Context_OneState(p->MinContext);
+ if (s->Symbol == symbol)
+ {
+ RangeEnc_EncodeBit_0(rc, *prob);
+ *prob = (UInt16)PPMD_UPDATE_PROB_0(*prob);
+ p->FoundState = s;
+ Ppmd7_UpdateBin(p);
+ return;
+ }
+ else
+ {
+ RangeEnc_EncodeBit_1(rc, *prob);
+ *prob = (UInt16)PPMD_UPDATE_PROB_1(*prob);
+ p->InitEsc = PPMD7_kExpEscape[*prob >> 10];
+ PPMD_SetAllBitsIn256Bytes(charMask);
+ MASK(s->Symbol) = 0;
+ p->PrevSuccess = 0;
+ }
+ }
+ for (;;)
+ {
+ UInt32 escFreq;
+ CPpmd_See *see;
+ CPpmd_State *s;
+ UInt32 sum;
+ unsigned i, numMasked = p->MinContext->NumStats;
+ do
+ {
+ p->OrderFall++;
+ if (!p->MinContext->Suffix)
+ return; /* EndMarker (symbol = -1) */
+ p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix);
+ }
+ while (p->MinContext->NumStats == numMasked);
+
+ see = Ppmd7_MakeEscFreq(p, numMasked, &escFreq);
+ s = Ppmd7_GetStats(p, p->MinContext);
+ sum = 0;
+ i = p->MinContext->NumStats;
+ do
+ {
+ int cur = s->Symbol;
+ if (cur == symbol)
+ {
+ UInt32 low = sum;
+ CPpmd_State *s1 = s;
+ do
+ {
+ sum += (s->Freq & (int)(MASK(s->Symbol)));
+ s++;
+ }
+ while (--i);
+ RangeEnc_Encode(rc, low, s1->Freq, sum + escFreq);
+ Ppmd_See_Update(see);
+ p->FoundState = s1;
+ Ppmd7_Update2(p);
+ return;
+ }
+ sum += (s->Freq & (int)(MASK(cur)));
+ MASK(cur) = 0;
+ s++;
+ }
+ while (--i);
+
+ RangeEnc_Encode(rc, sum, escFreq, sum + escFreq);
+ see->Summ = (UInt16)(see->Summ + sum + escFreq);
+ }
+}
+
+const IPpmd7 __archive_ppmd7_functions =
+{
+ &Ppmd7_Construct,
+ &Ppmd7_Alloc,
+ &Ppmd7_Free,
+ &Ppmd7_Init,
+ &Ppmd7z_RangeDec_CreateVTable,
+ &PpmdRAR_RangeDec_CreateVTable,
+ &Ppmd7z_RangeDec_Init,
+ &PpmdRAR_RangeDec_Init,
+ &Ppmd7_DecodeSymbol,
+ &Ppmd7z_RangeEnc_Init,
+ &Ppmd7z_RangeEnc_FlushData,
+ &Ppmd7_EncodeSymbol
+};
diff --git a/libarchive/archive_ppmd7_private.h b/libarchive/archive_ppmd7_private.h
new file mode 100644
index 000000000000..3a6b9eb4190f
--- /dev/null
+++ b/libarchive/archive_ppmd7_private.h
@@ -0,0 +1,119 @@
+/* Ppmd7.h -- PPMdH compression codec
+2010-03-12 : Igor Pavlov : Public domain
+This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
+
+/* This code supports virtual RangeDecoder and includes the implementation
+of RangeCoder from 7z, instead of RangeCoder from original PPMd var.H.
+If you need the compatibility with original PPMd var.H, you can use external RangeDecoder */
+
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
+#ifndef ARCHIVE_PPMD7_PRIVATE_H_INCLUDED
+#define ARCHIVE_PPMD7_PRIVATE_H_INCLUDED
+
+#include "archive_ppmd_private.h"
+
+#define PPMD7_MIN_ORDER 2
+#define PPMD7_MAX_ORDER 64
+
+#define PPMD7_MIN_MEM_SIZE (1 << 11)
+#define PPMD7_MAX_MEM_SIZE (0xFFFFFFFF - 12 * 3)
+
+struct CPpmd7_Context_;
+
+typedef
+ #ifdef PPMD_32BIT
+ struct CPpmd7_Context_ *
+ #else
+ UInt32
+ #endif
+ CPpmd7_Context_Ref;
+
+typedef struct CPpmd7_Context_
+{
+ UInt16 NumStats;
+ UInt16 SummFreq;
+ CPpmd_State_Ref Stats;
+ CPpmd7_Context_Ref Suffix;
+} CPpmd7_Context;
+
+#define Ppmd7Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq)
+
+typedef struct
+{
+ CPpmd7_Context *MinContext, *MaxContext;
+ CPpmd_State *FoundState;
+ unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder, HiBitsFlag;
+ Int32 RunLength, InitRL; /* must be 32-bit at least */
+
+ UInt32 Size;
+ UInt32 GlueCount;
+ Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart;
+ UInt32 AlignOffset;
+
+ Byte Indx2Units[PPMD_NUM_INDEXES];
+ Byte Units2Indx[128];
+ CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES];
+ Byte NS2Indx[256], NS2BSIndx[256], HB2Flag[256];
+ CPpmd_See DummySee, See[25][16];
+ UInt16 BinSumm[128][64];
+} CPpmd7;
+
+/* ---------- Decode ---------- */
+
+typedef struct
+{
+ UInt32 (*GetThreshold)(void *p, UInt32 total);
+ void (*Decode)(void *p, UInt32 start, UInt32 size);
+ UInt32 (*DecodeBit)(void *p, UInt32 size0);
+} IPpmd7_RangeDec;
+
+typedef struct
+{
+ IPpmd7_RangeDec p;
+ UInt32 Range;
+ UInt32 Code;
+ UInt32 Low;
+ UInt32 Bottom;
+ IByteIn *Stream;
+} CPpmd7z_RangeDec;
+
+/* ---------- Encode ---------- */
+
+typedef struct
+{
+ UInt64 Low;
+ UInt32 Range;
+ Byte Cache;
+ UInt64 CacheSize;
+ IByteOut *Stream;
+} CPpmd7z_RangeEnc;
+
+typedef struct
+{
+ /* Base Functions */
+ void (*Ppmd7_Construct)(CPpmd7 *p);
+ Bool (*Ppmd7_Alloc)(CPpmd7 *p, UInt32 size, ISzAlloc *alloc);
+ void (*Ppmd7_Free)(CPpmd7 *p, ISzAlloc *alloc);
+ void (*Ppmd7_Init)(CPpmd7 *p, unsigned maxOrder);
+ #define Ppmd7_WasAllocated(p) ((p)->Base != NULL)
+
+ /* Decode Functions */
+ void (*Ppmd7z_RangeDec_CreateVTable)(CPpmd7z_RangeDec *p);
+ void (*PpmdRAR_RangeDec_CreateVTable)(CPpmd7z_RangeDec *p);
+ Bool (*Ppmd7z_RangeDec_Init)(CPpmd7z_RangeDec *p);
+ Bool (*PpmdRAR_RangeDec_Init)(CPpmd7z_RangeDec *p);
+ #define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
+ int (*Ppmd7_DecodeSymbol)(CPpmd7 *p, IPpmd7_RangeDec *rc);
+
+ /* Encode Functions */
+ void (*Ppmd7z_RangeEnc_Init)(CPpmd7z_RangeEnc *p);
+ void (*Ppmd7z_RangeEnc_FlushData)(CPpmd7z_RangeEnc *p);
+
+ void (*Ppmd7_EncodeSymbol)(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol);
+} IPpmd7;
+
+extern const IPpmd7 __archive_ppmd7_functions;
+#endif
diff --git a/libarchive/archive_ppmd_private.h b/libarchive/archive_ppmd_private.h
new file mode 100644
index 000000000000..266676878557
--- /dev/null
+++ b/libarchive/archive_ppmd_private.h
@@ -0,0 +1,158 @@
+/* Ppmd.h -- PPMD codec common code
+2010-03-12 : Igor Pavlov : Public domain
+This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
+
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
+#ifndef ARCHIVE_PPMD_PRIVATE_H_INCLUDED
+#define ARCHIVE_PPMD_PRIVATE_H_INCLUDED
+
+#include <stddef.h>
+
+#include "archive_read_private.h"
+
+/*** Begin defined in Types.h ***/
+
+#if !defined(ZCONF_H)
+typedef unsigned char Byte;
+#endif
+typedef short Int16;
+typedef unsigned short UInt16;
+
+#ifdef _LZMA_UINT32_IS_ULONG
+typedef long Int32;
+typedef unsigned long UInt32;
+#else
+typedef int Int32;
+typedef unsigned int UInt32;
+#endif
+
+#ifdef _SZ_NO_INT_64
+
+/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
+ NOTES: Some code will work incorrectly in that case! */
+
+typedef long Int64;
+typedef unsigned long UInt64;
+
+#else
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+typedef __int64 Int64;
+typedef unsigned __int64 UInt64;
+#define UINT64_CONST(n) n
+#else
+typedef long long int Int64;
+typedef unsigned long long int UInt64;
+#define UINT64_CONST(n) n ## ULL
+#endif
+
+#endif
+
+typedef int Bool;
+#define True 1
+#define False 0
+
+/* The following interfaces use first parameter as pointer to structure */
+
+typedef struct
+{
+ struct archive_read *a;
+ Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */
+} IByteIn;
+
+typedef struct
+{
+ struct archive_write *a;
+ void (*Write)(void *p, Byte b);
+} IByteOut;
+
+
+typedef struct
+{
+ void *(*Alloc)(void *p, size_t size);
+ void (*Free)(void *p, void *address); /* address can be 0 */
+} ISzAlloc;
+
+/*** End defined in Types.h ***/
+/*** Begin defined in CpuArch.h ***/
+
+#if defined(_M_IX86) || defined(__i386__)
+#define MY_CPU_X86
+#endif
+
+#if defined(MY_CPU_X86) || defined(_M_ARM)
+#define MY_CPU_32BIT
+#endif
+
+#ifdef MY_CPU_32BIT
+#define PPMD_32BIT
+#endif
+
+/*** End defined in CpuArch.h ***/
+
+#define PPMD_INT_BITS 7
+#define PPMD_PERIOD_BITS 7
+#define PPMD_BIN_SCALE (1 << (PPMD_INT_BITS + PPMD_PERIOD_BITS))
+
+#define PPMD_GET_MEAN_SPEC(summ, shift, round) (((summ) + (1 << ((shift) - (round)))) >> (shift))
+#define PPMD_GET_MEAN(summ) PPMD_GET_MEAN_SPEC((summ), PPMD_PERIOD_BITS, 2)
+#define PPMD_UPDATE_PROB_0(prob) ((prob) + (1 << PPMD_INT_BITS) - PPMD_GET_MEAN(prob))
+#define PPMD_UPDATE_PROB_1(prob) ((prob) - PPMD_GET_MEAN(prob))
+
+#define PPMD_N1 4
+#define PPMD_N2 4
+#define PPMD_N3 4
+#define PPMD_N4 ((128 + 3 - 1 * PPMD_N1 - 2 * PPMD_N2 - 3 * PPMD_N3) / 4)
+#define PPMD_NUM_INDEXES (PPMD_N1 + PPMD_N2 + PPMD_N3 + PPMD_N4)
+
+/* SEE-contexts for PPM-contexts with masked symbols */
+typedef struct
+{
+ UInt16 Summ; /* Freq */
+ Byte Shift; /* Speed of Freq change; low Shift is for fast change */
+ Byte Count; /* Count to next change of Shift */
+} CPpmd_See;
+
+#define Ppmd_See_Update(p) if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) \
+ { (p)->Summ <<= 1; (p)->Count = (Byte)(3 << (p)->Shift++); }
+
+typedef struct
+{
+ Byte Symbol;
+ Byte Freq;
+ UInt16 SuccessorLow;
+ UInt16 SuccessorHigh;
+} CPpmd_State;
+
+typedef
+ #ifdef PPMD_32BIT
+ CPpmd_State *
+ #else
+ UInt32
+ #endif
+ CPpmd_State_Ref;
+
+typedef
+ #ifdef PPMD_32BIT
+ void *
+ #else
+ UInt32
+ #endif
+ CPpmd_Void_Ref;
+
+typedef
+ #ifdef PPMD_32BIT
+ Byte *
+ #else
+ UInt32
+ #endif
+ CPpmd_Byte_Ref;
+
+#define PPMD_SetAllBitsIn256Bytes(p) \
+ { unsigned i; for (i = 0; i < 256 / sizeof(p[0]); i += 8) { \
+ p[i+7] = p[i+6] = p[i+5] = p[i+4] = p[i+3] = p[i+2] = p[i+1] = p[i+0] = ~(size_t)0; }}
+
+#endif
diff --git a/libarchive/archive_private.h b/libarchive/archive_private.h
index fba3d62a20af..9941e96612ad 100644
--- a/libarchive/archive_private.h
+++ b/libarchive/archive_private.h
@@ -32,6 +32,10 @@
#ifndef ARCHIVE_PRIVATE_H_INCLUDED
#define ARCHIVE_PRIVATE_H_INCLUDED
+#if HAVE_ICONV_H
+#include <iconv.h>
+#endif
+
#include "archive.h"
#include "archive_string.h"
@@ -47,14 +51,13 @@
#define ARCHIVE_WRITE_DISK_MAGIC (0xc001b0c5U)
#define ARCHIVE_READ_DISK_MAGIC (0xbadb0c5U)
-#define ARCHIVE_STATE_ANY 0xFFFFU
#define ARCHIVE_STATE_NEW 1U
#define ARCHIVE_STATE_HEADER 2U
#define ARCHIVE_STATE_DATA 4U
-#define ARCHIVE_STATE_DATA_END 8U
#define ARCHIVE_STATE_EOF 0x10U
#define ARCHIVE_STATE_CLOSED 0x20U
#define ARCHIVE_STATE_FATAL 0x8000U
+#define ARCHIVE_STATE_ANY (0xFFFFU & ~ARCHIVE_STATE_FATAL)
struct archive_vtable {
int (*archive_close)(struct archive *);
@@ -65,9 +68,23 @@ struct archive_vtable {
ssize_t (*archive_write_data)(struct archive *,
const void *, size_t);
ssize_t (*archive_write_data_block)(struct archive *,
- const void *, size_t, off_t);
+ const void *, size_t, int64_t);
+
+ int (*archive_read_next_header)(struct archive *,
+ struct archive_entry **);
+ int (*archive_read_next_header2)(struct archive *,
+ struct archive_entry *);
+ int (*archive_read_data_block)(struct archive *,
+ const void **, size_t *, int64_t *);
+
+ int (*archive_filter_count)(struct archive *);
+ int64_t (*archive_filter_bytes)(struct archive *, int);
+ int (*archive_filter_code)(struct archive *, int);
+ const char * (*archive_filter_name)(struct archive *, int);
};
+struct archive_string_conv;
+
struct archive {
/*
* The magic/state values are used to sanity-check the
@@ -90,26 +107,35 @@ struct archive {
int compression_code; /* Currently active compression. */
const char *compression_name;
- /* Position in UNCOMPRESSED data stream. */
- int64_t file_position;
- /* Position in COMPRESSED data stream. */
- int64_t raw_position;
/* Number of file entries processed. */
int file_count;
int archive_error_number;
const char *error;
struct archive_string error_string;
+
+ char *current_code;
+ unsigned current_codepage; /* Current ACP(ANSI CodePage). */
+ unsigned current_oemcp; /* Current OEMCP(OEM CodePage). */
+ struct archive_string_conv *sconv;
};
-/* Check magic value and state; exit if it isn't valid. */
-void __archive_check_magic(struct archive *, unsigned int magic,
+/* Check magic value and state; return(ARCHIVE_FATAL) if it isn't valid. */
+int __archive_check_magic(struct archive *, unsigned int magic,
unsigned int state, const char *func);
+#define archive_check_magic(a, expected_magic, allowed_states, function_name) \
+ do { \
+ int magic_test = __archive_check_magic((a), (expected_magic), \
+ (allowed_states), (function_name)); \
+ if (magic_test == ARCHIVE_FATAL) \
+ return ARCHIVE_FATAL; \
+ } while (0)
void __archive_errx(int retvalue, const char *msg) __LA_DEAD;
-int __archive_parse_options(const char *p, const char *fn,
- int keysize, char *key, int valsize, char *val);
+int __archive_mktemp(const char *tmpdir);
+
+int __archive_clean(struct archive *);
#define err_combine(a,b) ((a) < (b) ? (a) : (b))
diff --git a/libarchive/archive_rb.c b/libarchive/archive_rb.c
new file mode 100644
index 000000000000..fa307be25064
--- /dev/null
+++ b/libarchive/archive_rb.c
@@ -0,0 +1,701 @@
+/*-
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas <matt@3am-software.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Based on: NetBSD: rb.c,v 1.6 2010/04/30 13:58:09 joerg Exp
+ */
+
+#include "archive_platform.h"
+
+#include <stddef.h>
+
+#include "archive_rb.h"
+
+/* Keep in sync with archive_rb.h */
+#define RB_DIR_LEFT 0
+#define RB_DIR_RIGHT 1
+#define RB_DIR_OTHER 1
+#define rb_left rb_nodes[RB_DIR_LEFT]
+#define rb_right rb_nodes[RB_DIR_RIGHT]
+
+#define RB_FLAG_POSITION 0x2
+#define RB_FLAG_RED 0x1
+#define RB_FLAG_MASK (RB_FLAG_POSITION|RB_FLAG_RED)
+#define RB_FATHER(rb) \
+ ((struct archive_rb_node *)((rb)->rb_info & ~RB_FLAG_MASK))
+#define RB_SET_FATHER(rb, father) \
+ ((void)((rb)->rb_info = (uintptr_t)(father)|((rb)->rb_info & RB_FLAG_MASK)))
+
+#define RB_SENTINEL_P(rb) ((rb) == NULL)
+#define RB_LEFT_SENTINEL_P(rb) RB_SENTINEL_P((rb)->rb_left)
+#define RB_RIGHT_SENTINEL_P(rb) RB_SENTINEL_P((rb)->rb_right)
+#define RB_FATHER_SENTINEL_P(rb) RB_SENTINEL_P(RB_FATHER((rb)))
+#define RB_CHILDLESS_P(rb) \
+ (RB_SENTINEL_P(rb) || (RB_LEFT_SENTINEL_P(rb) && RB_RIGHT_SENTINEL_P(rb)))
+#define RB_TWOCHILDREN_P(rb) \
+ (!RB_SENTINEL_P(rb) && !RB_LEFT_SENTINEL_P(rb) && !RB_RIGHT_SENTINEL_P(rb))
+
+#define RB_POSITION(rb) \
+ (((rb)->rb_info & RB_FLAG_POSITION) ? RB_DIR_RIGHT : RB_DIR_LEFT)
+#define RB_RIGHT_P(rb) (RB_POSITION(rb) == RB_DIR_RIGHT)
+#define RB_LEFT_P(rb) (RB_POSITION(rb) == RB_DIR_LEFT)
+#define RB_RED_P(rb) (!RB_SENTINEL_P(rb) && ((rb)->rb_info & RB_FLAG_RED) != 0)
+#define RB_BLACK_P(rb) (RB_SENTINEL_P(rb) || ((rb)->rb_info & RB_FLAG_RED) == 0)
+#define RB_MARK_RED(rb) ((void)((rb)->rb_info |= RB_FLAG_RED))
+#define RB_MARK_BLACK(rb) ((void)((rb)->rb_info &= ~RB_FLAG_RED))
+#define RB_INVERT_COLOR(rb) ((void)((rb)->rb_info ^= RB_FLAG_RED))
+#define RB_ROOT_P(rbt, rb) ((rbt)->rbt_root == (rb))
+#define RB_SET_POSITION(rb, position) \
+ ((void)((position) ? ((rb)->rb_info |= RB_FLAG_POSITION) : \
+ ((rb)->rb_info &= ~RB_FLAG_POSITION)))
+#define RB_ZERO_PROPERTIES(rb) ((void)((rb)->rb_info &= ~RB_FLAG_MASK))
+#define RB_COPY_PROPERTIES(dst, src) \
+ ((void)((dst)->rb_info ^= ((dst)->rb_info ^ (src)->rb_info) & RB_FLAG_MASK))
+#define RB_SWAP_PROPERTIES(a, b) do { \
+ uintptr_t xorinfo = ((a)->rb_info ^ (b)->rb_info) & RB_FLAG_MASK; \
+ (a)->rb_info ^= xorinfo; \
+ (b)->rb_info ^= xorinfo; \
+ } while (/*CONSTCOND*/ 0)
+
+static void __archive_rb_tree_insert_rebalance(struct archive_rb_tree *,
+ struct archive_rb_node *);
+static void __archive_rb_tree_removal_rebalance(struct archive_rb_tree *,
+ struct archive_rb_node *, unsigned int);
+
+#define RB_SENTINEL_NODE NULL
+
+#define T 1
+#define F 0
+
+void
+__archive_rb_tree_init(struct archive_rb_tree *rbt,
+ const struct archive_rb_tree_ops *ops)
+{
+ rbt->rbt_ops = ops;
+ *((const struct archive_rb_node **)&rbt->rbt_root) = RB_SENTINEL_NODE;
+}
+
+struct archive_rb_node *
+__archive_rb_tree_find_node(struct archive_rb_tree *rbt, const void *key)
+{
+ archive_rbto_compare_key_fn compare_key = rbt->rbt_ops->rbto_compare_key;
+ struct archive_rb_node *parent = rbt->rbt_root;
+
+ while (!RB_SENTINEL_P(parent)) {
+ const signed int diff = (*compare_key)(parent, key);
+ if (diff == 0)
+ return parent;
+ parent = parent->rb_nodes[diff > 0];
+ }
+
+ return NULL;
+}
+
+struct archive_rb_node *
+__archive_rb_tree_find_node_geq(struct archive_rb_tree *rbt, const void *key)
+{
+ archive_rbto_compare_key_fn compare_key = rbt->rbt_ops->rbto_compare_key;
+ struct archive_rb_node *parent = rbt->rbt_root;
+ struct archive_rb_node *last = NULL;
+
+ while (!RB_SENTINEL_P(parent)) {
+ const signed int diff = (*compare_key)(parent, key);
+ if (diff == 0)
+ return parent;
+ if (diff < 0)
+ last = parent;
+ parent = parent->rb_nodes[diff > 0];
+ }
+
+ return last;
+}
+
+struct archive_rb_node *
+__archive_rb_tree_find_node_leq(struct archive_rb_tree *rbt, const void *key)
+{
+ archive_rbto_compare_key_fn compare_key = rbt->rbt_ops->rbto_compare_key;
+ struct archive_rb_node *parent = rbt->rbt_root;
+ struct archive_rb_node *last = NULL;
+
+ while (!RB_SENTINEL_P(parent)) {
+ const signed int diff = (*compare_key)(parent, key);
+ if (diff == 0)
+ return parent;
+ if (diff > 0)
+ last = parent;
+ parent = parent->rb_nodes[diff > 0];
+ }
+
+ return last;
+}
+
+int
+__archive_rb_tree_insert_node(struct archive_rb_tree *rbt,
+ struct archive_rb_node *self)
+{
+ archive_rbto_compare_nodes_fn compare_nodes = rbt->rbt_ops->rbto_compare_nodes;
+ struct archive_rb_node *parent, *tmp;
+ unsigned int position;
+ int rebalance;
+
+ tmp = rbt->rbt_root;
+ /*
+ * This is a hack. Because rbt->rbt_root is just a
+ * struct archive_rb_node *, just like rb_node->rb_nodes[RB_DIR_LEFT],
+ * we can use this fact to avoid a lot of tests for root and know
+ * that even at root, updating
+ * RB_FATHER(rb_node)->rb_nodes[RB_POSITION(rb_node)] will
+ * update rbt->rbt_root.
+ */
+ parent = (struct archive_rb_node *)(void *)&rbt->rbt_root;
+ position = RB_DIR_LEFT;
+
+ /*
+ * Find out where to place this new leaf.
+ */
+ while (!RB_SENTINEL_P(tmp)) {
+ const signed int diff = (*compare_nodes)(tmp, self);
+ if (diff == 0) {
+ /*
+ * Node already exists; don't insert.
+ */
+ return F;
+ }
+ parent = tmp;
+ position = (diff > 0);
+ tmp = parent->rb_nodes[position];
+ }
+
+ /*
+ * Initialize the node and insert as a leaf into the tree.
+ */
+ RB_SET_FATHER(self, parent);
+ RB_SET_POSITION(self, position);
+ if (parent == (struct archive_rb_node *)(void *)&rbt->rbt_root) {
+ RB_MARK_BLACK(self); /* root is always black */
+ rebalance = F;
+ } else {
+ /*
+ * All new nodes are colored red. We only need to rebalance
+ * if our parent is also red.
+ */
+ RB_MARK_RED(self);
+ rebalance = RB_RED_P(parent);
+ }
+ self->rb_left = parent->rb_nodes[position];
+ self->rb_right = parent->rb_nodes[position];
+ parent->rb_nodes[position] = self;
+
+ /*
+ * Rebalance tree after insertion
+ */
+ if (rebalance)
+ __archive_rb_tree_insert_rebalance(rbt, self);
+
+ return T;
+}
+
+/*
+ * Swap the location and colors of 'self' and its child @ which. The child
+ * can not be a sentinel node. This is our rotation function. However,
+ * since it preserves coloring, it great simplifies both insertion and
+ * removal since rotation almost always involves the exchanging of colors
+ * as a separate step.
+ */
+/*ARGSUSED*/
+static void
+__archive_rb_tree_reparent_nodes(
+ struct archive_rb_node *old_father, const unsigned int which)
+{
+ const unsigned int other = which ^ RB_DIR_OTHER;
+ struct archive_rb_node * const grandpa = RB_FATHER(old_father);
+ struct archive_rb_node * const old_child = old_father->rb_nodes[which];
+ struct archive_rb_node * const new_father = old_child;
+ struct archive_rb_node * const new_child = old_father;
+
+ /*
+ * Exchange descendant linkages.
+ */
+ grandpa->rb_nodes[RB_POSITION(old_father)] = new_father;
+ new_child->rb_nodes[which] = old_child->rb_nodes[other];
+ new_father->rb_nodes[other] = new_child;
+
+ /*
+ * Update ancestor linkages
+ */
+ RB_SET_FATHER(new_father, grandpa);
+ RB_SET_FATHER(new_child, new_father);
+
+ /*
+ * Exchange properties between new_father and new_child. The only
+ * change is that new_child's position is now on the other side.
+ */
+ RB_SWAP_PROPERTIES(new_father, new_child);
+ RB_SET_POSITION(new_child, other);
+
+ /*
+ * Make sure to reparent the new child to ourself.
+ */
+ if (!RB_SENTINEL_P(new_child->rb_nodes[which])) {
+ RB_SET_FATHER(new_child->rb_nodes[which], new_child);
+ RB_SET_POSITION(new_child->rb_nodes[which], which);
+ }
+
+}
+
+static void
+__archive_rb_tree_insert_rebalance(struct archive_rb_tree *rbt,
+ struct archive_rb_node *self)
+{
+ struct archive_rb_node * father = RB_FATHER(self);
+ struct archive_rb_node * grandpa;
+ struct archive_rb_node * uncle;
+ unsigned int which;
+ unsigned int other;
+
+ for (;;) {
+ /*
+ * We are red and our parent is red, therefore we must have a
+ * grandfather and he must be black.
+ */
+ grandpa = RB_FATHER(father);
+ which = (father == grandpa->rb_right);
+ other = which ^ RB_DIR_OTHER;
+ uncle = grandpa->rb_nodes[other];
+
+ if (RB_BLACK_P(uncle))
+ break;
+
+ /*
+ * Case 1: our uncle is red
+ * Simply invert the colors of our parent and
+ * uncle and make our grandparent red. And
+ * then solve the problem up at his level.
+ */
+ RB_MARK_BLACK(uncle);
+ RB_MARK_BLACK(father);
+ if (RB_ROOT_P(rbt, grandpa)) {
+ /*
+ * If our grandpa is root, don't bother
+ * setting him to red, just return.
+ */
+ return;
+ }
+ RB_MARK_RED(grandpa);
+ self = grandpa;
+ father = RB_FATHER(self);
+ if (RB_BLACK_P(father)) {
+ /*
+ * If our greatgrandpa is black, we're done.
+ */
+ return;
+ }
+ }
+
+ /*
+ * Case 2&3: our uncle is black.
+ */
+ if (self == father->rb_nodes[other]) {
+ /*
+ * Case 2: we are on the same side as our uncle
+ * Swap ourselves with our parent so this case
+ * becomes case 3. Basically our parent becomes our
+ * child.
+ */
+ __archive_rb_tree_reparent_nodes(father, other);
+ }
+ /*
+ * Case 3: we are opposite a child of a black uncle.
+ * Swap our parent and grandparent. Since our grandfather
+ * is black, our father will become black and our new sibling
+ * (former grandparent) will become red.
+ */
+ __archive_rb_tree_reparent_nodes(grandpa, which);
+
+ /*
+ * Final step: Set the root to black.
+ */
+ RB_MARK_BLACK(rbt->rbt_root);
+}
+
+static void
+__archive_rb_tree_prune_node(struct archive_rb_tree *rbt,
+ struct archive_rb_node *self, int rebalance)
+{
+ const unsigned int which = RB_POSITION(self);
+ struct archive_rb_node *father = RB_FATHER(self);
+
+ /*
+ * Since we are childless, we know that self->rb_left is pointing
+ * to the sentinel node.
+ */
+ father->rb_nodes[which] = self->rb_left;
+
+ /*
+ * Rebalance if requested.
+ */
+ if (rebalance)
+ __archive_rb_tree_removal_rebalance(rbt, father, which);
+}
+
+/*
+ * When deleting an interior node
+ */
+static void
+__archive_rb_tree_swap_prune_and_rebalance(struct archive_rb_tree *rbt,
+ struct archive_rb_node *self, struct archive_rb_node *standin)
+{
+ const unsigned int standin_which = RB_POSITION(standin);
+ unsigned int standin_other = standin_which ^ RB_DIR_OTHER;
+ struct archive_rb_node *standin_son;
+ struct archive_rb_node *standin_father = RB_FATHER(standin);
+ int rebalance = RB_BLACK_P(standin);
+
+ if (standin_father == self) {
+ /*
+ * As a child of self, any children would be opposite of
+ * our parent.
+ */
+ standin_son = standin->rb_nodes[standin_which];
+ } else {
+ /*
+ * Since we aren't a child of self, any children would be
+ * on the same side as our parent.
+ */
+ standin_son = standin->rb_nodes[standin_other];
+ }
+
+ if (RB_RED_P(standin_son)) {
+ /*
+ * We know we have a red child so if we flip it to black
+ * we don't have to rebalance.
+ */
+ RB_MARK_BLACK(standin_son);
+ rebalance = F;
+
+ if (standin_father != self) {
+ /*
+ * Change the son's parentage to point to his grandpa.
+ */
+ RB_SET_FATHER(standin_son, standin_father);
+ RB_SET_POSITION(standin_son, standin_which);
+ }
+ }
+
+ if (standin_father == self) {
+ /*
+ * If we are about to delete the standin's father, then when
+ * we call rebalance, we need to use ourselves as our father.
+ * Otherwise remember our original father. Also, since we are
+ * our standin's father we only need to reparent the standin's
+ * brother.
+ *
+ * | R --> S |
+ * | Q S --> Q T |
+ * | t --> |
+ *
+ * Have our son/standin adopt his brother as his new son.
+ */
+ standin_father = standin;
+ } else {
+ /*
+ * | R --> S . |
+ * | / \ | T --> / \ | / |
+ * | ..... | S --> ..... | T |
+ *
+ * Sever standin's connection to his father.
+ */
+ standin_father->rb_nodes[standin_which] = standin_son;
+ /*
+ * Adopt the far son.
+ */
+ standin->rb_nodes[standin_other] = self->rb_nodes[standin_other];
+ RB_SET_FATHER(standin->rb_nodes[standin_other], standin);
+ /*
+ * Use standin_other because we need to preserve standin_which
+ * for the removal_rebalance.
+ */
+ standin_other = standin_which;
+ }
+
+ /*
+ * Move the only remaining son to our standin. If our standin is our
+ * son, this will be the only son needed to be moved.
+ */
+ standin->rb_nodes[standin_other] = self->rb_nodes[standin_other];
+ RB_SET_FATHER(standin->rb_nodes[standin_other], standin);
+
+ /*
+ * Now copy the result of self to standin and then replace
+ * self with standin in the tree.
+ */
+ RB_COPY_PROPERTIES(standin, self);
+ RB_SET_FATHER(standin, RB_FATHER(self));
+ RB_FATHER(standin)->rb_nodes[RB_POSITION(standin)] = standin;
+
+ if (rebalance)
+ __archive_rb_tree_removal_rebalance(rbt, standin_father, standin_which);
+}
+
+/*
+ * We could do this by doing
+ * __archive_rb_tree_node_swap(rbt, self, which);
+ * __archive_rb_tree_prune_node(rbt, self, F);
+ *
+ * But it's more efficient to just evaluate and recolor the child.
+ */
+static void
+__archive_rb_tree_prune_blackred_branch(
+ struct archive_rb_node *self, unsigned int which)
+{
+ struct archive_rb_node *father = RB_FATHER(self);
+ struct archive_rb_node *son = self->rb_nodes[which];
+
+ /*
+ * Remove ourselves from the tree and give our former child our
+ * properties (position, color, root).
+ */
+ RB_COPY_PROPERTIES(son, self);
+ father->rb_nodes[RB_POSITION(son)] = son;
+ RB_SET_FATHER(son, father);
+}
+/*
+ *
+ */
+void
+__archive_rb_tree_remove_node(struct archive_rb_tree *rbt,
+ struct archive_rb_node *self)
+{
+ struct archive_rb_node *standin;
+ unsigned int which;
+
+ /*
+ * In the following diagrams, we (the node to be removed) are S. Red
+ * nodes are lowercase. T could be either red or black.
+ *
+ * Remember the major axiom of the red-black tree: the number of
+ * black nodes from the root to each leaf is constant across all
+ * leaves, only the number of red nodes varies.
+ *
+ * Thus removing a red leaf doesn't require any other changes to a
+ * red-black tree. So if we must remove a node, attempt to rearrange
+ * the tree so we can remove a red node.
+ *
+ * The simplest case is a childless red node or a childless root node:
+ *
+ * | T --> T | or | R --> * |
+ * | s --> * |
+ */
+ if (RB_CHILDLESS_P(self)) {
+ const int rebalance = RB_BLACK_P(self) && !RB_ROOT_P(rbt, self);
+ __archive_rb_tree_prune_node(rbt, self, rebalance);
+ return;
+ }
+ if (!RB_TWOCHILDREN_P(self)) {
+ /*
+ * The next simplest case is the node we are deleting is
+ * black and has one red child.
+ *
+ * | T --> T --> T |
+ * | S --> R --> R |
+ * | r --> s --> * |
+ */
+ which = RB_LEFT_SENTINEL_P(self) ? RB_DIR_RIGHT : RB_DIR_LEFT;
+ __archive_rb_tree_prune_blackred_branch(self, which);
+ return;
+ }
+
+ /*
+ * We invert these because we prefer to remove from the inside of
+ * the tree.
+ */
+ which = RB_POSITION(self) ^ RB_DIR_OTHER;
+
+ /*
+ * Let's find the node closes to us opposite of our parent
+ * Now swap it with ourself, "prune" it, and rebalance, if needed.
+ */
+ standin = __archive_rb_tree_iterate(rbt, self, which);
+ __archive_rb_tree_swap_prune_and_rebalance(rbt, self, standin);
+}
+
+static void
+__archive_rb_tree_removal_rebalance(struct archive_rb_tree *rbt,
+ struct archive_rb_node *parent, unsigned int which)
+{
+
+ while (RB_BLACK_P(parent->rb_nodes[which])) {
+ unsigned int other = which ^ RB_DIR_OTHER;
+ struct archive_rb_node *brother = parent->rb_nodes[other];
+
+ /*
+ * For cases 1, 2a, and 2b, our brother's children must
+ * be black and our father must be black
+ */
+ if (RB_BLACK_P(parent)
+ && RB_BLACK_P(brother->rb_left)
+ && RB_BLACK_P(brother->rb_right)) {
+ if (RB_RED_P(brother)) {
+ /*
+ * Case 1: Our brother is red, swap its
+ * position (and colors) with our parent.
+ * This should now be case 2b (unless C or E
+ * has a red child which is case 3; thus no
+ * explicit branch to case 2b).
+ *
+ * B -> D
+ * A d -> b E
+ * C E -> A C
+ */
+ __archive_rb_tree_reparent_nodes(parent, other);
+ brother = parent->rb_nodes[other];
+ } else {
+ /*
+ * Both our parent and brother are black.
+ * Change our brother to red, advance up rank
+ * and go through the loop again.
+ *
+ * B -> *B
+ * *A D -> A d
+ * C E -> C E
+ */
+ RB_MARK_RED(brother);
+ if (RB_ROOT_P(rbt, parent))
+ return; /* root == parent == black */
+ which = RB_POSITION(parent);
+ parent = RB_FATHER(parent);
+ continue;
+ }
+ }
+ /*
+ * Avoid an else here so that case 2a above can hit either
+ * case 2b, 3, or 4.
+ */
+ if (RB_RED_P(parent)
+ && RB_BLACK_P(brother)
+ && RB_BLACK_P(brother->rb_left)
+ && RB_BLACK_P(brother->rb_right)) {
+ /*
+ * We are black, our father is red, our brother and
+ * both nephews are black. Simply invert/exchange the
+ * colors of our father and brother (to black and red
+ * respectively).
+ *
+ * | f --> F |
+ * | * B --> * b |
+ * | N N --> N N |
+ */
+ RB_MARK_BLACK(parent);
+ RB_MARK_RED(brother);
+ break; /* We're done! */
+ } else {
+ /*
+ * Our brother must be black and have at least one
+ * red child (it may have two).
+ */
+ if (RB_BLACK_P(brother->rb_nodes[other])) {
+ /*
+ * Case 3: our brother is black, our near
+ * nephew is red, and our far nephew is black.
+ * Swap our brother with our near nephew.
+ * This result in a tree that matches case 4.
+ * (Our father could be red or black).
+ *
+ * | F --> F |
+ * | x B --> x B |
+ * | n --> n |
+ */
+ __archive_rb_tree_reparent_nodes(brother, which);
+ brother = parent->rb_nodes[other];
+ }
+ /*
+ * Case 4: our brother is black and our far nephew
+ * is red. Swap our father and brother locations and
+ * change our far nephew to black. (these can be
+ * done in either order so we change the color first).
+ * The result is a valid red-black tree and is a
+ * terminal case. (again we don't care about the
+ * father's color)
+ *
+ * If the father is red, we will get a red-black-black
+ * tree:
+ * | f -> f --> b |
+ * | B -> B --> F N |
+ * | n -> N --> |
+ *
+ * If the father is black, we will get an all black
+ * tree:
+ * | F -> F --> B |
+ * | B -> B --> F N |
+ * | n -> N --> |
+ *
+ * If we had two red nephews, then after the swap,
+ * our former father would have a red grandson.
+ */
+ RB_MARK_BLACK(brother->rb_nodes[other]);
+ __archive_rb_tree_reparent_nodes(parent, other);
+ break; /* We're done! */
+ }
+ }
+}
+
+struct archive_rb_node *
+__archive_rb_tree_iterate(struct archive_rb_tree *rbt,
+ struct archive_rb_node *self, const unsigned int direction)
+{
+ const unsigned int other = direction ^ RB_DIR_OTHER;
+
+ if (self == NULL) {
+ self = rbt->rbt_root;
+ if (RB_SENTINEL_P(self))
+ return NULL;
+ while (!RB_SENTINEL_P(self->rb_nodes[direction]))
+ self = self->rb_nodes[direction];
+ return self;
+ }
+ /*
+ * We can't go any further in this direction. We proceed up in the
+ * opposite direction until our parent is in direction we want to go.
+ */
+ if (RB_SENTINEL_P(self->rb_nodes[direction])) {
+ while (!RB_ROOT_P(rbt, self)) {
+ if (other == RB_POSITION(self))
+ return RB_FATHER(self);
+ self = RB_FATHER(self);
+ }
+ return NULL;
+ }
+
+ /*
+ * Advance down one in current direction and go down as far as possible
+ * in the opposite direction.
+ */
+ self = self->rb_nodes[direction];
+ while (!RB_SENTINEL_P(self->rb_nodes[other]))
+ self = self->rb_nodes[other];
+ return self;
+}
diff --git a/libarchive/archive_rb.h b/libarchive/archive_rb.h
new file mode 100644
index 000000000000..4562e9ebc41b
--- /dev/null
+++ b/libarchive/archive_rb.h
@@ -0,0 +1,100 @@
+/*-
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas <matt@3am-software.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Based on NetBSD: rb.h,v 1.13 2009/08/16 10:57:01 yamt Exp
+ */
+#ifndef ARCHIVE_RB_H_
+#define ARCHIVE_RB_H_
+
+struct archive_rb_node {
+ struct archive_rb_node *rb_nodes[2];
+ /*
+ * rb_info contains the two flags and the parent back pointer.
+ * We put the two flags in the low two bits since we know that
+ * rb_node will have an alignment of 4 or 8 bytes.
+ */
+ uintptr_t rb_info;
+};
+
+#define ARCHIVE_RB_DIR_LEFT 0
+#define ARCHIVE_RB_DIR_RIGHT 1
+
+#define ARCHIVE_RB_TREE_MIN(T) \
+ __archive_rb_tree_iterate((T), NULL, ARCHIVE_RB_DIR_LEFT)
+#define ARCHIVE_RB_TREE_MAX(T) \
+ __archive_rb_tree_iterate((T), NULL, ARCHIVE_RB_DIR_RIGHT)
+#define ARCHIVE_RB_TREE_FOREACH(N, T) \
+ for ((N) = ARCHIVE_RB_TREE_MIN(T); (N); \
+ (N) = __archive_rb_tree_iterate((T), (N), ARCHIVE_RB_DIR_RIGHT))
+#define ARCHIVE_RB_TREE_FOREACH_REVERSE(N, T) \
+ for ((N) = ARCHIVE_RB_TREE_MAX(T); (N); \
+ (N) = __archive_rb_tree_iterate((T), (N), ARCHIVE_RB_DIR_LEFT))
+
+/*
+ * archive_rbto_compare_nodes_fn:
+ * return a positive value if the first node < the second node.
+ * return a negative value if the first node > the second node.
+ * return 0 if they are considered same.
+ *
+ * archive_rbto_compare_key_fn:
+ * return a positive value if the node < the key.
+ * return a negative value if the node > the key.
+ * return 0 if they are considered same.
+ */
+
+typedef signed int (*const archive_rbto_compare_nodes_fn)(const struct archive_rb_node *,
+ const struct archive_rb_node *);
+typedef signed int (*const archive_rbto_compare_key_fn)(const struct archive_rb_node *,
+ const void *);
+
+struct archive_rb_tree_ops {
+ archive_rbto_compare_nodes_fn rbto_compare_nodes;
+ archive_rbto_compare_key_fn rbto_compare_key;
+};
+
+struct archive_rb_tree {
+ struct archive_rb_node *rbt_root;
+ const struct archive_rb_tree_ops *rbt_ops;
+};
+
+void __archive_rb_tree_init(struct archive_rb_tree *,
+ const struct archive_rb_tree_ops *);
+int __archive_rb_tree_insert_node(struct archive_rb_tree *,
+ struct archive_rb_node *);
+struct archive_rb_node *
+ __archive_rb_tree_find_node(struct archive_rb_tree *, const void *);
+struct archive_rb_node *
+ __archive_rb_tree_find_node_geq(struct archive_rb_tree *, const void *);
+struct archive_rb_node *
+ __archive_rb_tree_find_node_leq(struct archive_rb_tree *, const void *);
+void __archive_rb_tree_remove_node(struct archive_rb_tree *, struct archive_rb_node *);
+struct archive_rb_node *
+ __archive_rb_tree_iterate(struct archive_rb_tree *,
+ struct archive_rb_node *, const unsigned int);
+
+#endif /* ARCHIVE_RB_H_*/
diff --git a/libarchive/archive_read.3 b/libarchive/archive_read.3
index 7b8e648a23e8..52851925c09e 100644
--- a/libarchive/archive_read.3
+++ b/libarchive/archive_read.3
@@ -24,179 +24,14 @@
.\"
.\" $FreeBSD: head/lib/libarchive/archive_read.3 191595 2009-04-27 20:13:13Z kientzle $
.\"
-.Dd April 13, 2009
+.Dd March 23, 2011
.Dt ARCHIVE_READ 3
.Os
.Sh NAME
-.Nm archive_read_new ,
-.Nm archive_read_set_filter_options ,
-.Nm archive_read_set_format_options ,
-.Nm archive_read_set_options ,
-.Nm archive_read_support_compression_all ,
-.Nm archive_read_support_compression_bzip2 ,
-.Nm archive_read_support_compression_compress ,
-.Nm archive_read_support_compression_gzip ,
-.Nm archive_read_support_compression_lzma ,
-.Nm archive_read_support_compression_none ,
-.Nm archive_read_support_compression_xz ,
-.Nm archive_read_support_compression_program ,
-.Nm archive_read_support_compression_program_signature ,
-.Nm archive_read_support_format_all ,
-.Nm archive_read_support_format_ar ,
-.Nm archive_read_support_format_cpio ,
-.Nm archive_read_support_format_empty ,
-.Nm archive_read_support_format_iso9660 ,
-.Nm archive_read_support_format_mtree,
-.Nm archive_read_support_format_raw,
-.Nm archive_read_support_format_tar ,
-.Nm archive_read_support_format_zip ,
-.Nm archive_read_open ,
-.Nm archive_read_open2 ,
-.Nm archive_read_open_fd ,
-.Nm archive_read_open_FILE ,
-.Nm archive_read_open_filename ,
-.Nm archive_read_open_memory ,
-.Nm archive_read_next_header ,
-.Nm archive_read_next_header2 ,
-.Nm archive_read_data ,
-.Nm archive_read_data_block ,
-.Nm archive_read_data_skip ,
-.\" #if ARCHIVE_API_VERSION < 3
-.Nm archive_read_data_into_buffer ,
-.\" #endif
-.Nm archive_read_data_into_fd ,
-.Nm archive_read_extract ,
-.Nm archive_read_extract2 ,
-.Nm archive_read_extract_set_progress_callback ,
-.Nm archive_read_close ,
-.Nm archive_read_free
+.Nm archive_read
.Nd functions for reading streaming archives
.Sh SYNOPSIS
.In archive.h
-.Ft struct archive *
-.Fn archive_read_new "void"
-.Ft int
-.Fn archive_read_support_compression_all "struct archive *"
-.Ft int
-.Fn archive_read_support_compression_bzip2 "struct archive *"
-.Ft int
-.Fn archive_read_support_compression_compress "struct archive *"
-.Ft int
-.Fn archive_read_support_compression_gzip "struct archive *"
-.Ft int
-.Fn archive_read_support_compression_lzma "struct archive *"
-.Ft int
-.Fn archive_read_support_compression_none "struct archive *"
-.Ft int
-.Fn archive_read_support_compression_xz "struct archive *"
-.Ft int
-.Fo archive_read_support_compression_program
-.Fa "struct archive *"
-.Fa "const char *cmd"
-.Fc
-.Ft int
-.Fo archive_read_support_compression_program_signature
-.Fa "struct archive *"
-.Fa "const char *cmd"
-.Fa "const void *signature"
-.Fa "size_t signature_length"
-.Fc
-.Ft int
-.Fn archive_read_support_format_all "struct archive *"
-.Ft int
-.Fn archive_read_support_format_ar "struct archive *"
-.Ft int
-.Fn archive_read_support_format_cpio "struct archive *"
-.Ft int
-.Fn archive_read_support_format_empty "struct archive *"
-.Ft int
-.Fn archive_read_support_format_iso9660 "struct archive *"
-.Ft int
-.Fn archive_read_support_format_mtree "struct archive *"
-.Ft int
-.Fn archive_read_support_format_raw "struct archive *"
-.Ft int
-.Fn archive_read_support_format_tar "struct archive *"
-.Ft int
-.Fn archive_read_support_format_zip "struct archive *"
-.Ft int
-.Fn archive_read_set_filter_options "struct archive *" "const char *"
-.Ft int
-.Fn archive_read_set_format_options "struct archive *" "const char *"
-.Ft int
-.Fn archive_read_set_options "struct archive *" "const char *"
-.Ft int
-.Fo archive_read_open
-.Fa "struct archive *"
-.Fa "void *client_data"
-.Fa "archive_open_callback *"
-.Fa "archive_read_callback *"
-.Fa "archive_close_callback *"
-.Fc
-.Ft int
-.Fo archive_read_open2
-.Fa "struct archive *"
-.Fa "void *client_data"
-.Fa "archive_open_callback *"
-.Fa "archive_read_callback *"
-.Fa "archive_skip_callback *"
-.Fa "archive_close_callback *"
-.Fc
-.Ft int
-.Fn archive_read_open_FILE "struct archive *" "FILE *file"
-.Ft int
-.Fn archive_read_open_fd "struct archive *" "int fd" "size_t block_size"
-.Ft int
-.Fo archive_read_open_filename
-.Fa "struct archive *"
-.Fa "const char *filename"
-.Fa "size_t block_size"
-.Fc
-.Ft int
-.Fn archive_read_open_memory "struct archive *" "void *buff" "size_t size"
-.Ft int
-.Fn archive_read_next_header "struct archive *" "struct archive_entry **"
-.Ft int
-.Fn archive_read_next_header2 "struct archive *" "struct archive_entry *"
-.Ft ssize_t
-.Fn archive_read_data "struct archive *" "void *buff" "size_t len"
-.Ft int
-.Fo archive_read_data_block
-.Fa "struct archive *"
-.Fa "const void **buff"
-.Fa "size_t *len"
-.Fa "off_t *offset"
-.Fc
-.Ft int
-.Fn archive_read_data_skip "struct archive *"
-.\" #if ARCHIVE_API_VERSION < 3
-.Ft int
-.Fn archive_read_data_into_buffer "struct archive *" "void *" "ssize_t len"
-.\" #endif
-.Ft int
-.Fn archive_read_data_into_fd "struct archive *" "int fd"
-.Ft int
-.Fo archive_read_extract
-.Fa "struct archive *"
-.Fa "struct archive_entry *"
-.Fa "int flags"
-.Fc
-.Ft int
-.Fo archive_read_extract2
-.Fa "struct archive *src"
-.Fa "struct archive_entry *"
-.Fa "struct archive *dest"
-.Fc
-.Ft void
-.Fo archive_read_extract_set_progress_callback
-.Fa "struct archive *"
-.Fa "void (*func)(void *)"
-.Fa "void *user_data"
-.Fc
-.Ft int
-.Fn archive_read_close "struct archive *"
-.Ft int
-.Fn archive_read_free "struct archive *"
.Sh DESCRIPTION
These functions provide a complete API for reading streaming archives.
The general process is to first create the
@@ -204,375 +39,120 @@ The general process is to first create the
object, set options, initialize the reader, iterate over the archive
headers and associated data, then close the archive and release all
resources.
-The following summary describes the functions in approximately the
-order they would be used:
-.Bl -tag -compact -width indent
-.It Fn archive_read_new
-Allocates and initializes a
+.\"
+.Ss Create archive object
+See
+.Xr archive_read_new 3 .
+.Pp
+To read an archive, you must first obtain an initialized
.Tn struct archive
-object suitable for reading from an archive.
-.It Xo
-.Fn archive_read_support_compression_bzip2 ,
-.Fn archive_read_support_compression_compress ,
-.Fn archive_read_support_compression_gzip ,
-.Fn archive_read_support_compression_lzma ,
-.Fn archive_read_support_compression_none ,
-.Fn archive_read_support_compression_xz
-.Xc
-Enables auto-detection code and decompression support for the
-specified compression.
-Returns
-.Cm ARCHIVE_OK
-if the compression is fully supported, or
-.Cm ARCHIVE_WARN
-if the compression is supported only through an external program.
-Note that decompression using an external program is usually slower than
-decompression through built-in libraries.
-Note that
-.Dq none
-is always enabled by default.
-.It Fn archive_read_support_compression_all
-Enables all available decompression filters.
-.It Fn archive_read_support_compression_program
-Data is fed through the specified external program before being dearchived.
-Note that this disables automatic detection of the compression format,
-so it makes no sense to specify this in conjunction with any other
-decompression option.
-.It Fn archive_read_support_compression_program_signature
-This feeds data through the specified external program
-but only if the initial bytes of the data match the specified
-signature value.
-.It Xo
-.Fn archive_read_support_format_all ,
-.Fn archive_read_support_format_ar ,
-.Fn archive_read_support_format_cpio ,
-.Fn archive_read_support_format_empty ,
-.Fn archive_read_support_format_iso9660 ,
-.Fn archive_read_support_format_mtree ,
-.Fn archive_read_support_format_tar ,
-.Fn archive_read_support_format_zip
-.Xc
-Enables support---including auto-detection code---for the
-specified archive format.
-For example,
-.Fn archive_read_support_format_tar
-enables support for a variety of standard tar formats, old-style tar,
-ustar, pax interchange format, and many common variants.
-For convenience,
-.Fn archive_read_support_format_all
-enables support for all available formats.
-Only empty archives are supported by default.
-.It Fn archive_read_support_format_raw
-The
-.Dq raw
-format handler allows libarchive to be used to read arbitrary data.
-It treats any data stream as an archive with a single entry.
-The pathname of this entry is
-.Dq data ;
-all other entry fields are unset.
-This is not enabled by
+object from
+.Fn archive_read_new .
+.\"
+.Ss Enable filters and formats
+See
+.Xr archive_read_filter 3
+and
+.Xr archive_read_format 3 .
+.Pp
+You can then modify this object for the desired operations with the
+various
+.Fn archive_read_set_XXX
+and
+.Fn archive_read_support_XXX
+functions.
+In particular, you will need to invoke appropriate
+.Fn archive_read_support_XXX
+functions to enable the corresponding compression and format
+support.
+Note that these latter functions perform two distinct operations:
+they cause the corresponding support code to be linked into your
+program, and they enable the corresponding auto-detect code.
+Unless you have specific constraints, you will generally want
+to invoke
+.Fn archive_read_support_filter_all
+and
.Fn archive_read_support_format_all
-in order to avoid erroneous handling of damaged archives.
-.It Xo
-.Fn archive_read_set_filter_options ,
-.Fn archive_read_set_format_options ,
-.Fn archive_read_set_options
-.Xc
-Specifies options that will be passed to currently-registered
-filters (including decompression filters) and/or format readers.
-The argument is a comma-separated list of individual options.
-Individual options have one of the following forms:
-.Bl -tag -compact -width indent
-.It Ar option=value
-The option/value pair will be provided to every module.
-Modules that do not accept an option with this name will ignore it.
-.It Ar option
-The option will be provided to every module with a value of
-.Dq 1 .
-.It Ar !option
-The option will be provided to every module with a NULL value.
-.It Ar module:option=value , Ar module:option , Ar module:!option
-As above, but the corresponding option and value will be provided
-only to modules whose name matches
-.Ar module .
-.El
-The return value will be
-.Cm ARCHIVE_OK
-if any module accepts the option, or
-.Cm ARCHIVE_WARN
-if no module accepted the option, or
-.Cm ARCHIVE_FATAL
-if there was a fatal error while attempting to process the option.
+to enable auto-detect for all formats and compression types
+currently supported by the library.
+.\"
+.Ss Set options
+See
+.Xr archive_read_set_options 3 .
+.\"
+.Ss Open archive
+See
+.Xr archive_read_open 3 .
.Pp
-The currently supported options are:
-.Bl -tag -compact -width indent
-.It Format iso9660
-.Bl -tag -compact -width indent
-.It Cm joliet
-Support Joliet extensions.
-Defaults to enabled, use
-.Cm !joliet
-to disable.
-.El
-.El
-.It Fn archive_read_open
-The same as
-.Fn archive_read_open2 ,
-except that the skip callback is assumed to be
-.Dv NULL .
-.It Fn archive_read_open2
-Freeze the settings, open the archive, and prepare for reading entries.
-This is the most generic version of this call, which accepts
-four callback functions.
-Most clients will want to use
-.Fn archive_read_open_filename ,
-.Fn archive_read_open_FILE ,
-.Fn archive_read_open_fd ,
-or
-.Fn archive_read_open_memory
-instead.
-The library invokes the client-provided functions to obtain
-raw bytes from the archive.
-.It Fn archive_read_open_FILE
-Like
-.Fn archive_read_open ,
-except that it accepts a
+Once you have prepared the
+.Tn struct archive
+object, you call
+.Fn archive_read_open
+to actually open the archive and prepare it for reading.
+There are several variants of this function;
+the most basic expects you to provide pointers to several
+functions that can provide blocks of bytes from the archive.
+There are convenience forms that allow you to
+specify a filename, file descriptor,
.Ft "FILE *"
-pointer.
-This function should not be used with tape drives or other devices
-that require strict I/O blocking.
-.It Fn archive_read_open_fd
-Like
-.Fn archive_read_open ,
-except that it accepts a file descriptor and block size rather than
-a set of function pointers.
-Note that the file descriptor will not be automatically closed at
-end-of-archive.
-This function is safe for use with tape drives or other blocked devices.
-.It Fn archive_read_open_file
-This is a deprecated synonym for
-.Fn archive_read_open_filename .
-.It Fn archive_read_open_filename
-Like
-.Fn archive_read_open ,
-except that it accepts a simple filename and a block size.
-A NULL filename represents standard input.
-This function is safe for use with tape drives or other blocked devices.
-.It Fn archive_read_open_memory
-Like
-.Fn archive_read_open ,
-except that it accepts a pointer and size of a block of
-memory containing the archive data.
-.It Fn archive_read_next_header
-Read the header for the next entry and return a pointer to
-a
-.Tn struct archive_entry .
-This is a convenience wrapper around
-.Fn archive_read_next_header2
-that reuses an internal
+object, or a block of memory from which to read the archive data.
+Note that the core library makes no assumptions about the
+size of the blocks read;
+callback functions are free to read whatever block size is
+most appropriate for the medium.
+.\"
+.Ss Consume archive
+See
+.Xr archive_read_header 3 ,
+.Xr archive_read_data 3
+and
+.Xr archive_read_extract 3 .
+.Pp
+Each archive entry consists of a header followed by a certain
+amount of data.
+You can obtain the next header with
+.Fn archive_read_next_header ,
+which returns a pointer to an
.Tn struct archive_entry
-object for each request.
-.It Fn archive_read_next_header2
-Read the header for the next entry and populate the provided
-.Tn struct archive_entry .
-.It Fn archive_read_data
-Read data associated with the header just read.
-Internally, this is a convenience function that calls
-.Fn archive_read_data_block
-and fills any gaps with nulls so that callers see a single
-continuous stream of data.
-.It Fn archive_read_data_block
-Return the next available block of data for this entry.
-Unlike
-.Fn archive_read_data ,
-the
-.Fn archive_read_data_block
-function avoids copying data and allows you to correctly handle
-sparse files, as supported by some archive formats.
-The library guarantees that offsets will increase and that blocks
-will not overlap.
-Note that the blocks returned from this function can be much larger
-than the block size read from disk, due to compression
-and internal buffer optimizations.
-.It Fn archive_read_data_skip
-A convenience function that repeatedly calls
-.Fn archive_read_data_block
-to skip all of the data for this archive entry.
-.\" #if ARCHIVE_API_VERSION < 3
-.It Fn archive_read_data_into_buffer
-This function is deprecated and will be removed.
-Use
+structure with information about the current archive element.
+If the entry is a regular file, then the header will be followed
+by the file data.
+You can use
.Fn archive_read_data
-instead.
-.\" #endif
-.It Fn archive_read_data_into_fd
-A convenience function that repeatedly calls
+(which works much like the
+.Xr read 2
+system call)
+to read this data from the archive, or
.Fn archive_read_data_block
-to copy the entire entry to the provided file descriptor.
-.It Fn archive_read_extract , Fn archive_read_extract_set_skip_file
-A convenience function that wraps the corresponding
-.Xr archive_write_disk 3
-interfaces.
-The first call to
-.Fn archive_read_extract
-creates a restore object using
-.Xr archive_write_disk_new 3
-and
-.Xr archive_write_disk_set_standard_lookup 3 ,
-then transparently invokes
-.Xr archive_write_disk_set_options 3 ,
-.Xr archive_write_header 3 ,
-.Xr archive_write_data 3 ,
-and
-.Xr archive_write_finish_entry 3
-to create the entry on disk and copy data into it.
-The
-.Va flags
-argument is passed unmodified to
-.Xr archive_write_disk_set_options 3 .
-.It Fn archive_read_extract2
-This is another version of
+which provides a slightly more efficient interface.
+You may prefer to use the higher-level
+.Fn archive_read_data_skip ,
+which reads and discards the data for this entry,
+.Fn archive_read_data_to_file ,
+which copies the data to the provided file descriptor, or
+.Fn archive_read_extract ,
+which recreates the specified entry on disk and copies data
+from the archive.
+In particular, note that
.Fn archive_read_extract
-that allows you to provide your own restore object.
-In particular, this allows you to override the standard lookup functions
-using
-.Xr archive_write_disk_set_group_lookup 3 ,
-and
-.Xr archive_write_disk_set_user_lookup 3 .
-Note that
-.Fn archive_read_extract2
-does not accept a
-.Va flags
-argument; you should use
-.Fn archive_write_disk_set_options
-to set the restore options yourself.
-.It Fn archive_read_extract_set_progress_callback
-Sets a pointer to a user-defined callback that can be used
-for updating progress displays during extraction.
-The progress function will be invoked during the extraction of large
-regular files.
-The progress function will be invoked with the pointer provided to this call.
-Generally, the data pointed to should include a reference to the archive
-object and the archive_entry object so that various statistics
-can be retrieved for the progress display.
-.It Fn archive_read_close
-Complete the archive and invoke the close callback.
-.It Fn archive_read_free
-Invokes
-.Fn archive_read_close
-if it was not invoked manually, then release all resources.
-Note: In libarchive 1.x, this function was declared to return
-.Ft void ,
-which made it impossible to detect certain errors when
-.Fn archive_read_close
-was invoked implicitly from this function.
-The declaration is corrected beginning with libarchive 2.0.
-.El
-.Pp
-Note that the library determines most of the relevant information about
-the archive by inspection.
-In particular, it automatically detects
-.Xr gzip 1
-or
-.Xr bzip2 1
-compression and transparently performs the appropriate decompression.
-It also automatically detects the archive format.
-.Pp
-A complete description of the
-.Tn struct archive
-and
+uses the
.Tn struct archive_entry
-objects can be found in the overview manual page for
-.Xr libarchive 3 .
-.Sh CLIENT CALLBACKS
-The callback functions must match the following prototypes:
-.Bl -item -offset indent
-.It
-.Ft typedef ssize_t
-.Fo archive_read_callback
-.Fa "struct archive *"
-.Fa "void *client_data"
-.Fa "const void **buffer"
-.Fc
-.It
-.\" #if ARCHIVE_API_VERSION < 2
-.Ft typedef int
-.Fo archive_skip_callback
-.Fa "struct archive *"
-.Fa "void *client_data"
-.Fa "size_t request"
-.Fc
-.\" #else
-.\" .Ft typedef off_t
-.\" .Fo archive_skip_callback
-.\" .Fa "struct archive *"
-.\" .Fa "void *client_data"
-.\" .Fa "off_t request"
-.\" .Fc
-.\" #endif
-.It
-.Ft typedef int
-.Fn archive_open_callback "struct archive *" "void *client_data"
-.It
-.Ft typedef int
-.Fn archive_close_callback "struct archive *" "void *client_data"
-.El
-.Pp
-The open callback is invoked by
-.Fn archive_open .
-It should return
-.Cm ARCHIVE_OK
-if the underlying file or data source is successfully
-opened.
-If the open fails, it should call
-.Fn archive_set_error
-to register an error code and message and return
-.Cm ARCHIVE_FATAL .
-.Pp
-The read callback is invoked whenever the library
-requires raw bytes from the archive.
-The read callback should read data into a buffer,
-set the
-.Li const void **buffer
-argument to point to the available data, and
-return a count of the number of bytes available.
-The library will invoke the read callback again
-only after it has consumed this data.
-The library imposes no constraints on the size
-of the data blocks returned.
-On end-of-file, the read callback should
-return zero.
-On error, the read callback should invoke
-.Fn archive_set_error
-to register an error code and message and
-return -1.
-.Pp
-The skip callback is invoked when the
-library wants to ignore a block of data.
-The return value is the number of bytes actually
-skipped, which may differ from the request.
-If the callback cannot skip data, it should return
-zero.
-If the skip callback is not provided (the
-function pointer is
-.Dv NULL ),
-the library will invoke the read function
-instead and simply discard the result.
-A skip callback can provide significant
-performance gains when reading uncompressed
-archives from slow disk drives or other media
-that can skip quickly.
+structure that you provide it, which may differ from the
+entry just read from the archive.
+In particular, many applications will want to override the
+pathname, file permissions, or ownership.
+.\"
+.Ss Release resources
+See
+.Xr archive_read_free 3 .
.Pp
-The close callback is invoked by archive_close when
-the archive processing is complete.
-The callback should return
-.Cm ARCHIVE_OK
-on success.
-On failure, the callback should invoke
-.Fn archive_set_error
-to register an error code and message and
-return
-.Cm ARCHIVE_FATAL.
+Once you have finished reading data from the archive, you
+should call
+.Fn archive_read_close
+to close the archive, then call
+.Fn archive_read_free
+to release all resources, including all memory allocated by the library.
+.\"
.Sh EXAMPLE
The following illustrates basic usage of the library.
In this example,
@@ -593,7 +173,7 @@ list_archive(const char *name)
mydata = malloc(sizeof(struct mydata));
a = archive_read_new();
mydata->name = name;
- archive_read_support_compression_all(a);
+ archive_read_support_filter_all(a);
archive_read_support_format_all(a);
archive_read_open(a, mydata, myopen, myread, myclose);
while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
@@ -632,62 +212,18 @@ myclose(struct archive *a, void *client_data)
return (ARCHIVE_OK);
}
.Ed
-.Sh RETURN VALUES
-Most functions return zero on success, non-zero on error.
-The possible return codes include:
-.Cm ARCHIVE_OK
-(the operation succeeded),
-.Cm ARCHIVE_WARN
-(the operation succeeded but a non-critical error was encountered),
-.Cm ARCHIVE_EOF
-(end-of-archive was encountered),
-.Cm ARCHIVE_RETRY
-(the operation failed but can be retried),
-and
-.Cm ARCHIVE_FATAL
-(there was a fatal error; the archive should be closed immediately).
-Detailed error codes and textual descriptions are available from the
-.Fn archive_errno
-and
-.Fn archive_error_string
-functions.
-.Pp
-.Fn archive_read_new
-returns a pointer to a freshly allocated
-.Tn struct archive
-object.
-It returns
-.Dv NULL
-on error.
-.Pp
-.Fn archive_read_data
-returns a count of bytes actually read or zero at the end of the entry.
-On error, a value of
-.Cm ARCHIVE_FATAL ,
-.Cm ARCHIVE_WARN ,
-or
-.Cm ARCHIVE_RETRY
-is returned and an error code and textual description can be retrieved from the
-.Fn archive_errno
-and
-.Fn archive_error_string
-functions.
-.Pp
-The library expects the client callbacks to behave similarly.
-If there is an error, you can use
-.Fn archive_set_error
-to set an appropriate error code and description,
-then return one of the non-zero values above.
-(Note that the value eventually returned to the client may
-not be the same; many errors that are not critical at the level
-of basic I/O can prevent the archive from being properly read,
-thus most I/O errors eventually cause
-.Cm ARCHIVE_FATAL
-to be returned.)
.\" .Sh ERRORS
.Sh SEE ALSO
.Xr tar 1 ,
-.Xr archive 3 ,
+.Xr libarchive 3 ,
+.Xr archive_read_new 3 ,
+.Xr archive_read_data 3 ,
+.Xr archive_read_extract 3 ,
+.Xr archive_read_filter 3 ,
+.Xr archive_read_format 3 ,
+.Xr archive_read_header 3 ,
+.Xr archive_read_open 3 ,
+.Xr archive_read_set_options 3 ,
.Xr archive_util 3 ,
.Xr tar 5
.Sh HISTORY
diff --git a/libarchive/archive_read.c b/libarchive/archive_read.c
index 90b9bee535cd..b1d491435421 100644
--- a/libarchive/archive_read.c
+++ b/libarchive/archive_read.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2003-2011 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -55,12 +55,24 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read.c 201157 2009-12-29 05:30:2
#define minimum(a, b) (a < b ? a : b)
-static int build_stream(struct archive_read *);
+static int choose_filters(struct archive_read *);
static int choose_format(struct archive_read *);
-static int cleanup_filters(struct archive_read *);
+static void free_filters(struct archive_read *);
+static int close_filters(struct archive_read *);
static struct archive_vtable *archive_read_vtable(void);
+static int64_t _archive_filter_bytes(struct archive *, int);
+static int _archive_filter_code(struct archive *, int);
+static const char *_archive_filter_name(struct archive *, int);
+static int _archive_filter_count(struct archive *);
static int _archive_read_close(struct archive *);
+static int _archive_read_data_block(struct archive *,
+ const void **, size_t *, int64_t *);
static int _archive_read_free(struct archive *);
+static int _archive_read_next_header(struct archive *,
+ struct archive_entry **);
+static int _archive_read_next_header2(struct archive *,
+ struct archive_entry *);
+static int64_t advance_file_pointer(struct archive_read_filter *, int64_t);
static struct archive_vtable *
archive_read_vtable(void)
@@ -69,8 +81,16 @@ archive_read_vtable(void)
static int inited = 0;
if (!inited) {
+ av.archive_filter_bytes = _archive_filter_bytes;
+ av.archive_filter_code = _archive_filter_code;
+ av.archive_filter_name = _archive_filter_name;
+ av.archive_filter_count = _archive_filter_count;
+ av.archive_read_data_block = _archive_read_data_block;
+ av.archive_read_next_header = _archive_read_next_header;
+ av.archive_read_next_header2 = _archive_read_next_header2;
av.archive_free = _archive_read_free;
av.archive_close = _archive_read_close;
+ inited = 1;
}
return (&av);
}
@@ -90,7 +110,7 @@ archive_read_new(void)
a->archive.magic = ARCHIVE_READ_MAGIC;
a->archive.state = ARCHIVE_STATE_NEW;
- a->entry = archive_entry_new();
+ a->entry = archive_entry_new2(&a->archive);
a->archive.vtable = archive_read_vtable();
return (&a->archive);
@@ -100,143 +120,51 @@ archive_read_new(void)
* Record the do-not-extract-to file. This belongs in archive_read_extract.c.
*/
void
-archive_read_extract_set_skip_file(struct archive *_a, dev_t d, ino_t i)
+archive_read_extract_set_skip_file(struct archive *_a, int64_t d, int64_t i)
{
struct archive_read *a = (struct archive_read *)_a;
- __archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_ANY,
- "archive_read_extract_set_skip_file");
+
+ if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_extract_set_skip_file"))
+ return;
+ a->skip_file_set = 1;
a->skip_file_dev = d;
a->skip_file_ino = i;
}
/*
- * Set read options for the format.
+ * Open the archive
*/
int
-archive_read_set_format_options(struct archive *_a, const char *s)
+archive_read_open(struct archive *a, void *client_data,
+ archive_open_callback *client_opener, archive_read_callback *client_reader,
+ archive_close_callback *client_closer)
{
- struct archive_read *a;
- struct archive_format_descriptor *format;
- char key[64], val[64];
- char *valp;
- size_t i;
- int len, r;
-
- __archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
- "archive_read_set_format_options");
-
- if (s == NULL || *s == '\0')
- return (ARCHIVE_OK);
- a = (struct archive_read *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_NEW, "archive_read_set_format_options");
- len = 0;
- for (i = 0; i < sizeof(a->formats)/sizeof(a->formats[0]); i++) {
- format = &a->formats[i];
- if (format == NULL || format->options == NULL ||
- format->name == NULL)
- /* This format does not support option. */
- continue;
-
- while ((len = __archive_parse_options(s, format->name,
- sizeof(key), key, sizeof(val), val)) > 0) {
- valp = val[0] == '\0' ? NULL : val;
- a->format = format;
- r = format->options(a, key, valp);
- a->format = NULL;
- if (r == ARCHIVE_FATAL)
- return (r);
- s += len;
- }
- }
- if (len < 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Illegal format options.");
- return (ARCHIVE_WARN);
- }
- return (ARCHIVE_OK);
+ /* Old archive_read_open() is just a thin shell around
+ * archive_read_open1. */
+ archive_read_set_open_callback(a, client_opener);
+ archive_read_set_read_callback(a, client_reader);
+ archive_read_set_close_callback(a, client_closer);
+ archive_read_set_callback_data(a, client_data);
+ return archive_read_open1(a);
}
-/*
- * Set read options for the filter.
- */
-int
-archive_read_set_filter_options(struct archive *_a, const char *s)
-{
- struct archive_read *a;
- struct archive_read_filter *filter;
- struct archive_read_filter_bidder *bidder;
- char key[64], val[64];
- int len, r;
-
- __archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
- "archive_read_set_filter_options");
-
- if (s == NULL || *s == '\0')
- return (ARCHIVE_OK);
- a = (struct archive_read *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_NEW, "archive_read_set_filter_options");
- len = 0;
- for (filter = a->filter; filter != NULL; filter = filter->upstream) {
- bidder = filter->bidder;
- if (bidder == NULL)
- continue;
- if (bidder->options == NULL)
- /* This bidder does not support option */
- continue;
- while ((len = __archive_parse_options(s, filter->name,
- sizeof(key), key, sizeof(val), val)) > 0) {
- if (val[0] == '\0')
- r = bidder->options(bidder, key, NULL);
- else
- r = bidder->options(bidder, key, val);
- if (r == ARCHIVE_FATAL)
- return (r);
- s += len;
- }
- }
- if (len < 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Illegal format options.");
- return (ARCHIVE_WARN);
- }
- return (ARCHIVE_OK);
-}
-/*
- * Set read options for the format and the filter.
- */
int
-archive_read_set_options(struct archive *_a, const char *s)
-{
- int r;
-
- __archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
- "archive_read_set_options");
- archive_clear_error(_a);
-
- r = archive_read_set_format_options(_a, s);
- if (r != ARCHIVE_OK)
- return (r);
- r = archive_read_set_filter_options(_a, s);
- if (r != ARCHIVE_OK)
- return (r);
- return (ARCHIVE_OK);
-}
-
-/*
- * Open the archive
- */
-int
-archive_read_open(struct archive *a, void *client_data,
- archive_open_callback *client_opener, archive_read_callback *client_reader,
+archive_read_open2(struct archive *a, void *client_data,
+ archive_open_callback *client_opener,
+ archive_read_callback *client_reader,
+ archive_skip_callback *client_skipper,
archive_close_callback *client_closer)
{
- /* Old archive_read_open() is just a thin shell around
- * archive_read_open2. */
- return archive_read_open2(a, client_data, client_opener,
- client_reader, NULL, client_closer);
+ /* Old archive_read_open2() is just a thin shell around
+ * archive_read_open1. */
+ archive_read_set_callback_data(a, client_data);
+ archive_read_set_open_callback(a, client_opener);
+ archive_read_set_read_callback(a, client_reader);
+ archive_read_set_skip_callback(a, client_skipper);
+ archive_read_set_close_callback(a, client_closer);
+ return archive_read_open1(a);
}
static ssize_t
@@ -245,33 +173,70 @@ client_read_proxy(struct archive_read_filter *self, const void **buff)
ssize_t r;
r = (self->archive->client.reader)(&self->archive->archive,
self->data, buff);
- self->archive->archive.raw_position += r;
return (r);
}
static int64_t
client_skip_proxy(struct archive_read_filter *self, int64_t request)
{
- int64_t ask, get, total;
- /* Limit our maximum seek request to 1GB on platforms
- * with 32-bit off_t (such as Windows). */
- int64_t skip_limit = ((int64_t)1) << (sizeof(off_t) * 8 - 2);
-
- if (self->archive->client.skipper == NULL)
- return (0);
- total = 0;
- for (;;) {
- ask = request;
- if (ask > skip_limit)
- ask = skip_limit;
- get = (self->archive->client.skipper)(&self->archive->archive,
- self->data, ask);
- if (get == 0)
- return (total);
- request -= get;
- self->archive->archive.raw_position += get;
- total += get;
+ if (request < 0)
+ __archive_errx(1, "Negative skip requested.");
+ if (request == 0)
+ return 0;
+
+ if (self->archive->client.skipper != NULL) {
+ /* Seek requests over 1GiB are broken down into
+ * multiple seeks. This avoids overflows when the
+ * requests get passed through 32-bit arguments. */
+ int64_t skip_limit = (int64_t)1 << 30;
+ int64_t total = 0;
+ for (;;) {
+ int64_t get, ask = request;
+ if (ask > skip_limit)
+ ask = skip_limit;
+ get = (self->archive->client.skipper)(&self->archive->archive,
+ self->data, ask);
+ if (get == 0)
+ return (total);
+ request -= get;
+ total += get;
+ }
+ return total;
+ } else if (self->archive->client.seeker != NULL
+ && request > 64 * 1024) {
+ /* If the client provided a seeker but not a skipper,
+ * we can use the seeker to skip forward.
+ *
+ * Note: This isn't always a good idea. The client
+ * skipper is allowed to skip by less than requested
+ * if it needs to maintain block alignment. The
+ * seeker is not allowed to play such games, so using
+ * the seeker here may be a performance loss compared
+ * to just reading and discarding. That's why we
+ * only do this for skips of over 64k.
+ */
+ int64_t before = self->position;
+ int64_t after = (self->archive->client.seeker)(&self->archive->archive,
+ self->data, request, SEEK_CUR);
+ if (after != before + request)
+ return ARCHIVE_FATAL;
+ return after - before;
}
+ return 0;
+}
+
+static int64_t
+client_seek_proxy(struct archive_read_filter *self, int64_t offset, int whence)
+{
+ /* DO NOT use the skipper here! If we transparently handled
+ * forward seek here by using the skipper, that will break
+ * other libarchive code that assumes a successful forward
+ * seek means it can also seek backwards.
+ */
+ if (self->archive->client.seeker == NULL)
+ return (ARCHIVE_FAILED);
+ return (self->archive->client.seeker)(&self->archive->archive,
+ self->data, offset, whence);
}
static int
@@ -282,65 +247,134 @@ client_close_proxy(struct archive_read_filter *self)
if (self->archive->client.closer != NULL)
r = (self->archive->client.closer)((struct archive *)self->archive,
self->data);
- self->data = NULL;
return (r);
}
+int
+archive_read_set_open_callback(struct archive *_a,
+ archive_open_callback *client_opener)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
+ "archive_read_set_open_callback");
+ a->client.opener = client_opener;
+ return ARCHIVE_OK;
+}
int
-archive_read_open2(struct archive *_a, void *client_data,
- archive_open_callback *client_opener,
- archive_read_callback *client_reader,
- archive_skip_callback *client_skipper,
+archive_read_set_read_callback(struct archive *_a,
+ archive_read_callback *client_reader)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
+ "archive_read_set_read_callback");
+ a->client.reader = client_reader;
+ return ARCHIVE_OK;
+}
+
+int
+archive_read_set_skip_callback(struct archive *_a,
+ archive_skip_callback *client_skipper)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
+ "archive_read_set_skip_callback");
+ a->client.skipper = client_skipper;
+ return ARCHIVE_OK;
+}
+
+int
+archive_read_set_seek_callback(struct archive *_a,
+ archive_seek_callback *client_seeker)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
+ "archive_read_set_seek_callback");
+ a->client.seeker = client_seeker;
+ return ARCHIVE_OK;
+}
+
+int
+archive_read_set_close_callback(struct archive *_a,
archive_close_callback *client_closer)
{
struct archive_read *a = (struct archive_read *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
+ "archive_read_set_close_callback");
+ a->client.closer = client_closer;
+ return ARCHIVE_OK;
+}
+
+int
+archive_read_set_callback_data(struct archive *_a, void *client_data)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
+ "archive_read_set_callback_data");
+ a->client.data = client_data;
+ return ARCHIVE_OK;
+}
+
+int
+archive_read_open1(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
struct archive_read_filter *filter;
- int e;
+ int slot, e;
- __archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
"archive_read_open");
archive_clear_error(&a->archive);
- if (client_reader == NULL)
- __archive_errx(1,
+ if (a->client.reader == NULL) {
+ archive_set_error(&a->archive, EINVAL,
"No reader function provided to archive_read_open");
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+ }
/* Open data source. */
- if (client_opener != NULL) {
- e =(client_opener)(&a->archive, client_data);
+ if (a->client.opener != NULL) {
+ e =(a->client.opener)(&a->archive, a->client.data);
if (e != 0) {
/* If the open failed, call the closer to clean up. */
- if (client_closer)
- (client_closer)(&a->archive, client_data);
+ if (a->client.closer)
+ (a->client.closer)(&a->archive, a->client.data);
return (e);
}
}
- /* Save the client functions and mock up the initial source. */
- a->client.reader = client_reader;
- a->client.skipper = client_skipper;
- a->client.closer = client_closer;
-
filter = calloc(1, sizeof(*filter));
if (filter == NULL)
return (ARCHIVE_FATAL);
filter->bidder = NULL;
filter->upstream = NULL;
filter->archive = a;
- filter->data = client_data;
+ filter->data = a->client.data;
filter->read = client_read_proxy;
filter->skip = client_skip_proxy;
+ filter->seek = client_seek_proxy;
filter->close = client_close_proxy;
filter->name = "none";
filter->code = ARCHIVE_COMPRESSION_NONE;
a->filter = filter;
/* Build out the input pipeline. */
- e = build_stream(a);
- if (e == ARCHIVE_OK)
- a->archive.state = ARCHIVE_STATE_HEADER;
+ e = choose_filters(a);
+ if (e < ARCHIVE_WARN) {
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+ }
+
+ slot = choose_format(a);
+ if (slot < 0) {
+ close_filters(a);
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+ }
+ a->format = &(a->formats[slot]);
+ a->archive.state = ARCHIVE_STATE_HEADER;
return (e);
}
@@ -350,7 +384,7 @@ archive_read_open2(struct archive *_a, void *client_data,
* building the pipeline.
*/
static int
-build_stream(struct archive_read *a)
+choose_filters(struct archive_read *a)
{
int number_bidders, i, bid, best_bid;
struct archive_read_filter_bidder *bidder, *best_bidder;
@@ -377,10 +411,11 @@ build_stream(struct archive_read *a)
/* If no bidder, we're done. */
if (best_bidder == NULL) {
- /* Verify the final pipelin by asking it for some data. */
+ /* Verify the filter by asking it for some data. */
__archive_read_filter_ahead(a->filter, 1, &avail);
if (avail < 0) {
- cleanup_filters(a);
+ close_filters(a);
+ free_filters(a);
return (ARCHIVE_FATAL);
}
a->archive.compression_name = a->filter->name;
@@ -398,8 +433,9 @@ build_stream(struct archive_read *a)
a->filter = filter;
r = (best_bidder->init)(a->filter);
if (r != ARCHIVE_OK) {
- cleanup_filters(a);
- return (r);
+ close_filters(a);
+ free_filters(a);
+ return (ARCHIVE_FATAL);
}
}
}
@@ -407,60 +443,49 @@ build_stream(struct archive_read *a)
/*
* Read header of next entry.
*/
-int
-archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
+static int
+_archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
{
struct archive_read *a = (struct archive_read *)_a;
- int slot, ret;
+ int r1 = ARCHIVE_OK, r2;
- __archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
"archive_read_next_header");
- ++_a->file_count;
archive_entry_clear(entry);
archive_clear_error(&a->archive);
/*
- * If no format has yet been chosen, choose one.
- */
- if (a->format == NULL) {
- slot = choose_format(a);
- if (slot < 0) {
- a->archive.state = ARCHIVE_STATE_FATAL;
- return (ARCHIVE_FATAL);
- }
- a->format = &(a->formats[slot]);
- }
-
- /*
* If client didn't consume entire data, skip any remainder
* (This is especially important for GNU incremental directories.)
*/
if (a->archive.state == ARCHIVE_STATE_DATA) {
- ret = archive_read_data_skip(&a->archive);
- if (ret == ARCHIVE_EOF) {
- archive_set_error(&a->archive, EIO, "Premature end-of-file.");
+ r1 = archive_read_data_skip(&a->archive);
+ if (r1 == ARCHIVE_EOF)
+ archive_set_error(&a->archive, EIO,
+ "Premature end-of-file.");
+ if (r1 == ARCHIVE_EOF || r1 == ARCHIVE_FATAL) {
a->archive.state = ARCHIVE_STATE_FATAL;
return (ARCHIVE_FATAL);
}
- if (ret != ARCHIVE_OK)
- return (ret);
}
- /* Record start-of-header. */
- a->header_position = a->archive.file_position;
+ /* Record start-of-header offset in uncompressed stream. */
+ a->header_position = a->filter->position;
- ret = (a->format->read_header)(a, entry);
+ ++_a->file_count;
+ r2 = (a->format->read_header)(a, entry);
/*
* EOF and FATAL are persistent at this layer. By
* modifying the state, we guarantee that future calls to
* read a header or read data will fail.
*/
- switch (ret) {
+ switch (r2) {
case ARCHIVE_EOF:
a->archive.state = ARCHIVE_STATE_EOF;
+ --_a->file_count;/* Revert a file counter. */
break;
case ARCHIVE_OK:
a->archive.state = ARCHIVE_STATE_DATA;
@@ -477,16 +502,17 @@ archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
a->read_data_output_offset = 0;
a->read_data_remaining = 0;
- return (ret);
+ /* EOF always wins; otherwise return the worst error. */
+ return (r2 < r1 || r2 == ARCHIVE_EOF) ? r2 : r1;
}
int
-archive_read_next_header(struct archive *_a, struct archive_entry **entryp)
+_archive_read_next_header(struct archive *_a, struct archive_entry **entryp)
{
int ret;
struct archive_read *a = (struct archive_read *)_a;
*entryp = NULL;
- ret = archive_read_next_header2(_a, a->entry);
+ ret = _archive_read_next_header2(_a, a->entry);
*entryp = a->entry;
return ret;
}
@@ -507,13 +533,15 @@ choose_format(struct archive_read *a)
best_bid = -1;
best_bid_slot = -1;
- /* Set up a->format and a->pformat_data for convenience of bidders. */
+ /* Set up a->format for convenience of bidders. */
a->format = &(a->formats[0]);
for (i = 0; i < slots; i++, a->format++) {
if (a->format->bid) {
- bid = (a->format->bid)(a);
+ bid = (a->format->bid)(a, best_bid);
if (bid == ARCHIVE_FATAL)
return (ARCHIVE_FATAL);
+ if (a->filter->position != 0)
+ __archive_read_seek(a, 0, SEEK_SET);
if ((bid > best_bid) || (best_bid_slot < 0)) {
best_bid = bid;
best_bid_slot = i;
@@ -525,10 +553,11 @@ choose_format(struct archive_read *a)
* There were no bidders; this is a serious programmer error
* and demands a quick and definitive abort.
*/
- if (best_bid_slot < 0)
- __archive_errx(1, "No formats were registered; you must "
- "invoke at least one archive_read_support_format_XXX "
- "function in order to successfully read an archive.");
+ if (best_bid_slot < 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "No formats registered");
+ return (ARCHIVE_FATAL);
+ }
/*
* There were bidders, but no non-zero bids; this means we
@@ -551,7 +580,7 @@ int64_t
archive_read_header_position(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
- __archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
ARCHIVE_STATE_ANY, "archive_read_header_position");
return (a->header_position);
}
@@ -583,7 +612,7 @@ archive_read_data(struct archive *_a, void *buff, size_t s)
while (s > 0) {
if (a->read_data_remaining == 0) {
read_buf = a->read_data_block;
- r = archive_read_data_block(&a->archive, &read_buf,
+ r = _archive_read_data_block(&a->archive, &read_buf,
&a->read_data_remaining, &a->read_data_offset);
a->read_data_block = read_buf;
if (r == ARCHIVE_EOF)
@@ -604,7 +633,7 @@ archive_read_data(struct archive *_a, void *buff, size_t s)
}
/* Compute the amount of zero padding needed. */
- if (a->read_data_output_offset + (off_t)s <
+ if (a->read_data_output_offset + s <
a->read_data_offset) {
len = s;
} else if (a->read_data_output_offset <
@@ -639,22 +668,6 @@ archive_read_data(struct archive *_a, void *buff, size_t s)
return (bytes_read);
}
-#if ARCHIVE_API_VERSION < 3
-/*
- * Obsolete function provided for compatibility only. Note that the API
- * of this function doesn't allow the caller to detect if the remaining
- * data from the archive entry is shorter than the buffer provided, or
- * even if an error occurred while reading data.
- */
-int
-archive_read_data_into_buffer(struct archive *a, void *d, ssize_t len)
-{
-
- archive_read_data(a, d, len);
- return (ARCHIVE_OK);
-}
-#endif
-
/*
* Skip over all remaining data in this entry.
*/
@@ -665,9 +678,9 @@ archive_read_data_skip(struct archive *_a)
int r;
const void *buff;
size_t size;
- off_t offset;
+ int64_t offset;
- __archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA,
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA,
"archive_read_data_skip");
if (a->format->read_data_skip != NULL)
@@ -694,12 +707,12 @@ archive_read_data_skip(struct archive *_a)
* Returns ARCHIVE_OK if the operation is successful, ARCHIVE_EOF if
* the end of entry is encountered.
*/
-int
-archive_read_data_block(struct archive *_a,
- const void **buff, size_t *size, off_t *offset)
+static int
+_archive_read_data_block(struct archive *_a,
+ const void **buff, size_t *size, int64_t *offset)
{
struct archive_read *a = (struct archive_read *)_a;
- __archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA,
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA,
"archive_read_data_block");
if (a->format->read_data == NULL) {
@@ -712,69 +725,79 @@ archive_read_data_block(struct archive *_a,
return (a->format->read_data)(a, buff, size, offset);
}
+static int
+close_filters(struct archive_read *a)
+{
+ struct archive_read_filter *f = a->filter;
+ int r = ARCHIVE_OK;
+ /* Close each filter in the pipeline. */
+ while (f != NULL) {
+ struct archive_read_filter *t = f->upstream;
+ if (!f->closed && f->close != NULL) {
+ int r1 = (f->close)(f);
+ f->closed = 1;
+ if (r1 < r)
+ r = r1;
+ }
+ free(f->buffer);
+ f->buffer = NULL;
+ f = t;
+ }
+ return r;
+}
+
+static void
+free_filters(struct archive_read *a)
+{
+ while (a->filter != NULL) {
+ struct archive_read_filter *t = a->filter->upstream;
+ free(a->filter);
+ a->filter = t;
+ }
+}
+
/*
- * Close the file and release most resources.
- *
- * Be careful: client might just call read_new and then read_finish.
- * Don't assume we actually read anything or performed any non-trivial
- * initialization.
+ * return the count of # of filters in use
+ */
+static int
+_archive_filter_count(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct archive_read_filter *p = a->filter;
+ int count = 0;
+ while(p) {
+ count++;
+ p = p->upstream;
+ }
+ return count;
+}
+
+/*
+ * Close the file and all I/O.
*/
static int
_archive_read_close(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
int r = ARCHIVE_OK, r1 = ARCHIVE_OK;
- size_t i, n;
- __archive_check_magic(&a->archive, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_ANY, "archive_read_close");
+ archive_check_magic(&a->archive, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_close");
+ if (a->archive.state == ARCHIVE_STATE_CLOSED)
+ return (ARCHIVE_OK);
archive_clear_error(&a->archive);
a->archive.state = ARCHIVE_STATE_CLOSED;
-
- /* Call cleanup functions registered by optional components. */
- if (a->cleanup_archive_extract != NULL)
- r = (a->cleanup_archive_extract)(a);
-
/* TODO: Clean up the formatters. */
/* Release the filter objects. */
- r1 = cleanup_filters(a);
+ r1 = close_filters(a);
if (r1 < r)
r = r1;
- /* Release the bidder objects. */
- n = sizeof(a->bidders)/sizeof(a->bidders[0]);
- for (i = 0; i < n; i++) {
- if (a->bidders[i].free != NULL) {
- r1 = (a->bidders[i].free)(&a->bidders[i]);
- if (r1 < r)
- r = r1;
- }
- }
-
return (r);
}
-static int
-cleanup_filters(struct archive_read *a)
-{
- int r = ARCHIVE_OK;
- /* Clean up the filter pipeline. */
- while (a->filter != NULL) {
- struct archive_read_filter *t = a->filter->upstream;
- if (a->filter->close != NULL) {
- int r1 = (a->filter->close)(a->filter);
- if (r1 < r)
- r = r1;
- }
- free(a->filter->buffer);
- free(a->filter);
- a->filter = t;
- }
- return r;
-}
-
/*
* Release memory and other resources.
*/
@@ -782,15 +805,22 @@ static int
_archive_read_free(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
- int i;
+ int i, n;
int slots;
int r = ARCHIVE_OK;
- __archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_ANY,
- "archive_read_free");
- if (a->archive.state != ARCHIVE_STATE_CLOSED)
+ if (_a == NULL)
+ return (ARCHIVE_OK);
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_free");
+ if (a->archive.state != ARCHIVE_STATE_CLOSED
+ && a->archive.state != ARCHIVE_STATE_FATAL)
r = archive_read_close(&a->archive);
+ /* Call cleanup functions registered by optional components. */
+ if (a->cleanup_archive_extract != NULL)
+ r = (a->cleanup_archive_extract)(a);
+
/* Cleanup format-specific data. */
slots = sizeof(a->formats) / sizeof(a->formats[0]);
for (i = 0; i < slots; i++) {
@@ -799,14 +829,71 @@ _archive_read_free(struct archive *_a)
(a->formats[i].cleanup)(a);
}
+ /* Free the filters */
+ free_filters(a);
+
+ /* Release the bidder objects. */
+ n = sizeof(a->bidders)/sizeof(a->bidders[0]);
+ for (i = 0; i < n; i++) {
+ if (a->bidders[i].free != NULL) {
+ int r1 = (a->bidders[i].free)(&a->bidders[i]);
+ if (r1 < r)
+ r = r1;
+ }
+ }
+
archive_string_free(&a->archive.error_string);
if (a->entry)
archive_entry_free(a->entry);
a->archive.magic = 0;
+ __archive_clean(&a->archive);
free(a);
-#if ARCHIVE_API_VERSION > 1
return (r);
-#endif
+}
+
+static struct archive_read_filter *
+get_filter(struct archive *_a, int n)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct archive_read_filter *f = a->filter;
+ /* We use n == -1 for 'the last filter', which is always the client proxy. */
+ if (n == -1 && f != NULL) {
+ struct archive_read_filter *last = f;
+ f = f->upstream;
+ while (f != NULL) {
+ last = f;
+ f = f->upstream;
+ }
+ return (last);
+ }
+ if (n < 0)
+ return NULL;
+ while (n > 0 && f != NULL) {
+ f = f->upstream;
+ --n;
+ }
+ return (f);
+}
+
+static int
+_archive_filter_code(struct archive *_a, int n)
+{
+ struct archive_read_filter *f = get_filter(_a, n);
+ return f == NULL ? -1 : f->code;
+}
+
+static const char *
+_archive_filter_name(struct archive *_a, int n)
+{
+ struct archive_read_filter *f = get_filter(_a, n);
+ return f == NULL ? NULL : f->name;
+}
+
+static int64_t
+_archive_filter_bytes(struct archive *_a, int n)
+{
+ struct archive_read_filter *f = get_filter(_a, n);
+ return f == NULL ? -1 : f->position;
}
/*
@@ -817,16 +904,16 @@ int
__archive_read_register_format(struct archive_read *a,
void *format_data,
const char *name,
- int (*bid)(struct archive_read *),
+ int (*bid)(struct archive_read *, int),
int (*options)(struct archive_read *, const char *, const char *),
int (*read_header)(struct archive_read *, struct archive_entry *),
- int (*read_data)(struct archive_read *, const void **, size_t *, off_t *),
+ int (*read_data)(struct archive_read *, const void **, size_t *, int64_t *),
int (*read_data_skip)(struct archive_read *),
int (*cleanup)(struct archive_read *))
{
int i, number_slots;
- __archive_check_magic(&a->archive,
+ archive_check_magic(&a->archive,
ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
"__archive_read_register_format");
@@ -848,74 +935,68 @@ __archive_read_register_format(struct archive_read *a,
}
}
- __archive_errx(1, "Not enough slots for format registration");
- return (ARCHIVE_FATAL); /* Never actually called. */
+ archive_set_error(&a->archive, ENOMEM,
+ "Not enough slots for format registration");
+ return (ARCHIVE_FATAL);
}
/*
* Used internally by decompression routines to register their bid and
* initialization functions.
*/
-struct archive_read_filter_bidder *
-__archive_read_get_bidder(struct archive_read *a)
+int
+__archive_read_get_bidder(struct archive_read *a,
+ struct archive_read_filter_bidder **bidder)
{
int i, number_slots;
- __archive_check_magic(&a->archive,
- ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
- "__archive_read_get_bidder");
-
number_slots = sizeof(a->bidders) / sizeof(a->bidders[0]);
for (i = 0; i < number_slots; i++) {
if (a->bidders[i].bid == NULL) {
memset(a->bidders + i, 0, sizeof(a->bidders[0]));
- return (a->bidders + i);
+ *bidder = (a->bidders + i);
+ return (ARCHIVE_OK);
}
}
- __archive_errx(1, "Not enough slots for compression registration");
- return (NULL); /* Never actually executed. */
+ archive_set_error(&a->archive, ENOMEM,
+ "Not enough slots for filter registration");
+ return (ARCHIVE_FATAL);
}
/*
- * The next three functions comprise the peek/consume internal I/O
- * system used by archive format readers. This system allows fairly
- * flexible read-ahead and allows the I/O code to operate in a
- * zero-copy manner most of the time.
+ * The next section implements the peek/consume internal I/O
+ * system used by archive readers. This system allows simple
+ * read-ahead for consumers while preserving zero-copy operation
+ * most of the time.
+ *
+ * The two key operations:
+ * * The read-ahead function returns a pointer to a block of data
+ * that satisfies a minimum request.
+ * * The consume function advances the file pointer.
*
* In the ideal case, filters generate blocks of data
* and __archive_read_ahead() just returns pointers directly into
* those blocks. Then __archive_read_consume() just bumps those
* pointers. Only if your request would span blocks does the I/O
* layer use a copy buffer to provide you with a contiguous block of
- * data. The __archive_read_skip() is an optimization; it scans ahead
- * very quickly (it usually translates into a seek() operation if
- * you're reading uncompressed disk files).
+ * data.
*
* A couple of useful idioms:
* * "I just want some data." Ask for 1 byte and pay attention to
* the "number of bytes available" from __archive_read_ahead().
- * You can consume more than you asked for; you just can't consume
- * more than is available. If you consume everything that's
- * immediately available, the next read_ahead() call will pull
- * the next block.
+ * Consume whatever you actually use.
* * "I want to output a large block of data." As above, ask for 1 byte,
- * emit all that's available (up to whatever limit you have), then
- * repeat until you're done.
+ * emit all that's available (up to whatever limit you have), consume
+ * it all, then repeat until you're done. This effectively means that
+ * you're passing along the blocks that came from your provider.
* * "I want to peek ahead by a large amount." Ask for 4k or so, then
* double and repeat until you get an error or have enough. Note
* that the I/O layer will likely end up expanding its copy buffer
* to fit your request, so use this technique cautiously. This
* technique is used, for example, by some of the format tasting
* code that has uncertain look-ahead needs.
- *
- * TODO: Someday, provide a more generic __archive_read_seek() for
- * those cases where it's useful. This is tricky because there are lots
- * of cases where seek() is not available (reading gzip data from a
- * network socket, for instance), so there needs to be a good way to
- * communicate whether seek() is available and users of that interface
- * need to use non-seeking strategies whenever seek() is not available.
*/
/*
@@ -924,8 +1005,8 @@ __archive_read_get_bidder(struct archive_read *a)
* in the current buffer, which may be much larger than requested.
* * If end-of-file, *avail gets set to zero.
* * If error, *avail gets error code.
- * * If request can be met, returns pointer to data, returns NULL
- * if request is not met.
+ * * If request can be met, returns pointer to data.
+ * * If minimum request cannot be met, returns NULL.
*
* Note: If you just want "some data", ask for 1 byte and pay attention
* to *avail, which will have the actual amount available. If you
@@ -935,17 +1016,6 @@ __archive_read_get_bidder(struct archive_read *a)
* Important: This does NOT move the file pointer. See
* __archive_read_consume() below.
*/
-
-/*
- * This is tricky. We need to provide our clients with pointers to
- * contiguous blocks of memory but we want to avoid copying whenever
- * possible.
- *
- * Mostly, this code returns pointers directly into the block of data
- * provided by the client_read routine. It can do this unless the
- * request would split across blocks. In that case, we have to copy
- * into an internal buffer to combine reads.
- */
const void *
__archive_read_ahead(struct archive_read *a, size_t min, ssize_t *avail)
{
@@ -1034,7 +1104,6 @@ __archive_read_filter_ahead(struct archive_read_filter *filter,
*avail = filter->avail;
return (NULL);
}
- filter->position += bytes_read;
filter->client_total = bytes_read;
filter->client_avail = filter->client_total;
filter->client_next = filter->client_buff;
@@ -1114,136 +1183,160 @@ __archive_read_filter_ahead(struct archive_read_filter *filter,
}
/*
- * Move the file pointer forward. This should be called after
- * __archive_read_ahead() returns data to you. Don't try to move
- * ahead by more than the amount of data available according to
- * __archive_read_ahead().
- */
-/*
- * Mark the appropriate data as used. Note that the request here will
- * often be much smaller than the size of the previous read_ahead
- * request.
+ * Move the file pointer forward.
*/
-ssize_t
-__archive_read_consume(struct archive_read *a, size_t request)
+int64_t
+__archive_read_consume(struct archive_read *a, int64_t request)
{
- ssize_t r;
- r = __archive_read_filter_consume(a->filter, request);
- a->archive.file_position += r;
- return (r);
+ return (__archive_read_filter_consume(a->filter, request));
}
-ssize_t
+int64_t
__archive_read_filter_consume(struct archive_read_filter * filter,
- size_t request)
+ int64_t request)
{
- if (filter->avail > 0) {
- /* Read came from copy buffer. */
- filter->next += request;
- filter->avail -= request;
- } else {
- /* Read came from client buffer. */
- filter->client_next += request;
- filter->client_avail -= request;
- }
- return (request);
-}
+ int64_t skipped;
-/*
- * Move the file pointer ahead by an arbitrary amount. If you're
- * reading uncompressed data from a disk file, this will actually
- * translate into a seek() operation. Even in cases where seek()
- * isn't feasible, this at least pushes the read-and-discard loop
- * down closer to the data source.
- */
-int64_t
-__archive_read_skip(struct archive_read *a, int64_t request)
-{
- int64_t skipped = __archive_read_skip_lenient(a, request);
+ if (request == 0)
+ return 0;
+
+ skipped = advance_file_pointer(filter, request);
if (skipped == request)
return (skipped);
/* We hit EOF before we satisfied the skip request. */
- if (skipped < 0) // Map error code to 0 for error message below.
+ if (skipped < 0) /* Map error code to 0 for error message below. */
skipped = 0;
- archive_set_error(&a->archive,
+ archive_set_error(&filter->archive->archive,
ARCHIVE_ERRNO_MISC,
"Truncated input file (needed %jd bytes, only %jd available)",
(intmax_t)request, (intmax_t)skipped);
return (ARCHIVE_FATAL);
}
-int64_t
-__archive_read_skip_lenient(struct archive_read *a, int64_t request)
-{
- int64_t skipped = __archive_read_filter_skip(a->filter, request);
- if (skipped > 0)
- a->archive.file_position += skipped;
- return (skipped);
-}
-
-int64_t
-__archive_read_filter_skip(struct archive_read_filter *filter, int64_t request)
+/*
+ * Advance the file pointer by the amount requested.
+ * Returns the amount actually advanced, which may be less than the
+ * request if EOF is encountered first.
+ * Returns a negative value if there's an I/O error.
+ */
+static int64_t
+advance_file_pointer(struct archive_read_filter *filter, int64_t request)
{
int64_t bytes_skipped, total_bytes_skipped = 0;
+ ssize_t bytes_read;
size_t min;
if (filter->fatal)
return (-1);
- /*
- * If there is data in the buffers already, use that first.
- */
+
+ /* Use up the copy buffer first. */
if (filter->avail > 0) {
- min = minimum(request, (off_t)filter->avail);
- bytes_skipped = __archive_read_filter_consume(filter, min);
- request -= bytes_skipped;
- total_bytes_skipped += bytes_skipped;
+ min = minimum(request, (int64_t)filter->avail);
+ filter->next += min;
+ filter->avail -= min;
+ request -= min;
+ filter->position += min;
+ total_bytes_skipped += min;
}
+
+ /* Then use up the client buffer. */
if (filter->client_avail > 0) {
min = minimum(request, (int64_t)filter->client_avail);
- bytes_skipped = __archive_read_filter_consume(filter, min);
- request -= bytes_skipped;
- total_bytes_skipped += bytes_skipped;
+ filter->client_next += min;
+ filter->client_avail -= min;
+ request -= min;
+ filter->position += min;
+ total_bytes_skipped += min;
}
if (request == 0)
return (total_bytes_skipped);
- /*
- * If a client_skipper was provided, try that first.
- */
-#if ARCHIVE_API_VERSION < 2
- if ((filter->skip != NULL) && (request < SSIZE_MAX)) {
-#else
+
+ /* If there's an optimized skip function, use it. */
if (filter->skip != NULL) {
-#endif
bytes_skipped = (filter->skip)(filter, request);
if (bytes_skipped < 0) { /* error */
- filter->client_total = filter->client_avail = 0;
- filter->client_next = filter->client_buff = NULL;
filter->fatal = 1;
return (bytes_skipped);
}
+ filter->position += bytes_skipped;
total_bytes_skipped += bytes_skipped;
request -= bytes_skipped;
- filter->client_next = filter->client_buff;
- filter->client_avail = filter->client_total = 0;
+ if (request == 0)
+ return (total_bytes_skipped);
}
- /*
- * Note that client_skipper will usually not satisfy the
- * full request (due to low-level blocking concerns),
- * so even if client_skipper is provided, we may still
- * have to use ordinary reads to finish out the request.
- */
- while (request > 0) {
- ssize_t bytes_read;
- (void)__archive_read_filter_ahead(filter, 1, &bytes_read);
- if (bytes_read < 0)
+
+ /* Use ordinary reads as necessary to complete the request. */
+ for (;;) {
+ bytes_read = (filter->read)(filter, &filter->client_buff);
+ if (bytes_read < 0) {
+ filter->client_buff = NULL;
+ filter->fatal = 1;
return (bytes_read);
+ }
+
if (bytes_read == 0) {
+ filter->client_buff = NULL;
+ filter->end_of_file = 1;
return (total_bytes_skipped);
}
- min = (size_t)(minimum(bytes_read, request));
- bytes_read = __archive_read_filter_consume(filter, min);
+
+ if (bytes_read >= request) {
+ filter->client_next =
+ ((const char *)filter->client_buff) + request;
+ filter->client_avail = bytes_read - request;
+ filter->client_total = bytes_read;
+ total_bytes_skipped += request;
+ filter->position += request;
+ return (total_bytes_skipped);
+ }
+
+ filter->position += bytes_read;
total_bytes_skipped += bytes_read;
request -= bytes_read;
}
- return (total_bytes_skipped);
+}
+
+/**
+ * Returns ARCHIVE_FAILED if seeking isn't supported.
+ */
+int64_t
+__archive_read_seek(struct archive_read *a, int64_t offset, int whence)
+{
+ return __archive_read_filter_seek(a->filter, offset, whence);
+}
+
+int64_t
+__archive_read_filter_seek(struct archive_read_filter *filter, int64_t offset, int whence)
+{
+ int64_t r;
+
+ if (filter->closed || filter->fatal)
+ return (ARCHIVE_FATAL);
+ if (filter->seek == NULL)
+ return (ARCHIVE_FAILED);
+ r = filter->seek(filter, offset, whence);
+ if (r >= 0) {
+ /*
+ * Ouch. Clearing the buffer like this hurts, especially
+ * at bid time. A lot of our efficiency at bid time comes
+ * from having bidders reuse the data we've already read.
+ *
+ * TODO: If the seek request is in data we already
+ * have, then don't call the seek callback.
+ *
+ * TODO: Zip seeks to end-of-file at bid time. If
+ * other formats also start doing this, we may need to
+ * find a way for clients to fudge the seek offset to
+ * a block boundary.
+ *
+ * Hmmm... If whence was SEEK_END, we know the file
+ * size is (r - offset). Can we use that to simplify
+ * the TODO items above?
+ */
+ filter->avail = filter->client_avail = 0;
+ filter->next = filter->buffer;
+ filter->position = r;
+ filter->end_of_file = 0;
+ }
+ return r;
}
diff --git a/libarchive/archive_read_data.3 b/libarchive/archive_read_data.3
new file mode 100644
index 000000000000..78d04978205c
--- /dev/null
+++ b/libarchive/archive_read_data.3
@@ -0,0 +1,128 @@
+.\" Copyright (c) 2003-2011 Tim Kientzle
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd March 22, 2011
+.Dt ARCHIVE_READ_DATA 3
+.Os
+.Sh NAME
+.Nm archive_read_data
+.Nm archive_read_data_block ,
+.Nm archive_read_data_skip ,
+.Nm archive_read_data_into_fd
+.Nd functions for reading streaming archives
+.Sh SYNOPSIS
+.In archive.h
+.Ft ssize_t
+.Fn archive_read_data "struct archive *" "void *buff" "size_t len"
+.Ft int
+.Fo archive_read_data_block
+.Fa "struct archive *"
+.Fa "const void **buff"
+.Fa "size_t *len"
+.Fa "off_t *offset"
+.Fc
+.Ft int
+.Fn archive_read_data_skip "struct archive *"
+.Ft int
+.Fn archive_read_data_into_fd "struct archive *" "int fd"
+.\"
+.Sh DESCRIPTION
+.Bl -tag -compact -width indent
+.It Fn archive_read_data
+Read data associated with the header just read.
+Internally, this is a convenience function that calls
+.Fn archive_read_data_block
+and fills any gaps with nulls so that callers see a single
+continuous stream of data.
+.It Fn archive_read_data_block
+Return the next available block of data for this entry.
+Unlike
+.Fn archive_read_data ,
+the
+.Fn archive_read_data_block
+function avoids copying data and allows you to correctly handle
+sparse files, as supported by some archive formats.
+The library guarantees that offsets will increase and that blocks
+will not overlap.
+Note that the blocks returned from this function can be much larger
+than the block size read from disk, due to compression
+and internal buffer optimizations.
+.It Fn archive_read_data_skip
+A convenience function that repeatedly calls
+.Fn archive_read_data_block
+to skip all of the data for this archive entry.
+Note that this function is invoked automatically by
+.Fn archive_read_next_header2
+if the previous entry was not completely consumed.
+.It Fn archive_read_data_into_fd
+A convenience function that repeatedly calls
+.Fn archive_read_data_block
+to copy the entire entry to the provided file descriptor.
+.El
+.\"
+.Sh RETURN VALUES
+Most functions return zero on success, non-zero on error.
+The possible return codes include:
+.Cm ARCHIVE_OK
+(the operation succeeded),
+.Cm ARCHIVE_WARN
+(the operation succeeded but a non-critical error was encountered),
+.Cm ARCHIVE_EOF
+(end-of-archive was encountered),
+.Cm ARCHIVE_RETRY
+(the operation failed but can be retried),
+and
+.Cm ARCHIVE_FATAL
+(there was a fatal error; the archive should be closed immediately).
+.Pp
+.Fn archive_read_data
+returns a count of bytes actually read or zero at the end of the entry.
+On error, a value of
+.Cm ARCHIVE_FATAL ,
+.Cm ARCHIVE_WARN ,
+or
+.Cm ARCHIVE_RETRY
+is returned.
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.\"
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_read 3 ,
+.Xr archive_read_extract 3 ,
+.Xr archive_read_filter 3 ,
+.Xr archive_read_format 3 ,
+.Xr archive_read_header 3 ,
+.Xr archive_read_open 3 ,
+.Xr archive_read_set_options 3 ,
+.Xr archive_util 3 ,
+.Xr tar 5
diff --git a/libarchive/archive_read_data_into_fd.c b/libarchive/archive_read_data_into_fd.c
index 3aeef3bc2da8..14f941070e5c 100644
--- a/libarchive/archive_read_data_into_fd.c
+++ b/libarchive/archive_read_data_into_fd.c
@@ -45,31 +45,68 @@ __FBSDID("$FreeBSD: src/lib/libarchive/archive_read_data_into_fd.c,v 1.16 2008/0
/*
* This implementation minimizes copying of data and is sparse-file aware.
*/
+static int
+pad_to(struct archive *a, int fd, int can_lseek,
+ size_t nulls_size, const char *nulls,
+ int64_t target_offset, int64_t actual_offset)
+{
+ size_t to_write;
+ ssize_t bytes_written;
+
+ if (can_lseek) {
+ actual_offset = lseek(fd,
+ target_offset - actual_offset, SEEK_CUR);
+ if (actual_offset != target_offset) {
+ archive_set_error(a, errno, "Seek error");
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_OK);
+ }
+ while (target_offset > actual_offset) {
+ to_write = nulls_size;
+ if (target_offset < actual_offset + nulls_size)
+ to_write = (size_t)(target_offset - actual_offset);
+ bytes_written = write(fd, nulls, to_write);
+ if (bytes_written < 0) {
+ archive_set_error(a, errno, "Write error");
+ return (ARCHIVE_FATAL);
+ }
+ actual_offset += bytes_written;
+ }
+ return (ARCHIVE_OK);
+}
+
+
int
archive_read_data_into_fd(struct archive *a, int fd)
{
- int r;
+ struct stat st;
+ int r, r2;
const void *buff;
size_t size, bytes_to_write;
- ssize_t bytes_written, total_written;
- off_t offset;
- off_t output_offset;
+ ssize_t bytes_written;
+ int64_t target_offset;
+ int64_t actual_offset = 0;
+ int can_lseek;
+ char *nulls = NULL;
+ size_t nulls_size = 16384;
- __archive_check_magic(a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA, "archive_read_data_into_fd");
+ archive_check_magic(a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA,
+ "archive_read_data_into_fd");
- total_written = 0;
- output_offset = 0;
+ can_lseek = (fstat(fd, &st) == 0) && S_ISREG(st.st_mode);
+ if (!can_lseek)
+ nulls = calloc(1, nulls_size);
- while ((r = archive_read_data_block(a, &buff, &size, &offset)) ==
+ while ((r = archive_read_data_block(a, &buff, &size, &target_offset)) ==
ARCHIVE_OK) {
const char *p = buff;
- if (offset > output_offset) {
- output_offset = lseek(fd,
- offset - output_offset, SEEK_CUR);
- if (output_offset != offset) {
- archive_set_error(a, errno, "Seek error");
- return (ARCHIVE_FATAL);
- }
+ if (target_offset > actual_offset) {
+ r = pad_to(a, fd, can_lseek, nulls_size, nulls,
+ target_offset, actual_offset);
+ if (r != ARCHIVE_OK)
+ break;
+ actual_offset = target_offset;
}
while (size > 0) {
bytes_to_write = size;
@@ -78,15 +115,24 @@ archive_read_data_into_fd(struct archive *a, int fd)
bytes_written = write(fd, p, bytes_to_write);
if (bytes_written < 0) {
archive_set_error(a, errno, "Write error");
- return (ARCHIVE_FATAL);
+ r = ARCHIVE_FATAL;
+ goto cleanup;
}
- output_offset += bytes_written;
- total_written += bytes_written;
+ actual_offset += bytes_written;
p += bytes_written;
size -= bytes_written;
}
}
+ if (r == ARCHIVE_EOF && target_offset > actual_offset) {
+ r2 = pad_to(a, fd, can_lseek, nulls_size, nulls,
+ target_offset, actual_offset);
+ if (r2 != ARCHIVE_OK)
+ r = r2;
+ }
+
+cleanup:
+ free(nulls);
if (r != ARCHIVE_EOF)
return (r);
return (ARCHIVE_OK);
diff --git a/libarchive/archive_read_disk.3 b/libarchive/archive_read_disk.3
index 1d725a90e950..3c49bffc835d 100644
--- a/libarchive/archive_read_disk.3
+++ b/libarchive/archive_read_disk.3
@@ -39,6 +39,7 @@
.Nm archive_read_disk_set_gname_lookup ,
.Nm archive_read_disk_set_standard_lookup ,
.Nm archive_read_close ,
+.Nm archive_read_finish ,
.Nm archive_read_free
.Nd functions for reading objects from disk
.Sh SYNOPSIS
@@ -81,6 +82,8 @@
.Ft int
.Fn archive_read_close "struct archive *"
.Ft int
+.Fn archive_read_finish "struct archive *"
+.Ft int
.Fn archive_read_free "struct archive *"
.Sh DESCRIPTION
These functions provide an API for reading information about
@@ -177,7 +180,12 @@ This affects the file ownership fields and ACL values in the
.Tn struct archive_entry
object.
.It Fn archive_read_close
-This currently does nothing.
+Does nothing for
+.Tn archive_read_disk
+handles.
+.It Fn archive_read_finish
+This is a deprecated synonym for
+.Fn archive_read_free .
.It Fn archive_read_free
Invokes
.Fn archive_read_close
@@ -207,7 +215,7 @@ file_to_archive(struct archive *a, const char *name)
fd = open(name, O_RDONLY);
if (fd < 0)
return;
- archive_entry_copy_sourcepath(entry, name);
+ archive_entry_copy_pathname(entry, name);
archive_read_disk_entry_from_file(ard, entry, fd, NULL);
archive_write_header(a, entry);
while ((bytes_read = read(fd, buff, sizeof(buff))) > 0)
@@ -229,15 +237,6 @@ for operations that might succeed if retried,
for unusual conditions that do not prevent further operations, and
.Cm ARCHIVE_FATAL
for serious errors that make remaining operations impossible.
-The
-.Xr archive_errno 3
-and
-.Xr archive_error_string 3
-functions can be used to retrieve an appropriate error code and a
-textual error message.
-(See
-.Xr archive_util 3
-for details.)
.Pp
.Fn archive_read_disk_new
returns a pointer to a newly-allocated
@@ -253,9 +252,17 @@ pointers to the textual name or NULL if the lookup failed for any reason.
The returned pointer points to internal storage that
may be reused on the next call to either of these functions;
callers should copy the string if they need to continue accessing it.
-.Pp
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.\"
.Sh SEE ALSO
.Xr archive_read 3 ,
+.Xr archive_util 3 ,
.Xr archive_write 3 ,
.Xr archive_write_disk 3 ,
.Xr tar 1 ,
diff --git a/libarchive/archive_read_disk.c b/libarchive/archive_read_disk.c
deleted file mode 100644
index dc43e179c7c5..000000000000
--- a/libarchive/archive_read_disk.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/*-
- * Copyright (c) 2003-2009 Tim Kientzle
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer
- * in this position and unchanged.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_disk.c 189429 2009-03-06 04:35:31Z kientzle $");
-
-#include "archive.h"
-#include "archive_string.h"
-#include "archive_entry.h"
-#include "archive_private.h"
-#include "archive_read_disk_private.h"
-
-static int _archive_read_free(struct archive *);
-static int _archive_read_close(struct archive *);
-static const char *trivial_lookup_gname(void *, gid_t gid);
-static const char *trivial_lookup_uname(void *, uid_t uid);
-
-static struct archive_vtable *
-archive_read_disk_vtable(void)
-{
- static struct archive_vtable av;
- static int inited = 0;
-
- if (!inited) {
- av.archive_free = _archive_read_free;
- av.archive_close = _archive_read_close;
- }
- return (&av);
-}
-
-const char *
-archive_read_disk_gname(struct archive *_a, gid_t gid)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- if (a->lookup_gname != NULL)
- return ((*a->lookup_gname)(a->lookup_gname_data, gid));
- return (NULL);
-}
-
-const char *
-archive_read_disk_uname(struct archive *_a, uid_t uid)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- if (a->lookup_uname != NULL)
- return ((*a->lookup_uname)(a->lookup_uname_data, uid));
- return (NULL);
-}
-
-int
-archive_read_disk_set_gname_lookup(struct archive *_a,
- void *private_data,
- const char * (*lookup_gname)(void *private, gid_t gid),
- void (*cleanup_gname)(void *private))
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_ANY, "archive_read_disk_set_gname_lookup");
-
- if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL)
- (a->cleanup_gname)(a->lookup_gname_data);
-
- a->lookup_gname = lookup_gname;
- a->cleanup_gname = cleanup_gname;
- a->lookup_gname_data = private_data;
- return (ARCHIVE_OK);
-}
-
-int
-archive_read_disk_set_uname_lookup(struct archive *_a,
- void *private_data,
- const char * (*lookup_uname)(void *private, uid_t uid),
- void (*cleanup_uname)(void *private))
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC,
- ARCHIVE_STATE_ANY, "archive_read_disk_set_uname_lookup");
-
- if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL)
- (a->cleanup_uname)(a->lookup_uname_data);
-
- a->lookup_uname = lookup_uname;
- a->cleanup_uname = cleanup_uname;
- a->lookup_uname_data = private_data;
- return (ARCHIVE_OK);
-}
-
-/*
- * Create a new archive_read_disk object and initialize it with global state.
- */
-struct archive *
-archive_read_disk_new(void)
-{
- struct archive_read_disk *a;
-
- a = (struct archive_read_disk *)malloc(sizeof(*a));
- if (a == NULL)
- return (NULL);
- memset(a, 0, sizeof(*a));
- a->archive.magic = ARCHIVE_READ_DISK_MAGIC;
- /* We're ready to write a header immediately. */
- a->archive.state = ARCHIVE_STATE_HEADER;
- a->archive.vtable = archive_read_disk_vtable();
- a->lookup_uname = trivial_lookup_uname;
- a->lookup_gname = trivial_lookup_gname;
- return (&a->archive);
-}
-
-static int
-_archive_read_free(struct archive *_a)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
-
- if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL)
- (a->cleanup_gname)(a->lookup_gname_data);
- if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL)
- (a->cleanup_uname)(a->lookup_uname_data);
- archive_string_free(&a->archive.error_string);
- free(a);
- return (ARCHIVE_OK);
-}
-
-static int
-_archive_read_close(struct archive *_a)
-{
- (void)_a; /* UNUSED */
- return (ARCHIVE_OK);
-}
-
-int
-archive_read_disk_set_symlink_logical(struct archive *_a)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- a->symlink_mode = 'L';
- a->follow_symlinks = 1;
- return (ARCHIVE_OK);
-}
-
-int
-archive_read_disk_set_symlink_physical(struct archive *_a)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- a->symlink_mode = 'P';
- a->follow_symlinks = 0;
- return (ARCHIVE_OK);
-}
-
-int
-archive_read_disk_set_symlink_hybrid(struct archive *_a)
-{
- struct archive_read_disk *a = (struct archive_read_disk *)_a;
- a->symlink_mode = 'H';
- a->follow_symlinks = 1; /* Follow symlinks initially. */
- return (ARCHIVE_OK);
-}
-
-/*
- * Trivial implementations of gname/uname lookup functions.
- * These are normally overridden by the client, but these stub
- * versions ensure that we always have something that works.
- */
-static const char *
-trivial_lookup_gname(void *private_data, gid_t gid)
-{
- (void)private_data; /* UNUSED */
- (void)gid; /* UNUSED */
- return (NULL);
-}
-
-static const char *
-trivial_lookup_uname(void *private_data, uid_t uid)
-{
- (void)private_data; /* UNUSED */
- (void)uid; /* UNUSED */
- return (NULL);
-}
diff --git a/libarchive/archive_read_disk_entry_from_file.c b/libarchive/archive_read_disk_entry_from_file.c
index 7473c506e832..8ce88b380fca 100644
--- a/libarchive/archive_read_disk_entry_from_file.c
+++ b/libarchive/archive_read_disk_entry_from_file.c
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2003-2009 Tim Kientzle
+ * Copyright (c) 2010 Michihiro NAKAJIMA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,6 +27,9 @@
#include "archive_platform.h"
__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_disk_entry_from_file.c 201084 2009-12-28 02:14:09Z kientzle $");
+/* This is the tree-walking code for POSIX systems. */
+#if !defined(_WIN32) || defined(__CYGWIN__)
+
#ifdef HAVE_SYS_TYPES_H
/* Mac OSX requires sys/types.h before sys/acl.h. */
#include <sys/types.h>
@@ -36,6 +40,9 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_disk_entry_from_file.c 2010
#ifdef HAVE_SYS_EXTATTR_H
#include <sys/extattr.h>
#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
@@ -45,20 +52,48 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_disk_entry_from_file.c 2010
#ifdef HAVE_SYS_XATTR_H
#include <sys/xattr.h>
#endif
+#ifdef HAVE_SYS_EA_H
+#include <sys/ea.h>
+#endif
#ifdef HAVE_ACL_LIBACL_H
#include <acl/libacl.h>
#endif
#ifdef HAVE_ATTR_XATTR_H
#include <attr/xattr.h>
#endif
+#ifdef HAVE_COPYFILE_H
+#include <copyfile.h>
+#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
-#ifdef HAVE_WINDOWS_H
-#include <windows.h>
+#ifdef HAVE_LINUX_FIEMAP_H
+#include <linux/fiemap.h>
+#endif
+#ifdef HAVE_LINUX_FS_H
+#include <linux/fs.h>
+#endif
+/*
+ * Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h.
+ * As the include guards don't agree, the order of include is important.
+ */
+#ifdef HAVE_LINUX_EXT2_FS_H
+#include <linux/ext2_fs.h> /* for Linux file flags */
+#endif
+#if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__)
+#include <ext2fs/ext2_fs.h> /* Linux file flags, broken on Cygwin */
+#endif
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
#endif
#include "archive.h"
@@ -78,13 +113,18 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_disk_entry_from_file.c 2010
static int setup_acls_posix1e(struct archive_read_disk *,
struct archive_entry *, int fd);
+static int setup_mac_metadata(struct archive_read_disk *,
+ struct archive_entry *, int fd);
static int setup_xattrs(struct archive_read_disk *,
struct archive_entry *, int fd);
+static int setup_sparse(struct archive_read_disk *,
+ struct archive_entry *, int fd);
int
archive_read_disk_entry_from_file(struct archive *_a,
struct archive_entry *entry,
- int fd, const struct stat *st)
+ int fd,
+ const struct stat *st)
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
const char *path, *name;
@@ -97,54 +137,35 @@ archive_read_disk_entry_from_file(struct archive *_a,
if (path == NULL)
path = archive_entry_pathname(entry);
-#ifdef EXT2_IOC_GETFLAGS
- /* Linux requires an extra ioctl to pull the flags. Although
- * this is an extra step, it has a nice side-effect: We get an
- * open file descriptor which we can use in the subsequent lookups. */
- if ((S_ISREG(st->st_mode) || S_ISDIR(st->st_mode))) {
- if (fd < 0)
- fd = open(pathname, O_RDONLY | O_NONBLOCK | O_BINARY);
- if (fd >= 0) {
- unsigned long stflags;
- int r = ioctl(fd, EXT2_IOC_GETFLAGS, &stflags);
- if (r == 0 && stflags != 0)
- archive_entry_set_fflags(entry, stflags, 0);
- }
- }
-#endif
-
- if (st == NULL) {
- /* TODO: On Windows, use GetFileInfoByHandle() here.
- * Using Windows stat() call is badly broken, but
- * even the stat() wrapper has problems because
- * 'struct stat' is broken on Windows.
- */
+ if (a->tree == NULL) {
+ if (st == NULL) {
#if HAVE_FSTAT
- if (fd >= 0) {
- if (fstat(fd, &s) != 0) {
- archive_set_error(&a->archive, errno,
- "Can't fstat");
- return (ARCHIVE_FAILED);
- }
- } else
+ if (fd >= 0) {
+ if (fstat(fd, &s) != 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't fstat");
+ return (ARCHIVE_FAILED);
+ }
+ } else
#endif
#if HAVE_LSTAT
- if (!a->follow_symlinks) {
- if (lstat(path, &s) != 0) {
+ if (!a->follow_symlinks) {
+ if (lstat(path, &s) != 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't lstat %s", path);
+ return (ARCHIVE_FAILED);
+ }
+ } else
+#endif
+ if (stat(path, &s) != 0) {
archive_set_error(&a->archive, errno,
- "Can't lstat %s", path);
+ "Can't stat %s", path);
return (ARCHIVE_FAILED);
}
- } else
-#endif
- if (stat(path, &s) != 0) {
- archive_set_error(&a->archive, errno,
- "Can't lstat %s", path);
- return (ARCHIVE_FAILED);
+ st = &s;
}
- st = &s;
+ archive_entry_copy_stat(entry, st);
}
- archive_entry_copy_stat(entry, st);
/* Lookup uname/gname */
name = archive_read_disk_uname(_a, archive_entry_uid(entry));
@@ -161,30 +182,185 @@ archive_read_disk_entry_from_file(struct archive *_a,
archive_entry_set_fflags(entry, st->st_flags, 0);
#endif
-#ifdef HAVE_READLINK
+#if defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)
+ /* Linux requires an extra ioctl to pull the flags. Although
+ * this is an extra step, it has a nice side-effect: We get an
+ * open file descriptor which we can use in the subsequent lookups. */
+ if ((S_ISREG(st->st_mode) || S_ISDIR(st->st_mode))) {
+ if (fd < 0)
+ fd = open(path, O_RDONLY | O_NONBLOCK);
+ if (fd >= 0) {
+ unsigned long stflags;
+ int r = ioctl(fd, EXT2_IOC_GETFLAGS, &stflags);
+ if (r == 0 && stflags != 0)
+ archive_entry_set_fflags(entry, stflags, 0);
+ }
+ }
+#endif
+
+#if defined(HAVE_READLINK) || defined(HAVE_READLINKAT)
if (S_ISLNK(st->st_mode)) {
- char linkbuffer[PATH_MAX + 1];
- int lnklen = readlink(path, linkbuffer, PATH_MAX);
+ size_t linkbuffer_len = st->st_size + 1;
+ char *linkbuffer;
+ int lnklen;
+
+ linkbuffer = malloc(linkbuffer_len);
+ if (linkbuffer == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Couldn't read link data");
+ return (ARCHIVE_FAILED);
+ }
+#ifdef HAVE_READLINKAT
+ if (a->entry_wd_fd >= 0)
+ lnklen = readlinkat(a->entry_wd_fd, path,
+ linkbuffer, linkbuffer_len);
+ else
+#endif /* HAVE_READLINKAT */
+ lnklen = readlink(path, linkbuffer, linkbuffer_len);
if (lnklen < 0) {
archive_set_error(&a->archive, errno,
"Couldn't read link data");
+ free(linkbuffer);
return (ARCHIVE_FAILED);
}
linkbuffer[lnklen] = 0;
archive_entry_set_symlink(entry, linkbuffer);
+ free(linkbuffer);
}
-#endif
+#endif /* HAVE_READLINK || HAVE_READLINKAT */
r = setup_acls_posix1e(a, entry, fd);
r1 = setup_xattrs(a, entry, fd);
if (r1 < r)
r = r1;
+ r1 = setup_mac_metadata(a, entry, fd);
+ if (r1 < r)
+ r = r1;
+ r1 = setup_sparse(a, entry, fd);
+ if (r1 < r)
+ r = r1;
+
/* If we opened the file earlier in this function, close it. */
if (initial_fd != fd)
close(fd);
return (r);
}
+#if defined(__APPLE__) && defined(HAVE_COPYFILE_H)
+/*
+ * The Mac OS "copyfile()" API copies the extended metadata for a
+ * file into a separate file in AppleDouble format (see RFC 1740).
+ *
+ * Mac OS tar and cpio implementations store this extended
+ * metadata as a separate entry just before the regular entry
+ * with a "._" prefix added to the filename.
+ *
+ * Note that this is currently done unconditionally; the tar program has
+ * an option to discard this information before the archive is written.
+ *
+ * TODO: If there's a failure, report it and return ARCHIVE_WARN.
+ */
+static int
+setup_mac_metadata(struct archive_read_disk *a,
+ struct archive_entry *entry, int fd)
+{
+ int tempfd = -1;
+ int copyfile_flags = COPYFILE_NOFOLLOW | COPYFILE_ACL | COPYFILE_XATTR;
+ struct stat copyfile_stat;
+ int ret = ARCHIVE_OK;
+ void *buff;
+ int have_attrs;
+ const char *name, *tempdir, *tempfile = NULL;
+
+ name = archive_entry_sourcepath(entry);
+ if (name == NULL)
+ name = archive_entry_pathname(entry);
+ if (name == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Can't open file to read extended attributes: No name");
+ return (ARCHIVE_WARN);
+ }
+
+ /* Short-circuit if there's nothing to do. */
+ have_attrs = copyfile(name, NULL, 0, copyfile_flags | COPYFILE_CHECK);
+ if (have_attrs == -1) {
+ archive_set_error(&a->archive, errno,
+ "Could not check extended attributes");
+ return (ARCHIVE_WARN);
+ }
+ if (have_attrs == 0)
+ return (ARCHIVE_OK);
+
+ tempdir = NULL;
+ if (issetugid() == 0)
+ tempdir = getenv("TMPDIR");
+ if (tempdir == NULL)
+ tempdir = _PATH_TMP;
+ tempfile = tempnam(tempdir, "tar.md.");
+
+ /* XXX I wish copyfile() could pack directly to a memory
+ * buffer; that would avoid the temp file here. For that
+ * matter, it would be nice if fcopyfile() actually worked,
+ * that would reduce the many open/close races here. */
+ if (copyfile(name, tempfile, 0, copyfile_flags | COPYFILE_PACK)) {
+ archive_set_error(&a->archive, errno,
+ "Could not pack extended attributes");
+ ret = ARCHIVE_WARN;
+ goto cleanup;
+ }
+ tempfd = open(tempfile, O_RDONLY);
+ if (tempfd < 0) {
+ archive_set_error(&a->archive, errno,
+ "Could not open extended attribute file");
+ ret = ARCHIVE_WARN;
+ goto cleanup;
+ }
+ if (fstat(tempfd, &copyfile_stat)) {
+ archive_set_error(&a->archive, errno,
+ "Could not check size of extended attributes");
+ ret = ARCHIVE_WARN;
+ goto cleanup;
+ }
+ buff = malloc(copyfile_stat.st_size);
+ if (buff == NULL) {
+ archive_set_error(&a->archive, errno,
+ "Could not allocate memory for extended attributes");
+ ret = ARCHIVE_WARN;
+ goto cleanup;
+ }
+ if (copyfile_stat.st_size != read(tempfd, buff, copyfile_stat.st_size)) {
+ archive_set_error(&a->archive, errno,
+ "Could not read extended attributes into memory");
+ ret = ARCHIVE_WARN;
+ goto cleanup;
+ }
+ archive_entry_copy_mac_metadata(entry, buff, copyfile_stat.st_size);
+
+cleanup:
+ if (tempfd >= 0)
+ close(tempfd);
+ if (tempfile != NULL)
+ unlink(tempfile);
+ return (ret);
+}
+
+#else
+
+/*
+ * Stub implementation for non-Mac systems.
+ */
+static int
+setup_mac_metadata(struct archive_read_disk *a,
+ struct archive_entry *entry, int fd)
+{
+ (void)a; /* UNUSED */
+ (void)entry; /* UNUSED */
+ (void)fd; /* UNUSED */
+ return (ARCHIVE_OK);
+}
+#endif
+
+
#ifdef HAVE_POSIX_ACL
static void setup_acl_posix1e(struct archive_read_disk *a,
struct archive_entry *entry, acl_t acl, int archive_entry_acl_type);
@@ -307,10 +483,12 @@ setup_acls_posix1e(struct archive_read_disk *a,
}
#endif
-#if HAVE_LISTXATTR && HAVE_LLISTXATTR && HAVE_GETXATTR && HAVE_LGETXATTR
+#if (HAVE_FGETXATTR && HAVE_FLISTXATTR && HAVE_LISTXATTR && \
+ HAVE_LLISTXATTR && HAVE_GETXATTR && HAVE_LGETXATTR) || \
+ (HAVE_FGETEA && HAVE_FLISTEA && HAVE_LISTEA)
/*
- * Linux extended attribute support.
+ * Linux and AIX extended attribute support.
*
* TODO: By using a stack-allocated buffer for the first
* call to getxattr(), we might be able to avoid the second
@@ -329,16 +507,25 @@ setup_xattr(struct archive_read_disk *a,
void *value = NULL;
const char *accpath;
- (void)fd; /* UNUSED */
-
accpath = archive_entry_sourcepath(entry);
if (accpath == NULL)
accpath = archive_entry_pathname(entry);
- if (!a->follow_symlinks)
+#if HAVE_FGETXATTR
+ if (fd >= 0)
+ size = fgetxattr(fd, name, NULL, 0);
+ else if (!a->follow_symlinks)
size = lgetxattr(accpath, name, NULL, 0);
else
size = getxattr(accpath, name, NULL, 0);
+#elif HAVE_FGETEA
+ if (fd >= 0)
+ size = fgetea(fd, name, NULL, 0);
+ else if (!a->follow_symlinks)
+ size = lgetea(accpath, name, NULL, 0);
+ else
+ size = getea(accpath, name, NULL, 0);
+#endif
if (size == -1) {
archive_set_error(&a->archive, errno,
@@ -351,10 +538,21 @@ setup_xattr(struct archive_read_disk *a,
return (ARCHIVE_FATAL);
}
- if (!a->follow_symlinks)
+#if HAVE_FGETXATTR
+ if (fd >= 0)
+ size = fgetxattr(fd, name, value, size);
+ else if (!a->follow_symlinks)
size = lgetxattr(accpath, name, value, size);
else
size = getxattr(accpath, name, value, size);
+#elif HAVE_FGETEA
+ if (fd >= 0)
+ size = fgetea(fd, name, value, size);
+ else if (!a->follow_symlinks)
+ size = lgetea(accpath, name, value, size);
+ else
+ size = getea(accpath, name, value, size);
+#endif
if (size == -1) {
archive_set_error(&a->archive, errno,
@@ -376,18 +574,28 @@ setup_xattrs(struct archive_read_disk *a,
const char *path;
ssize_t list_size;
-
path = archive_entry_sourcepath(entry);
if (path == NULL)
path = archive_entry_pathname(entry);
- if (!a->follow_symlinks)
+#if HAVE_FLISTXATTR
+ if (fd >= 0)
+ list_size = flistxattr(fd, NULL, 0);
+ else if (!a->follow_symlinks)
list_size = llistxattr(path, NULL, 0);
else
list_size = listxattr(path, NULL, 0);
+#elif HAVE_FLISTEA
+ if (fd >= 0)
+ list_size = flistea(fd, NULL, 0);
+ else if (!a->follow_symlinks)
+ list_size = llistea(path, NULL, 0);
+ else
+ list_size = listea(path, NULL, 0);
+#endif
if (list_size == -1) {
- if (errno == ENOTSUP)
+ if (errno == ENOTSUP || errno == ENOSYS)
return (ARCHIVE_OK);
archive_set_error(&a->archive, errno,
"Couldn't list extended attributes");
@@ -402,10 +610,21 @@ setup_xattrs(struct archive_read_disk *a,
return (ARCHIVE_FATAL);
}
- if (!a->follow_symlinks)
+#if HAVE_FLISTXATTR
+ if (fd >= 0)
+ list_size = flistxattr(fd, list, list_size);
+ else if (!a->follow_symlinks)
list_size = llistxattr(path, list, list_size);
else
list_size = listxattr(path, list, list_size);
+#elif HAVE_FLISTEA
+ if (fd >= 0)
+ list_size = flistea(fd, list, list_size);
+ else if (!a->follow_symlinks)
+ list_size = llistea(path, list, list_size);
+ else
+ list_size = listea(path, list, list_size);
+#endif
if (list_size == -1) {
archive_set_error(&a->archive, errno,
@@ -449,13 +668,13 @@ setup_xattr(struct archive_read_disk *a, struct archive_entry *entry,
void *value = NULL;
const char *accpath;
- (void)fd; /* UNUSED */
-
accpath = archive_entry_sourcepath(entry);
if (accpath == NULL)
accpath = archive_entry_pathname(entry);
- if (!a->follow_symlinks)
+ if (fd >= 0)
+ size = extattr_get_fd(fd, namespace, name, NULL, 0);
+ else if (!a->follow_symlinks)
size = extattr_get_link(accpath, namespace, name, NULL, 0);
else
size = extattr_get_file(accpath, namespace, name, NULL, 0);
@@ -471,7 +690,9 @@ setup_xattr(struct archive_read_disk *a, struct archive_entry *entry,
return (ARCHIVE_FATAL);
}
- if (!a->follow_symlinks)
+ if (fd >= 0)
+ size = extattr_get_fd(fd, namespace, name, value, size);
+ else if (!a->follow_symlinks)
size = extattr_get_link(accpath, namespace, name, value, size);
else
size = extattr_get_file(accpath, namespace, name, value, size);
@@ -502,7 +723,9 @@ setup_xattrs(struct archive_read_disk *a,
if (path == NULL)
path = archive_entry_pathname(entry);
- if (!a->follow_symlinks)
+ if (fd >= 0)
+ list_size = extattr_list_fd(fd, namespace, NULL, 0);
+ else if (!a->follow_symlinks)
list_size = extattr_list_link(path, namespace, NULL, 0);
else
list_size = extattr_list_file(path, namespace, NULL, 0);
@@ -523,7 +746,9 @@ setup_xattrs(struct archive_read_disk *a,
return (ARCHIVE_FATAL);
}
- if (!a->follow_symlinks)
+ if (fd >= 0)
+ list_size = extattr_list_fd(fd, namespace, list, list_size);
+ else if (!a->follow_symlinks)
list_size = extattr_list_link(path, namespace, list, list_size);
else
list_size = extattr_list_file(path, namespace, list, list_size);
@@ -568,3 +793,213 @@ setup_xattrs(struct archive_read_disk *a,
}
#endif
+
+#if defined(HAVE_LINUX_FIEMAP_H)
+
+/*
+ * Linux sparse interface.
+ *
+ * The FIEMAP ioctl returns an "extent" for each physical allocation
+ * on disk. We need to process those to generate a more compact list
+ * of logical file blocks. We also need to be very careful to use
+ * FIEMAP_FLAG_SYNC here, since there are reports that Linux sometimes
+ * does not report allocations for newly-written data that hasn't
+ * been synced to disk.
+ *
+ * It's important to return a minimal sparse file list because we want
+ * to not trigger sparse file extensions if we don't have to, since
+ * not all readers support them.
+ */
+
+static int
+setup_sparse(struct archive_read_disk *a,
+ struct archive_entry *entry, int fd)
+{
+ char buff[4096];
+ struct fiemap *fm;
+ struct fiemap_extent *fe;
+ int64_t size;
+ int count, do_fiemap;
+ int initial_fd = fd;
+ int exit_sts = ARCHIVE_OK;
+
+ if (archive_entry_filetype(entry) != AE_IFREG
+ || archive_entry_size(entry) <= 0
+ || archive_entry_hardlink(entry) != NULL)
+ return (ARCHIVE_OK);
+
+ if (fd < 0) {
+ const char *path;
+
+ path = archive_entry_sourcepath(entry);
+ if (path == NULL)
+ path = archive_entry_pathname(entry);
+ fd = open(path, O_RDONLY | O_NONBLOCK);
+ if (fd < 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't open `%s'", path);
+ return (ARCHIVE_FAILED);
+ }
+ }
+
+ count = (sizeof(buff) - sizeof(*fm))/sizeof(*fe);
+ fm = (struct fiemap *)buff;
+ fm->fm_start = 0;
+ fm->fm_length = ~0ULL;;
+ fm->fm_flags = FIEMAP_FLAG_SYNC;
+ fm->fm_extent_count = count;
+ do_fiemap = 1;
+ size = archive_entry_size(entry);
+ for (;;) {
+ int i, r;
+
+ r = ioctl(fd, FS_IOC_FIEMAP, fm);
+ if (r < 0) {
+ /* When errno is ENOTTY, it is better we should
+ * return ARCHIVE_OK because an earlier version
+ *(<2.6.28) cannot perfom FS_IOC_FIEMAP.
+ * We should also check if errno is EOPNOTSUPP,
+ * it means "Operation not supported". */
+ if (errno != ENOTTY && errno != EOPNOTSUPP) {
+ archive_set_error(&a->archive, errno,
+ "FIEMAP failed");
+ exit_sts = ARCHIVE_FAILED;
+ }
+ goto exit_setup_sparse;
+ }
+ if (fm->fm_mapped_extents == 0)
+ break;
+ fe = fm->fm_extents;
+ for (i = 0; i < fm->fm_mapped_extents; i++, fe++) {
+ if (!(fe->fe_flags & FIEMAP_EXTENT_UNWRITTEN)) {
+ /* The fe_length of the last block does not
+ * adjust itself to its size files. */
+ int64_t length = fe->fe_length;
+ if (fe->fe_logical + length > size)
+ length -= fe->fe_logical + length - size;
+ if (fe->fe_logical == 0 && length == size) {
+ /* This is not sparse. */
+ do_fiemap = 0;
+ break;
+ }
+ if (length > 0)
+ archive_entry_sparse_add_entry(entry,
+ fe->fe_logical, length);
+ }
+ if (fe->fe_flags & FIEMAP_EXTENT_LAST)
+ do_fiemap = 0;
+ }
+ if (do_fiemap) {
+ fe = fm->fm_extents + fm->fm_mapped_extents -1;
+ fm->fm_start = fe->fe_logical + fe->fe_length;
+ } else
+ break;
+ }
+exit_setup_sparse:
+ if (initial_fd != fd)
+ close(fd);
+ return (exit_sts);
+}
+
+#elif defined(SEEK_HOLE) && defined(SEEK_DATA) && defined(_PC_MIN_HOLE_SIZE)
+
+/*
+ * FreeBSD and Solaris sparse interface.
+ */
+
+static int
+setup_sparse(struct archive_read_disk *a,
+ struct archive_entry *entry, int fd)
+{
+ int64_t size;
+ int initial_fd = fd;
+ off_t initial_off; /* FreeBSD/Solaris only, so off_t okay here */
+ off_t off_s, off_e; /* FreeBSD/Solaris only, so off_t okay here */
+ int exit_sts = ARCHIVE_OK;
+
+ if (archive_entry_filetype(entry) != AE_IFREG
+ || archive_entry_size(entry) <= 0
+ || archive_entry_hardlink(entry) != NULL)
+ return (ARCHIVE_OK);
+
+ /* Does filesystem support the reporting of hole ? */
+ if (fd >= 0) {
+ if (fpathconf(fd, _PC_MIN_HOLE_SIZE) <= 0)
+ return (ARCHIVE_OK);
+ initial_off = lseek(fd, 0, SEEK_CUR);
+ if (initial_off != 0)
+ lseek(fd, 0, SEEK_SET);
+ } else {
+ const char *path;
+
+ path = archive_entry_sourcepath(entry);
+ if (path == NULL)
+ path = archive_entry_pathname(entry);
+ if (pathconf(path, _PC_MIN_HOLE_SIZE) <= 0)
+ return (ARCHIVE_OK);
+ fd = open(path, O_RDONLY | O_NONBLOCK);
+ if (fd < 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't open `%s'", path);
+ return (ARCHIVE_FAILED);
+ }
+ initial_off = 0;
+ }
+
+ off_s = 0;
+ size = archive_entry_size(entry);
+ while (off_s < size) {
+ off_s = lseek(fd, off_s, SEEK_DATA);
+ if (off_s == (off_t)-1) {
+ if (errno == ENXIO)
+ break;/* no more hole */
+ archive_set_error(&a->archive, errno,
+ "lseek(SEEK_HOLE) failed");
+ exit_sts = ARCHIVE_FAILED;
+ goto exit_setup_sparse;
+ }
+ off_e = lseek(fd, off_s, SEEK_HOLE);
+ if (off_s == (off_t)-1) {
+ if (errno == ENXIO) {
+ off_e = lseek(fd, 0, SEEK_END);
+ if (off_e != (off_t)-1)
+ break;/* no more data */
+ }
+ archive_set_error(&a->archive, errno,
+ "lseek(SEEK_DATA) failed");
+ exit_sts = ARCHIVE_FAILED;
+ goto exit_setup_sparse;
+ }
+ if (off_s == 0 && off_e == size)
+ break;/* This is not spase. */
+ archive_entry_sparse_add_entry(entry, off_s,
+ off_e - off_s);
+ off_s = off_e;
+ }
+exit_setup_sparse:
+ if (initial_fd != fd)
+ close(fd);
+ else
+ lseek(fd, initial_off, SEEK_SET);
+ return (exit_sts);
+}
+
+#else
+
+/*
+ * Generic (stub) sparse support.
+ */
+static int
+setup_sparse(struct archive_read_disk *a,
+ struct archive_entry *entry, int fd)
+{
+ (void)a; /* UNUSED */
+ (void)entry; /* UNUSED */
+ (void)fd; /* UNUSED */
+ return (ARCHIVE_OK);
+}
+
+#endif
+
+#endif /* !defined(_WIN32) || defined(__CYGWIN__) */
+
diff --git a/libarchive/archive_read_disk_posix.c b/libarchive/archive_read_disk_posix.c
new file mode 100644
index 000000000000..b81ab30fe719
--- /dev/null
+++ b/libarchive/archive_read_disk_posix.c
@@ -0,0 +1,2311 @@
+/*-
+ * Copyright (c) 2003-2009 Tim Kientzle
+ * Copyright (c) 2010,2011 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* This is the tree-walking code for POSIX systems. */
+#if !defined(_WIN32) || defined(__CYGWIN__)
+
+#include "archive_platform.h"
+__FBSDID("$FreeBSD$");
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_MOUNT_H
+#include <sys/mount.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_STATFS_H
+#include <sys/statfs.h>
+#endif
+#ifdef HAVE_SYS_STATVFS_H
+#include <sys/statvfs.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_LINUX_MAGIC_H
+#include <linux/magic.h>
+#endif
+#ifdef HAVE_DIRECT_H
+#include <direct.h>
+#endif
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "archive.h"
+#include "archive_string.h"
+#include "archive_entry.h"
+#include "archive_private.h"
+#include "archive_read_disk_private.h"
+
+#ifndef HAVE_FCHDIR
+#error fchdir function required.
+#endif
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+/*-
+ * This is a new directory-walking system that addresses a number
+ * of problems I've had with fts(3). In particular, it has no
+ * pathname-length limits (other than the size of 'int'), handles
+ * deep logical traversals, uses considerably less memory, and has
+ * an opaque interface (easier to modify in the future).
+ *
+ * Internally, it keeps a single list of "tree_entry" items that
+ * represent filesystem objects that require further attention.
+ * Non-directories are not kept in memory: they are pulled from
+ * readdir(), returned to the client, then freed as soon as possible.
+ * Any directory entry to be traversed gets pushed onto the stack.
+ *
+ * There is surprisingly little information that needs to be kept for
+ * each item on the stack. Just the name, depth (represented here as the
+ * string length of the parent directory's pathname), and some markers
+ * indicating how to get back to the parent (via chdir("..") for a
+ * regular dir or via fchdir(2) for a symlink).
+ */
+/*
+ * TODO:
+ * 1) Loop checking.
+ * 3) Arbitrary logical traversals by closing/reopening intermediate fds.
+ */
+
+struct restore_time {
+ const char *name;
+ time_t mtime;
+ long mtime_nsec;
+ time_t atime;
+ long atime_nsec;
+ mode_t filetype;
+ int noatime;
+};
+
+struct tree_entry {
+ int depth;
+ struct tree_entry *next;
+ struct tree_entry *parent;
+ struct archive_string name;
+ size_t dirname_length;
+ int64_t dev;
+ int64_t ino;
+ int flags;
+ int filesystem_id;
+ /* How to return back to the parent of a symlink. */
+ int symlink_parent_fd;
+ /* How to restore time of a directory. */
+ struct restore_time restore_time;
+};
+
+struct filesystem {
+ int64_t dev;
+ int synthetic;
+ int remote;
+ int noatime;
+#if defined(HAVE_READDIR_R)
+ size_t name_max;
+#endif
+ long incr_xfer_size;
+ long max_xfer_size;
+ long min_xfer_size;
+ long xfer_align;
+
+ /*
+ * Buffer used for reading file contents.
+ */
+ /* Exactly allocated memory pointer. */
+ unsigned char *allocation_ptr;
+ /* Pointer adjusted to the filesystem alignment . */
+ unsigned char *buff;
+ size_t buff_size;
+};
+
+/* Definitions for tree_entry.flags bitmap. */
+#define isDir 1 /* This entry is a regular directory. */
+#define isDirLink 2 /* This entry is a symbolic link to a directory. */
+#define needsFirstVisit 4 /* This is an initial entry. */
+#define needsDescent 8 /* This entry needs to be previsited. */
+#define needsOpen 16 /* This is a directory that needs to be opened. */
+#define needsAscent 32 /* This entry needs to be postvisited. */
+
+/*
+ * Local data for this package.
+ */
+struct tree {
+ struct tree_entry *stack;
+ struct tree_entry *current;
+ DIR *d;
+#define INVALID_DIR_HANDLE NULL
+ struct dirent *de;
+#if defined(HAVE_READDIR_R)
+ struct dirent *dirent;
+ size_t dirent_allocated;
+#endif
+ int flags;
+ int visit_type;
+ /* Error code from last failed operation. */
+ int tree_errno;
+
+ /* Dynamically-sized buffer for holding path */
+ struct archive_string path;
+
+ /* Last path element */
+ const char *basename;
+ /* Leading dir length */
+ size_t dirname_length;
+
+ int depth;
+ int openCount;
+ int maxOpenCount;
+ int initial_dir_fd;
+ int working_dir_fd;
+
+ struct stat lst;
+ struct stat st;
+ int descend;
+ int nlink;
+ /* How to restore time of a file. */
+ struct restore_time restore_time;
+
+ struct entry_sparse {
+ int64_t length;
+ int64_t offset;
+ } *sparse_list, *current_sparse;
+ int sparse_count;
+ int sparse_list_size;
+
+ char initial_symlink_mode;
+ char symlink_mode;
+ struct filesystem *current_filesystem;
+ struct filesystem *filesystem_table;
+ int current_filesystem_id;
+ int max_filesystem_id;
+ int allocated_filesytem;
+
+ int entry_fd;
+ int entry_eof;
+ int64_t entry_remaining_bytes;
+ int64_t entry_total;
+ unsigned char *entry_buff;
+ size_t entry_buff_size;
+};
+
+/* Definitions for tree.flags bitmap. */
+#define hasStat 16 /* The st entry is valid. */
+#define hasLstat 32 /* The lst entry is valid. */
+#define onWorkingDir 64 /* We are on the working dir where we are
+ * reading directory entry at this time. */
+#define needsRestoreTimes 128
+
+static int
+tree_dir_next_posix(struct tree *t);
+
+#ifdef HAVE_DIRENT_D_NAMLEN
+/* BSD extension; avoids need for a strlen() call. */
+#define D_NAMELEN(dp) (dp)->d_namlen
+#else
+#define D_NAMELEN(dp) (strlen((dp)->d_name))
+#endif
+
+/* Initiate/terminate a tree traversal. */
+static struct tree *tree_open(const char *, int, int);
+static struct tree *tree_reopen(struct tree *, const char *, int);
+static void tree_close(struct tree *);
+static void tree_free(struct tree *);
+static void tree_push(struct tree *, const char *, int, int64_t, int64_t,
+ struct restore_time *);
+static int tree_enter_initial_dir(struct tree *);
+static int tree_enter_working_dir(struct tree *);
+static int tree_current_dir_fd(struct tree *);
+
+/*
+ * tree_next() returns Zero if there is no next entry, non-zero if
+ * there is. Note that directories are visited three times.
+ * Directories are always visited first as part of enumerating their
+ * parent; that is a "regular" visit. If tree_descend() is invoked at
+ * that time, the directory is added to a work list and will
+ * subsequently be visited two more times: once just after descending
+ * into the directory ("postdescent") and again just after ascending
+ * back to the parent ("postascent").
+ *
+ * TREE_ERROR_DIR is returned if the descent failed (because the
+ * directory couldn't be opened, for instance). This is returned
+ * instead of TREE_POSTDESCENT/TREE_POSTASCENT. TREE_ERROR_DIR is not a
+ * fatal error, but it does imply that the relevant subtree won't be
+ * visited. TREE_ERROR_FATAL is returned for an error that left the
+ * traversal completely hosed. Right now, this is only returned for
+ * chdir() failures during ascent.
+ */
+#define TREE_REGULAR 1
+#define TREE_POSTDESCENT 2
+#define TREE_POSTASCENT 3
+#define TREE_ERROR_DIR -1
+#define TREE_ERROR_FATAL -2
+
+static int tree_next(struct tree *);
+
+/*
+ * Return information about the current entry.
+ */
+
+/*
+ * The current full pathname, length of the full pathname, and a name
+ * that can be used to access the file. Because tree does use chdir
+ * extensively, the access path is almost never the same as the full
+ * current path.
+ *
+ * TODO: On platforms that support it, use openat()-style operations
+ * to eliminate the chdir() operations entirely while still supporting
+ * arbitrarily deep traversals. This makes access_path troublesome to
+ * support, of course, which means we'll need a rich enough interface
+ * that clients can function without it. (In particular, we'll need
+ * tree_current_open() that returns an open file descriptor.)
+ *
+ */
+static const char *tree_current_path(struct tree *);
+static const char *tree_current_access_path(struct tree *);
+
+/*
+ * Request the lstat() or stat() data for the current path. Since the
+ * tree package needs to do some of this anyway, and caches the
+ * results, you should take advantage of it here if you need it rather
+ * than make a redundant stat() or lstat() call of your own.
+ */
+static const struct stat *tree_current_stat(struct tree *);
+static const struct stat *tree_current_lstat(struct tree *);
+static int tree_current_is_symblic_link_target(struct tree *);
+
+/* The following functions use tricks to avoid a certain number of
+ * stat()/lstat() calls. */
+/* "is_physical_dir" is equivalent to S_ISDIR(tree_current_lstat()->st_mode) */
+static int tree_current_is_physical_dir(struct tree *);
+/* "is_dir" is equivalent to S_ISDIR(tree_current_stat()->st_mode) */
+static int tree_current_is_dir(struct tree *);
+static int update_current_filesystem(struct archive_read_disk *a,
+ int64_t dev);
+static int setup_current_filesystem(struct archive_read_disk *);
+static int tree_target_is_same_as_parent(struct tree *, const struct stat *);
+
+static int _archive_read_disk_open(struct archive *, const char *);
+static int _archive_read_free(struct archive *);
+static int _archive_read_close(struct archive *);
+static int _archive_read_data_block(struct archive *,
+ const void **, size_t *, int64_t *);
+static int _archive_read_next_header2(struct archive *,
+ struct archive_entry *);
+static const char *trivial_lookup_gname(void *, int64_t gid);
+static const char *trivial_lookup_uname(void *, int64_t uid);
+static int setup_sparse(struct archive_read_disk *, struct archive_entry *);
+static int close_and_restore_time(int fd, struct tree *,
+ struct restore_time *);
+
+
+static struct archive_vtable *
+archive_read_disk_vtable(void)
+{
+ static struct archive_vtable av;
+ static int inited = 0;
+
+ if (!inited) {
+ av.archive_free = _archive_read_free;
+ av.archive_close = _archive_read_close;
+ av.archive_read_data_block = _archive_read_data_block;
+ av.archive_read_next_header2 = _archive_read_next_header2;
+ inited = 1;
+ }
+ return (&av);
+}
+
+const char *
+archive_read_disk_gname(struct archive *_a, int64_t gid)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_gname"))
+ return (NULL);
+ if (a->lookup_gname == NULL)
+ return (NULL);
+ return ((*a->lookup_gname)(a->lookup_gname_data, gid));
+}
+
+const char *
+archive_read_disk_uname(struct archive *_a, int64_t uid)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_uname"))
+ return (NULL);
+ if (a->lookup_uname == NULL)
+ return (NULL);
+ return ((*a->lookup_uname)(a->lookup_uname_data, uid));
+}
+
+int
+archive_read_disk_set_gname_lookup(struct archive *_a,
+ void *private_data,
+ const char * (*lookup_gname)(void *private, int64_t gid),
+ void (*cleanup_gname)(void *private))
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_set_gname_lookup");
+
+ if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL)
+ (a->cleanup_gname)(a->lookup_gname_data);
+
+ a->lookup_gname = lookup_gname;
+ a->cleanup_gname = cleanup_gname;
+ a->lookup_gname_data = private_data;
+ return (ARCHIVE_OK);
+}
+
+int
+archive_read_disk_set_uname_lookup(struct archive *_a,
+ void *private_data,
+ const char * (*lookup_uname)(void *private, int64_t uid),
+ void (*cleanup_uname)(void *private))
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_set_uname_lookup");
+
+ if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL)
+ (a->cleanup_uname)(a->lookup_uname_data);
+
+ a->lookup_uname = lookup_uname;
+ a->cleanup_uname = cleanup_uname;
+ a->lookup_uname_data = private_data;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Create a new archive_read_disk object and initialize it with global state.
+ */
+struct archive *
+archive_read_disk_new(void)
+{
+ struct archive_read_disk *a;
+
+ a = (struct archive_read_disk *)malloc(sizeof(*a));
+ if (a == NULL)
+ return (NULL);
+ memset(a, 0, sizeof(*a));
+ a->archive.magic = ARCHIVE_READ_DISK_MAGIC;
+ a->archive.state = ARCHIVE_STATE_NEW;
+ a->archive.vtable = archive_read_disk_vtable();
+ a->lookup_uname = trivial_lookup_uname;
+ a->lookup_gname = trivial_lookup_gname;
+ a->entry_wd_fd = -1;
+ return (&a->archive);
+}
+
+static int
+_archive_read_free(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ int r;
+
+ if (_a == NULL)
+ return (ARCHIVE_OK);
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_free");
+
+ if (a->archive.state != ARCHIVE_STATE_CLOSED)
+ r = _archive_read_close(&a->archive);
+ else
+ r = ARCHIVE_OK;
+
+ tree_free(a->tree);
+ if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL)
+ (a->cleanup_gname)(a->lookup_gname_data);
+ if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL)
+ (a->cleanup_uname)(a->lookup_uname_data);
+ archive_string_free(&a->archive.error_string);
+ a->archive.magic = 0;
+ __archive_clean(&a->archive);
+ free(a);
+ return (r);
+}
+
+static int
+_archive_read_close(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_close");
+
+ if (a->archive.state != ARCHIVE_STATE_FATAL)
+ a->archive.state = ARCHIVE_STATE_CLOSED;
+
+ tree_close(a->tree);
+
+ return (ARCHIVE_OK);
+}
+
+static void
+setup_symlink_mode(struct archive_read_disk *a, char symlink_mode,
+ int follow_symlinks)
+{
+ a->symlink_mode = symlink_mode;
+ a->follow_symlinks = follow_symlinks;
+ if (a->tree != NULL) {
+ a->tree->initial_symlink_mode = a->symlink_mode;
+ a->tree->symlink_mode = a->symlink_mode;
+ }
+}
+
+int
+archive_read_disk_set_symlink_logical(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_logical");
+ setup_symlink_mode(a, 'L', 1);
+ return (ARCHIVE_OK);
+}
+
+int
+archive_read_disk_set_symlink_physical(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_physical");
+ setup_symlink_mode(a, 'P', 0);
+ return (ARCHIVE_OK);
+}
+
+int
+archive_read_disk_set_symlink_hybrid(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_hybrid");
+ setup_symlink_mode(a, 'H', 1);/* Follow symlinks initially. */
+ return (ARCHIVE_OK);
+}
+
+int
+archive_read_disk_set_atime_restored(struct archive *_a)
+{
+#ifndef HAVE_UTIMES
+ static int warning_done = 0;
+#endif
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_restore_atime");
+#ifdef HAVE_UTIMES
+ a->restore_time = 1;
+ if (a->tree != NULL)
+ a->tree->flags |= needsRestoreTimes;
+ return (ARCHIVE_OK);
+#else
+ if (warning_done)
+ /* Warning was already emitted; suppress further warnings. */
+ return (ARCHIVE_OK);
+
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Cannot restore access time on this system");
+ warning_done = 1;
+ return (ARCHIVE_WARN);
+#endif
+}
+
+/*
+ * Trivial implementations of gname/uname lookup functions.
+ * These are normally overridden by the client, but these stub
+ * versions ensure that we always have something that works.
+ */
+static const char *
+trivial_lookup_gname(void *private_data, int64_t gid)
+{
+ (void)private_data; /* UNUSED */
+ (void)gid; /* UNUSED */
+ return (NULL);
+}
+
+static const char *
+trivial_lookup_uname(void *private_data, int64_t uid)
+{
+ (void)private_data; /* UNUSED */
+ (void)uid; /* UNUSED */
+ return (NULL);
+}
+
+/*
+ * Allocate memory for the reading buffer adjusted to the filesystem
+ * alignment.
+ */
+static int
+setup_suitable_read_buffer(struct archive_read_disk *a)
+{
+ struct tree *t = a->tree;
+ struct filesystem *cf = t->current_filesystem;
+ size_t asize;
+ size_t s;
+
+ if (cf->allocation_ptr == NULL) {
+ /* If we couldn't get a filesystem alignment,
+ * we use 4096 as default value but we won't use
+ * O_DIRECT to open() and openat() operations. */
+ long xfer_align = (cf->xfer_align == -1)?4096:cf->xfer_align;
+
+ if (cf->max_xfer_size != -1)
+ asize = cf->max_xfer_size + xfer_align;
+ else {
+ long incr = cf->incr_xfer_size;
+ /* Some platform does not set a proper value to
+ * incr_xfer_size.*/
+ if (incr < 0)
+ incr = cf->min_xfer_size;
+ if (cf->min_xfer_size < 0) {
+ incr = xfer_align;
+ asize = xfer_align;
+ } else
+ asize = cf->min_xfer_size;
+
+ /* Increase a buffer size up to 64K bytes in
+ * a proper incremant size. */
+ while (asize < 1024*64)
+ asize += incr;
+ /* Take a margin to adjust to the filesystem
+ * alignment. */
+ asize += xfer_align;
+ }
+ cf->allocation_ptr = malloc(asize);
+ if (cf->allocation_ptr == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Couldn't allocate memory");
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+ }
+
+ /*
+ * Calculate proper address for the filesystem.
+ */
+ s = (uintptr_t)cf->allocation_ptr;
+ s %= xfer_align;
+ if (s > 0)
+ s = xfer_align - s;
+
+ /*
+ * Set a read buffer pointer in the proper alignment of
+ * the current filesystem.
+ */
+ cf->buff = cf->allocation_ptr + s;
+ cf->buff_size = asize - xfer_align;
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+_archive_read_data_block(struct archive *_a, const void **buff,
+ size_t *size, int64_t *offset)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ struct tree *t = a->tree;
+ int r;
+ ssize_t bytes;
+ size_t buffbytes;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
+ "archive_read_data_block");
+
+ if (t->entry_eof || t->entry_remaining_bytes <= 0) {
+ r = ARCHIVE_EOF;
+ goto abort_read_data;
+ }
+
+ /*
+ * Open the current file.
+ */
+ if (t->entry_fd < 0) {
+ int flags = O_RDONLY | O_BINARY;
+
+ /*
+ * Eliminate or reduce cache effects if we can.
+ *
+ * Carefully consider this to be enabled.
+ */
+#if defined(O_DIRECT) && 0/* Disabled for now */
+ if (t->current_filesystem->xfer_align != -1 &&
+ t->nlink == 1)
+ flags |= O_DIRECT;
+#endif
+#if defined(O_NOATIME)
+ /*
+ * Linux has O_NOATIME flag; use it if we need.
+ */
+ if ((t->flags & needsRestoreTimes) != 0 &&
+ t->restore_time.noatime == 0)
+ flags |= O_NOATIME;
+ do {
+#endif
+#ifdef HAVE_OPENAT
+ t->entry_fd = openat(tree_current_dir_fd(t),
+ tree_current_access_path(t), flags);
+#else
+ tree_enter_working_dir(t);
+ t->entry_fd = open(tree_current_access_path(t), flags);
+#endif
+#if defined(O_NOATIME)
+ /*
+ * When we did open the file with O_NOATIME flag,
+ * if successful, set 1 to t->restore_time.noatime
+ * not to restore an atime of the file later.
+ * if failed by EPERM, retry it without O_NOATIME flag.
+ */
+ if (flags & O_NOATIME) {
+ if (t->entry_fd >= 0)
+ t->restore_time.noatime = 1;
+ else if (errno == EPERM) {
+ flags &= ~O_NOATIME;
+ continue;
+ }
+ }
+ } while (0);
+#endif
+ if (t->entry_fd < 0) {
+ archive_set_error(&a->archive, errno,
+ "Couldn't open %s", tree_current_path(t));
+ r = ARCHIVE_FAILED;
+ tree_enter_initial_dir(t);
+ goto abort_read_data;
+ }
+ tree_enter_initial_dir(t);
+ }
+
+ /*
+ * Allocate read buffer if not allocated.
+ */
+ if (t->current_filesystem->allocation_ptr == NULL) {
+ r = setup_suitable_read_buffer(a);
+ if (r != ARCHIVE_OK) {
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ goto abort_read_data;
+ }
+ }
+ t->entry_buff = t->current_filesystem->buff;
+ t->entry_buff_size = t->current_filesystem->buff_size;
+
+ buffbytes = t->entry_buff_size;
+ if (buffbytes > t->current_sparse->length)
+ buffbytes = t->current_sparse->length;
+
+ /*
+ * Skip hole.
+ * TODO: Should we consider t->current_filesystem->xfer_align?
+ */
+ if (t->current_sparse->offset > t->entry_total) {
+ if (lseek(t->entry_fd,
+ (off_t)t->current_sparse->offset, SEEK_SET) < 0) {
+ archive_set_error(&a->archive, errno, "Seek error");
+ r = ARCHIVE_FATAL;
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ goto abort_read_data;
+ }
+ bytes = t->current_sparse->offset - t->entry_total;
+ t->entry_remaining_bytes -= bytes;
+ t->entry_total += bytes;
+ }
+
+ /*
+ * Read file contents.
+ */
+ if (buffbytes > 0) {
+ bytes = read(t->entry_fd, t->entry_buff, buffbytes);
+ if (bytes < 0) {
+ archive_set_error(&a->archive, errno, "Read error");
+ r = ARCHIVE_FATAL;
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ goto abort_read_data;
+ }
+ } else
+ bytes = 0;
+ if (bytes == 0) {
+ /* Get EOF */
+ t->entry_eof = 1;
+ r = ARCHIVE_EOF;
+ goto abort_read_data;
+ }
+ *buff = t->entry_buff;
+ *size = bytes;
+ *offset = t->entry_total;
+ t->entry_total += bytes;
+ t->entry_remaining_bytes -= bytes;
+ if (t->entry_remaining_bytes == 0) {
+ /* Close the current file descriptor */
+ close_and_restore_time(t->entry_fd, t, &t->restore_time);
+ t->entry_fd = -1;
+ t->entry_eof = 1;
+ }
+ t->current_sparse->offset += bytes;
+ t->current_sparse->length -= bytes;
+ if (t->current_sparse->length == 0 && !t->entry_eof)
+ t->current_sparse++;
+ return (ARCHIVE_OK);
+
+abort_read_data:
+ *buff = NULL;
+ *size = 0;
+ *offset = t->entry_total;
+ if (t->entry_fd >= 0) {
+ /* Close the current file descriptor */
+ close_and_restore_time(t->entry_fd, t, &t->restore_time);
+ t->entry_fd = -1;
+ }
+ return (r);
+}
+
+static int
+_archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ struct tree *t;
+ const struct stat *st; /* info to use for this entry */
+ const struct stat *lst;/* lstat() information */
+ int descend, fd = -1, r;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
+ "archive_read_next_header2");
+
+ t = a->tree;
+ if (t->entry_fd >= 0) {
+ close_and_restore_time(t->entry_fd, t, &t->restore_time);
+ t->entry_fd = -1;
+ }
+#if !(defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR))
+ /* Restore working directory. */
+ tree_enter_working_dir(t);
+#endif
+ st = NULL;
+ lst = NULL;
+ do {
+ switch (tree_next(t)) {
+ case TREE_ERROR_FATAL:
+ archive_set_error(&a->archive, t->tree_errno,
+ "%s: Unable to continue traversing directory tree",
+ tree_current_path(t));
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ tree_enter_initial_dir(t);
+ return (ARCHIVE_FATAL);
+ case TREE_ERROR_DIR:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "%s: Couldn't visit directory",
+ tree_current_path(t));
+ tree_enter_initial_dir(t);
+ return (ARCHIVE_FAILED);
+ case 0:
+ tree_enter_initial_dir(t);
+ return (ARCHIVE_EOF);
+ case TREE_POSTDESCENT:
+ case TREE_POSTASCENT:
+ break;
+ case TREE_REGULAR:
+ lst = tree_current_lstat(t);
+ if (lst == NULL) {
+ archive_set_error(&a->archive, errno,
+ "%s: Cannot stat",
+ tree_current_path(t));
+ tree_enter_initial_dir(t);
+ return (ARCHIVE_FAILED);
+ }
+ break;
+ }
+ } while (lst == NULL);
+
+ /*
+ * Distinguish 'L'/'P'/'H' symlink following.
+ */
+ switch(t->symlink_mode) {
+ case 'H':
+ /* 'H': After the first item, rest like 'P'. */
+ t->symlink_mode = 'P';
+ /* 'H': First item (from command line) like 'L'. */
+ /* FALLTHROUGH */
+ case 'L':
+ /* 'L': Do descend through a symlink to dir. */
+ descend = tree_current_is_dir(t);
+ /* 'L': Follow symlinks to files. */
+ a->symlink_mode = 'L';
+ a->follow_symlinks = 1;
+ /* 'L': Archive symlinks as targets, if we can. */
+ st = tree_current_stat(t);
+ if (st != NULL && !tree_target_is_same_as_parent(t, st))
+ break;
+ /* If stat fails, we have a broken symlink;
+ * in that case, don't follow the link. */
+ /* FALLTHROUGH */
+ default:
+ /* 'P': Don't descend through a symlink to dir. */
+ descend = tree_current_is_physical_dir(t);
+ /* 'P': Don't follow symlinks to files. */
+ a->symlink_mode = 'P';
+ a->follow_symlinks = 0;
+ /* 'P': Archive symlinks as symlinks. */
+ st = lst;
+ break;
+ }
+
+ if (update_current_filesystem(a, st->st_dev) != ARCHIVE_OK) {
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ tree_enter_initial_dir(t);
+ return (ARCHIVE_FATAL);
+ }
+ t->descend = descend;
+
+ archive_entry_set_pathname(entry, tree_current_path(t));
+ archive_entry_copy_sourcepath(entry, tree_current_access_path(t));
+ archive_entry_copy_stat(entry, st);
+
+ /* Save the times to be restored. */
+ t->restore_time.mtime = archive_entry_mtime(entry);
+ t->restore_time.mtime_nsec = archive_entry_mtime_nsec(entry);
+ t->restore_time.atime = archive_entry_atime(entry);
+ t->restore_time.atime_nsec = archive_entry_atime_nsec(entry);
+ t->restore_time.filetype = archive_entry_filetype(entry);
+ t->restore_time.noatime = t->current_filesystem->noatime;
+
+#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR)
+ /*
+ * Open the current file to freely gather its metadata anywhere in
+ * working directory.
+ * Note: A symbolic link file cannot be opened with O_NOFOLLOW.
+ */
+ if (a->follow_symlinks || archive_entry_filetype(entry) != AE_IFLNK)
+ fd = openat(tree_current_dir_fd(t), tree_current_access_path(t),
+ O_RDONLY | O_NONBLOCK);
+ /* Restore working directory if openat() operation failed or
+ * the file is a symbolic link. */
+ if (fd < 0)
+ tree_enter_working_dir(t);
+
+ /* The current direcotry fd is needed at
+ * archive_read_disk_entry_from_file() function to read link data
+ * with readlinkat(). */
+ a->entry_wd_fd = tree_current_dir_fd(t);
+#endif
+
+ /*
+ * Populate the archive_entry with metadata from the disk.
+ */
+ r = archive_read_disk_entry_from_file(&(a->archive), entry, fd, st);
+
+ /* Close the file descriptor used for reding the current file
+ * metadata at archive_read_disk_entry_from_file(). */
+ if (fd >= 0)
+ close(fd);
+
+ /* Return to the initial directory. */
+ tree_enter_initial_dir(t);
+ archive_entry_copy_sourcepath(entry, tree_current_path(t));
+
+ /*
+ * EOF and FATAL are persistent at this layer. By
+ * modifying the state, we guarantee that future calls to
+ * read a header or read data will fail.
+ */
+ switch (r) {
+ case ARCHIVE_EOF:
+ a->archive.state = ARCHIVE_STATE_EOF;
+ break;
+ case ARCHIVE_OK:
+ case ARCHIVE_WARN:
+ t->entry_total = 0;
+ if (archive_entry_filetype(entry) == AE_IFREG) {
+ t->nlink = archive_entry_nlink(entry);
+ t->entry_remaining_bytes = archive_entry_size(entry);
+ t->entry_eof = (t->entry_remaining_bytes == 0)? 1: 0;
+ if (!t->entry_eof &&
+ setup_sparse(a, entry) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ } else {
+ t->entry_remaining_bytes = 0;
+ t->entry_eof = 1;
+ }
+ a->archive.state = ARCHIVE_STATE_DATA;
+ break;
+ case ARCHIVE_RETRY:
+ break;
+ case ARCHIVE_FATAL:
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ break;
+ }
+
+ return (r);
+}
+
+static int
+setup_sparse(struct archive_read_disk *a, struct archive_entry *entry)
+{
+ struct tree *t = a->tree;
+ int64_t length, offset;
+ int i;
+
+ t->sparse_count = archive_entry_sparse_reset(entry);
+ if (t->sparse_count+1 > t->sparse_list_size) {
+ free(t->sparse_list);
+ t->sparse_list_size = t->sparse_count + 1;
+ t->sparse_list = malloc(sizeof(t->sparse_list[0]) *
+ t->sparse_list_size);
+ if (t->sparse_list == NULL) {
+ t->sparse_list_size = 0;
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate data");
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+ }
+ }
+ for (i = 0; i < t->sparse_count; i++) {
+ archive_entry_sparse_next(entry, &offset, &length);
+ t->sparse_list[i].offset = offset;
+ t->sparse_list[i].length = length;
+ }
+ if (i == 0) {
+ t->sparse_list[i].offset = 0;
+ t->sparse_list[i].length = archive_entry_size(entry);
+ } else {
+ t->sparse_list[i].offset = archive_entry_size(entry);
+ t->sparse_list[i].length = 0;
+ }
+ t->current_sparse = t->sparse_list;
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Called by the client to mark the directory just returned from
+ * tree_next() as needing to be visited.
+ */
+int
+archive_read_disk_descend(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ struct tree *t = a->tree;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
+ "archive_read_disk_descend");
+
+ if (t->visit_type != TREE_REGULAR || !t->descend) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Ignored the request descending the current object");
+ return (ARCHIVE_WARN);
+ }
+
+ if (tree_current_is_physical_dir(t)) {
+ tree_push(t, t->basename, t->current_filesystem_id,
+ t->lst.st_dev, t->lst.st_ino, &t->restore_time);
+ t->stack->flags |= isDir;
+ } else if (tree_current_is_dir(t)) {
+ tree_push(t, t->basename, t->current_filesystem_id,
+ t->st.st_dev, t->st.st_ino, &t->restore_time);
+ t->stack->flags |= isDirLink;
+ }
+ t->descend = 0;
+ return (ARCHIVE_OK);
+}
+
+int
+archive_read_disk_open(struct archive *_a, const char *pathname)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_NEW | ARCHIVE_STATE_CLOSED,
+ "archive_read_disk_open");
+ archive_clear_error(&a->archive);
+
+ return (_archive_read_disk_open(_a, pathname));
+}
+
+int
+archive_read_disk_open_w(struct archive *_a, const wchar_t *pathname)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ struct archive_string path;
+ int ret;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_NEW | ARCHIVE_STATE_CLOSED,
+ "archive_read_disk_open_w");
+ archive_clear_error(&a->archive);
+
+ /* Make a char string from a wchar_t string. */
+ archive_string_init(&path);
+ if (archive_string_append_from_wcs(&path, pathname,
+ wcslen(pathname)) != 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Can't convert a path to a char string");
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ ret = ARCHIVE_FATAL;
+ } else
+ ret = _archive_read_disk_open(_a, path.s);
+
+ archive_string_free(&path);
+ return (ret);
+}
+
+static int
+_archive_read_disk_open(struct archive *_a, const char *pathname)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+
+ if (a->tree != NULL)
+ a->tree = tree_reopen(a->tree, pathname, a->restore_time);
+ else
+ a->tree = tree_open(pathname, a->symlink_mode,
+ a->restore_time);
+ if (a->tree == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate tar data");
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+ }
+ a->archive.state = ARCHIVE_STATE_HEADER;
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Return a current filesystem ID which is index of the filesystem entry
+ * you've visited through archive_read_disk.
+ */
+int
+archive_read_disk_current_filesystem(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
+ "archive_read_disk_current_filesystem");
+
+ return (a->tree->current_filesystem_id);
+}
+
+static int
+update_current_filesystem(struct archive_read_disk *a, int64_t dev)
+{
+ struct tree *t = a->tree;
+ int i, fid;
+
+ if (t->current_filesystem != NULL &&
+ t->current_filesystem->dev == dev)
+ return (ARCHIVE_OK);
+
+ for (i = 0; i < t->max_filesystem_id; i++) {
+ if (t->filesystem_table[i].dev == dev) {
+ /* There is the filesytem ID we've already generated. */
+ t->current_filesystem_id = i;
+ t->current_filesystem = &(t->filesystem_table[i]);
+ return (ARCHIVE_OK);
+ }
+ }
+
+ /*
+ * This is the new filesytem which we have to generate a new ID for.
+ */
+ fid = t->max_filesystem_id++;
+ if (t->max_filesystem_id > t->allocated_filesytem) {
+ size_t s;
+
+ s = t->max_filesystem_id * 2;
+ t->filesystem_table = realloc(t->filesystem_table,
+ s * sizeof(*t->filesystem_table));
+ if (t->filesystem_table == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate tar data");
+ return (ARCHIVE_FATAL);
+ }
+ t->allocated_filesytem = s;
+ }
+ t->current_filesystem_id = fid;
+ t->current_filesystem = &(t->filesystem_table[fid]);
+ t->current_filesystem->dev = dev;
+ t->current_filesystem->allocation_ptr = NULL;
+ t->current_filesystem->buff = NULL;
+
+ /* Setup the current filesystem properties which depend on
+ * platform specific. */
+ return (setup_current_filesystem(a));
+}
+
+/*
+ * Returns 1 if current filesystem is generated filesystem, 0 if it is not
+ * or -1 if it is unknown.
+ */
+int
+archive_read_disk_current_filesystem_is_synthetic(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
+ "archive_read_disk_current_filesystem");
+
+ return (a->tree->current_filesystem->synthetic);
+}
+
+/*
+ * Returns 1 if current filesystem is remote filesystem, 0 if it is not
+ * or -1 if it is unknown.
+ */
+int
+archive_read_disk_current_filesystem_is_remote(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
+ "archive_read_disk_current_filesystem");
+
+ return (a->tree->current_filesystem->remote);
+}
+
+#if defined(_PC_REC_INCR_XFER_SIZE) && defined(_PC_REC_MAX_XFER_SIZE) &&\
+ defined(_PC_REC_MIN_XFER_SIZE) && defined(_PC_REC_XFER_ALIGN)
+static int
+get_xfer_size(struct tree *t, int fd, const char *path)
+{
+ t->current_filesystem->xfer_align = -1;
+ errno = 0;
+ if (fd >= 0) {
+ t->current_filesystem->incr_xfer_size =
+ fpathconf(fd, _PC_REC_INCR_XFER_SIZE);
+ t->current_filesystem->max_xfer_size =
+ fpathconf(fd, _PC_REC_MAX_XFER_SIZE);
+ t->current_filesystem->min_xfer_size =
+ fpathconf(fd, _PC_REC_MIN_XFER_SIZE);
+ t->current_filesystem->xfer_align =
+ fpathconf(fd, _PC_REC_XFER_ALIGN);
+ } else if (path != NULL) {
+ t->current_filesystem->incr_xfer_size =
+ pathconf(path, _PC_REC_INCR_XFER_SIZE);
+ t->current_filesystem->max_xfer_size =
+ pathconf(path, _PC_REC_MAX_XFER_SIZE);
+ t->current_filesystem->min_xfer_size =
+ pathconf(path, _PC_REC_MIN_XFER_SIZE);
+ t->current_filesystem->xfer_align =
+ pathconf(path, _PC_REC_XFER_ALIGN);
+ }
+ /* At least we need an alignment size. */
+ if (t->current_filesystem->xfer_align == -1)
+ return ((errno == EINVAL)?1:-1);
+ else
+ return (0);
+}
+#else
+static int
+get_xfer_size(struct tree *t, int fd, const char *path)
+{
+ (void)t; /* UNUSED */
+ (void)fd; /* UNUSED */
+ (void)path; /* UNUSED */
+ return (1);/* Not supported */
+}
+#endif
+
+#if defined(HAVE_STATFS) && defined(HAVE_FSTATFS) && defined(MNT_LOCAL) \
+ && !defined(ST_LOCAL)
+
+/*
+ * Gather current filesystem properties on FreeBSD, OpenBSD and Mac OS X.
+ */
+static int
+setup_current_filesystem(struct archive_read_disk *a)
+{
+ struct tree *t = a->tree;
+ struct statfs sfs;
+#if defined(HAVE_GETVFSBYNAME) && defined(VFCF_SYNTHETIC)
+ struct xvfsconf vfc;
+#endif
+ int r, xr = 0;
+#if !defined(HAVE_STRUCT_STATFS_F_NAMEMAX)
+ long nm;
+#endif
+
+ t->current_filesystem->synthetic = -1;
+ t->current_filesystem->remote = -1;
+ if (tree_current_is_symblic_link_target(t)) {
+#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR)
+ /*
+ * Get file system statistics on any directory
+ * where current is.
+ */
+ int fd = openat(tree_current_dir_fd(t),
+ tree_current_access_path(t), O_RDONLY);
+ if (fd < 0) {
+ archive_set_error(&a->archive, errno,
+ "openat failed");
+ return (ARCHIVE_FAILED);
+ }
+ r = fstatfs(fd, &sfs);
+ if (r == 0)
+ xr = get_xfer_size(t, fd, NULL);
+ close(fd);
+#else
+ r = statfs(tree_current_access_path(t), &sfs);
+ if (r == 0)
+ xr = get_xfer_size(t, -1, tree_current_access_path(t));
+#endif
+ } else {
+ r = fstatfs(tree_current_dir_fd(t), &sfs);
+ if (r == 0)
+ xr = get_xfer_size(t, tree_current_dir_fd(t), NULL);
+ }
+ if (r == -1 || xr == -1) {
+ archive_set_error(&a->archive, errno, "statfs failed");
+ return (ARCHIVE_FAILED);
+ } else if (xr == 1) {
+ /* pathconf(_PC_REX_*) operations are not supported. */
+ t->current_filesystem->xfer_align = sfs.f_bsize;
+ t->current_filesystem->max_xfer_size = -1;
+ t->current_filesystem->min_xfer_size = sfs.f_iosize;
+ t->current_filesystem->incr_xfer_size = sfs.f_iosize;
+ }
+ if (sfs.f_flags & MNT_LOCAL)
+ t->current_filesystem->remote = 0;
+ else
+ t->current_filesystem->remote = 1;
+
+#if defined(HAVE_GETVFSBYNAME) && defined(VFCF_SYNTHETIC)
+ r = getvfsbyname(sfs.f_fstypename, &vfc);
+ if (r == -1) {
+ archive_set_error(&a->archive, errno, "getvfsbyname failed");
+ return (ARCHIVE_FAILED);
+ }
+ if (vfc.vfc_flags & VFCF_SYNTHETIC)
+ t->current_filesystem->synthetic = 1;
+ else
+ t->current_filesystem->synthetic = 0;
+#endif
+
+#if defined(MNT_NOATIME)
+ if (sfs.f_flags & MNT_NOATIME)
+ t->current_filesystem->noatime = 1;
+ else
+#endif
+ t->current_filesystem->noatime = 0;
+
+#if defined(HAVE_READDIR_R)
+ /* Set maximum filename length. */
+#if defined(HAVE_STRUCT_STATFS_F_NAMEMAX)
+ t->current_filesystem->name_max = sfs.f_namemax;
+#else
+ /* Mac OS X does not have f_namemax in struct statfs. */
+ if (tree_current_is_symblic_link_target(t))
+ nm = pathconf(tree_current_access_path(t), _PC_NAME_MAX);
+ else
+ nm = fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX);
+ if (nm == -1)
+ t->current_filesystem->name_max = NAME_MAX;
+ else
+ t->current_filesystem->name_max = nm;
+#endif
+#endif /* HAVE_READDIR_R */
+ return (ARCHIVE_OK);
+}
+
+#elif (defined(HAVE_STATVFS) || defined(HAVE_FSTATVFS)) && defined(ST_LOCAL)
+
+/*
+ * Gather current filesystem properties on NetBSD
+ */
+static int
+setup_current_filesystem(struct archive_read_disk *a)
+{
+ struct tree *t = a->tree;
+ struct statvfs sfs;
+ int r, xr = 0;
+
+ t->current_filesystem->synthetic = -1;
+ if (tree_current_is_symblic_link_target(t)) {
+ r = statvfs(tree_current_access_path(t), &sfs);
+ if (r == 0)
+ xr = get_xfer_size(t, -1, tree_current_access_path(t));
+ } else {
+#ifdef HAVE_FSTATVFS
+ r = fstatvfs(tree_current_dir_fd(t), &sfs);
+ if (r == 0)
+ xr = get_xfer_size(t, tree_current_dir_fd(t), NULL);
+#else
+ r = statvfs(".", &sfs);
+ if (r == 0)
+ xr = get_xfer_size(t, -1, ".");
+#endif
+ }
+ if (r == -1 || xr == -1) {
+ t->current_filesystem->remote = -1;
+ archive_set_error(&a->archive, errno, "statvfs failed");
+ return (ARCHIVE_FAILED);
+ } else if (xr == 1) {
+ /* Usuall come here unless NetBSD supports _PC_REC_XFER_ALIGN
+ * for pathconf() function. */
+ t->current_filesystem->xfer_align = sfs.f_frsize;
+ t->current_filesystem->max_xfer_size = -1;
+ t->current_filesystem->min_xfer_size = sfs.f_iosize;
+ t->current_filesystem->incr_xfer_size = sfs.f_iosize;
+ }
+ if (sfs.f_flag & ST_LOCAL)
+ t->current_filesystem->remote = 0;
+ else
+ t->current_filesystem->remote = 1;
+
+ if (sfs.f_flag & ST_NOATIME)
+ t->current_filesystem->noatime = 1;
+ else
+ t->current_filesystem->noatime = 0;
+
+ /* Set maximum filename length. */
+ t->current_filesystem->name_max = sfs.f_namemax;
+ return (ARCHIVE_OK);
+}
+
+#elif defined(HAVE_SYS_STATFS_H) && defined(HAVE_LINUX_MAGIC_H) &&\
+ defined(HAVE_STATFS) && defined(HAVE_FSTATFS)
+/*
+ * Note: statfs is deprecated since LSB 3.2
+ */
+
+#ifndef CIFS_SUPER_MAGIC
+#define CIFS_SUPER_MAGIC 0xFF534D42
+#endif
+#ifndef DEVFS_SUPER_MAGIC
+#define DEVFS_SUPER_MAGIC 0x1373
+#endif
+
+/*
+ * Gather current filesystem properties on Linux
+ */
+static int
+setup_current_filesystem(struct archive_read_disk *a)
+{
+ struct tree *t = a->tree;
+ struct statfs sfs;
+ struct statvfs svfs;
+ int r, vr = 0, xr = 0;
+
+ if (tree_current_is_symblic_link_target(t)) {
+#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR)
+ /*
+ * Get file system statistics on any directory
+ * where current is.
+ */
+ int fd = openat(tree_current_dir_fd(t),
+ tree_current_access_path(t), O_RDONLY);
+ if (fd < 0) {
+ archive_set_error(&a->archive, errno,
+ "openat failed");
+ return (ARCHIVE_FAILED);
+ }
+ vr = fstatvfs(fd, &svfs);/* for f_flag, mount flags */
+ r = fstatfs(fd, &sfs);
+ if (r == 0)
+ xr = get_xfer_size(t, fd, NULL);
+ close(fd);
+#else
+ vr = statvfs(tree_current_access_path(t), &svfs);
+ r = statfs(tree_current_access_path(t), &sfs);
+ if (r == 0)
+ xr = get_xfer_size(t, -1, tree_current_access_path(t));
+#endif
+ } else {
+#ifdef HAVE_FSTATFS
+ vr = fstatvfs(tree_current_dir_fd(t), &svfs);
+ r = fstatfs(tree_current_dir_fd(t), &sfs);
+ if (r == 0)
+ xr = get_xfer_size(t, tree_current_dir_fd(t), NULL);
+#elif defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR)
+#error "Unexpected case. Please tell us about this error."
+#else
+ vr = statvfs(".", &svfs);
+ r = statfs(".", &sfs);
+ if (r == 0)
+ xr = get_xfer_size(t, -1, ".");
+#endif
+ }
+ if (r == -1 || xr == -1 || vr == -1) {
+ t->current_filesystem->synthetic = -1;
+ t->current_filesystem->remote = -1;
+ archive_set_error(&a->archive, errno, "statfs failed");
+ return (ARCHIVE_FAILED);
+ } else if (xr == 1) {
+ /* pathconf(_PC_REX_*) operations are not supported. */
+ t->current_filesystem->xfer_align = svfs.f_frsize;
+ t->current_filesystem->max_xfer_size = -1;
+ t->current_filesystem->min_xfer_size = svfs.f_bsize;
+ t->current_filesystem->incr_xfer_size = svfs.f_bsize;
+ }
+ switch (sfs.f_type) {
+ case AFS_SUPER_MAGIC:
+ case CIFS_SUPER_MAGIC:
+ case CODA_SUPER_MAGIC:
+ case NCP_SUPER_MAGIC:/* NetWare */
+ case NFS_SUPER_MAGIC:
+ case SMB_SUPER_MAGIC:
+ t->current_filesystem->remote = 1;
+ t->current_filesystem->synthetic = 0;
+ break;
+ case DEVFS_SUPER_MAGIC:
+ case PROC_SUPER_MAGIC:
+ case USBDEVICE_SUPER_MAGIC:
+ t->current_filesystem->remote = 0;
+ t->current_filesystem->synthetic = 1;
+ break;
+ default:
+ t->current_filesystem->remote = 0;
+ t->current_filesystem->synthetic = 0;
+ break;
+ }
+
+#if defined(ST_NOATIME)
+ if (svfs.f_flag & ST_NOATIME)
+ t->current_filesystem->noatime = 1;
+ else
+#endif
+ t->current_filesystem->noatime = 0;
+
+#if defined(HAVE_READDIR_R)
+ /* Set maximum filename length. */
+ t->current_filesystem->name_max = sfs.f_namelen;
+#endif
+ return (ARCHIVE_OK);
+}
+
+#elif defined(HAVE_SYS_STATVFS_H) &&\
+ (defined(HAVE_STATVFS) || defined(HAVE_FSTATVFS))
+
+/*
+ * Gather current filesystem properties on other posix platform.
+ */
+static int
+setup_current_filesystem(struct archive_read_disk *a)
+{
+ struct tree *t = a->tree;
+ struct statvfs sfs;
+ int r, xr = 0;
+
+ t->current_filesystem->synthetic = -1;/* Not supported */
+ t->current_filesystem->remote = -1;/* Not supported */
+ if (tree_current_is_symblic_link_target(t)) {
+#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR)
+ /*
+ * Get file system statistics on any directory
+ * where current is.
+ */
+ int fd = openat(tree_current_dir_fd(t),
+ tree_current_access_path(t), O_RDONLY);
+ if (fd < 0) {
+ archive_set_error(&a->archive, errno,
+ "openat failed");
+ return (ARCHIVE_FAILED);
+ }
+ r = fstatvfs(fd, &sfs);
+ if (r == 0)
+ xr = get_xfer_size(t, fd, NULL);
+ close(fd);
+#else
+ r = statvfs(tree_current_access_path(t), &sfs);
+ if (r == 0)
+ xr = get_xfer_size(t, -1, tree_current_access_path(t));
+#endif
+ } else {
+#ifdef HAVE_FSTATVFS
+ r = fstatvfs(tree_current_dir_fd(t), &sfs);
+ if (r == 0)
+ xr = get_xfer_size(t, tree_current_dir_fd(t), NULL);
+#elif defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR)
+#error "Unexpected case. Please tell us about this error."
+#else
+ r = statvfs(".", &sfs);
+ if (r == 0)
+ xr = get_xfer_size(t, -1, ".");
+#endif
+ }
+ if (r == -1 || xr == -1) {
+ t->current_filesystem->synthetic = -1;
+ t->current_filesystem->remote = -1;
+ archive_set_error(&a->archive, errno, "statvfs failed");
+ return (ARCHIVE_FAILED);
+ } else if (xr == 1) {
+ /* pathconf(_PC_REX_*) operations are not supported. */
+ t->current_filesystem->xfer_align = sfs.f_frsize;
+ t->current_filesystem->max_xfer_size = -1;
+ t->current_filesystem->min_xfer_size = sfs.f_bsize;
+ t->current_filesystem->incr_xfer_size = sfs.f_bsize;
+ }
+
+#if defined(ST_NOATIME)
+ if (sfs.f_flag & ST_NOATIME)
+ t->current_filesystem->noatime = 1;
+ else
+#endif
+ t->current_filesystem->noatime = 0;
+
+#if defined(HAVE_READDIR_R)
+ /* Set maximum filename length. */
+ t->current_filesystem->name_max = sfs.f_namemax;
+#endif
+ return (ARCHIVE_OK);
+}
+
+#else
+
+/*
+ * Generic: Gather current filesystem properties.
+ * TODO: Is this generic function really needed?
+ */
+static int
+setup_current_filesystem(struct archive_read_disk *a)
+{
+ struct tree *t = a->tree;
+#if defined(_PC_NAME_MAX) && defined(HAVE_READDIR_R)
+ long nm;
+#endif
+ t->current_filesystem->synthetic = -1;/* Not supported */
+ t->current_filesystem->remote = -1;/* Not supported */
+ t->current_filesystem->noatime = 0;
+ (void)get_xfer_size(t, -1, ".");/* Dummy call to avoid build error. */
+ t->current_filesystem->xfer_align = -1;/* Unknown */
+ t->current_filesystem->max_xfer_size = -1;
+ t->current_filesystem->min_xfer_size = -1;
+ t->current_filesystem->incr_xfer_size = -1;
+
+#if defined(HAVE_READDIR_R)
+ /* Set maximum filename length. */
+# if defined(_PC_NAME_MAX)
+ if (tree_current_is_symblic_link_target(t))
+ nm = pathconf(tree_current_access_path(t), _PC_NAME_MAX);
+ else
+ nm = fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX);
+ if (nm == -1)
+# endif /* _PC_NAME_MAX */
+ /*
+ * Some sysmtes (HP-UX or others?) incorrectly defined
+ * NAME_MAX macro to be a smaller value.
+ */
+# if defined(NAME_MAX) && NAME_MAX >= 255
+ t->current_filesystem->name_max = NAME_MAX;
+# else
+ /* No way to get a trusted value of maximum filename
+ * length. */
+ t->current_filesystem->name_max = PATH_MAX;
+# endif /* NAME_MAX */
+# if defined(_PC_NAME_MAX)
+ else
+ t->current_filesystem->name_max = nm;
+# endif /* _PC_NAME_MAX */
+#endif /* HAVE_READDIR_R */
+ return (ARCHIVE_OK);
+}
+
+#endif
+
+static int
+close_and_restore_time(int fd, struct tree *t, struct restore_time *rt)
+{
+#ifndef HAVE_UTIMES
+ (void)a; /* UNUSED */
+ return (close(fd));
+#else
+#if defined(HAVE_FUTIMENS) && !defined(__CYGWIN__)
+ struct timespec timespecs[2];
+#endif
+ struct timeval times[2];
+
+ if ((t->flags & needsRestoreTimes) == 0 || rt->noatime) {
+ if (fd >= 0)
+ return (close(fd));
+ else
+ return (0);
+ }
+
+#if defined(HAVE_FUTIMENS) && !defined(__CYGWIN__)
+ timespecs[1].tv_sec = rt->mtime;
+ timespecs[1].tv_nsec = rt->mtime_nsec;
+
+ timespecs[0].tv_sec = rt->atime;
+ timespecs[0].tv_nsec = rt->atime_nsec;
+ /* futimens() is defined in POSIX.1-2008. */
+ if (futimens(fd, timespecs) == 0)
+ return (close(fd));
+#endif
+
+ times[1].tv_sec = rt->mtime;
+ times[1].tv_usec = rt->mtime_nsec / 1000;
+
+ times[0].tv_sec = rt->atime;
+ times[0].tv_usec = rt->atime_nsec / 1000;
+
+#if !defined(HAVE_FUTIMENS) && defined(HAVE_FUTIMES) && !defined(__CYGWIN__)
+ if (futimes(fd, times) == 0)
+ return (close(fd));
+#endif
+ close(fd);
+#if defined(HAVE_FUTIMESAT)
+ if (futimesat(tree_current_dir_fd(t), rt->name, times) == 0)
+ return (0);
+#endif
+#ifdef HAVE_LUTIMES
+ if (lutimes(rt->name, times) != 0)
+#else
+ if (AE_IFLNK != rt->filetype && utimes(rt->name, times) != 0)
+#endif
+ return (-1);
+#endif
+ return (0);
+}
+
+/*
+ * Add a directory path to the current stack.
+ */
+static void
+tree_push(struct tree *t, const char *path, int filesystem_id,
+ int64_t dev, int64_t ino, struct restore_time *rt)
+{
+ struct tree_entry *te;
+
+ te = malloc(sizeof(*te));
+ memset(te, 0, sizeof(*te));
+ te->next = t->stack;
+ te->parent = t->current;
+ if (te->parent)
+ te->depth = te->parent->depth + 1;
+ t->stack = te;
+ archive_string_init(&te->name);
+ te->symlink_parent_fd = -1;
+ archive_strcpy(&te->name, path);
+ te->flags = needsDescent | needsOpen | needsAscent;
+ te->filesystem_id = filesystem_id;
+ te->dev = dev;
+ te->ino = ino;
+ te->dirname_length = t->dirname_length;
+ te->restore_time.name = te->name.s;
+ if (rt != NULL) {
+ te->restore_time.mtime = rt->mtime;
+ te->restore_time.mtime_nsec = rt->mtime_nsec;
+ te->restore_time.atime = rt->atime;
+ te->restore_time.atime_nsec = rt->atime_nsec;
+ te->restore_time.filetype = rt->filetype;
+ te->restore_time.noatime = rt->noatime;
+ }
+}
+
+/*
+ * Append a name to the current dir path.
+ */
+static void
+tree_append(struct tree *t, const char *name, size_t name_length)
+{
+ size_t size_needed;
+
+ t->path.s[t->dirname_length] = '\0';
+ t->path.length = t->dirname_length;
+ /* Strip trailing '/' from name, unless entire name is "/". */
+ while (name_length > 1 && name[name_length - 1] == '/')
+ name_length--;
+
+ /* Resize pathname buffer as needed. */
+ size_needed = name_length + t->dirname_length + 2;
+ archive_string_ensure(&t->path, size_needed);
+ /* Add a separating '/' if it's needed. */
+ if (t->dirname_length > 0 && t->path.s[archive_strlen(&t->path)-1] != '/')
+ archive_strappend_char(&t->path, '/');
+ t->basename = t->path.s + archive_strlen(&t->path);
+ archive_strncat(&t->path, name, name_length);
+ t->restore_time.name = t->basename;
+}
+
+/*
+ * Open a directory tree for traversal.
+ */
+static struct tree *
+tree_open(const char *path, int symlink_mode, int restore_time)
+{
+ struct tree *t;
+
+ if ((t = malloc(sizeof(*t))) == NULL)
+ return (NULL);
+ memset(t, 0, sizeof(*t));
+ archive_string_init(&t->path);
+ archive_string_ensure(&t->path, 31);
+ t->initial_symlink_mode = symlink_mode;
+ return (tree_reopen(t, path, restore_time));
+}
+
+static struct tree *
+tree_reopen(struct tree *t, const char *path, int restore_time)
+{
+ t->flags = (restore_time)?needsRestoreTimes:0;
+ t->visit_type = 0;
+ t->tree_errno = 0;
+ t->dirname_length = 0;
+ t->depth = 0;
+ t->descend = 0;
+ t->current = NULL;
+ t->d = INVALID_DIR_HANDLE;
+ t->symlink_mode = t->initial_symlink_mode;
+ archive_string_empty(&t->path);
+ t->entry_fd = -1;
+ t->entry_eof = 0;
+ t->entry_remaining_bytes = 0;
+
+ /* First item is set up a lot like a symlink traversal. */
+ tree_push(t, path, 0, 0, 0, NULL);
+ t->stack->flags = needsFirstVisit;
+ t->maxOpenCount = t->openCount = 1;
+ t->initial_dir_fd = open(".", O_RDONLY);
+ t->working_dir_fd = dup(t->initial_dir_fd);
+ return (t);
+}
+
+static int
+tree_descent(struct tree *t)
+{
+ int r = 0;
+
+#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR)
+ int new_fd;
+ t->dirname_length = archive_strlen(&t->path);
+ new_fd = openat(t->working_dir_fd, t->stack->name.s, O_RDONLY);
+ if (new_fd < 0) {
+ t->tree_errno = errno;
+ r = TREE_ERROR_DIR;
+ } else {
+ t->depth++;
+ /* If it is a link, set up fd for the ascent. */
+ if (t->stack->flags & isDirLink) {
+ t->stack->symlink_parent_fd = t->working_dir_fd;
+ t->openCount++;
+ if (t->openCount > t->maxOpenCount)
+ t->maxOpenCount = t->openCount;
+ } else
+ close(t->working_dir_fd);
+ t->working_dir_fd = new_fd;
+ }
+#else
+ /* If it is a link, set up fd for the ascent. */
+ if (t->stack->flags & isDirLink)
+ t->stack->symlink_parent_fd = t->working_dir_fd;
+ else {
+ close(t->working_dir_fd);
+ t->openCount--;
+ }
+ t->working_dir_fd = -1;
+ t->dirname_length = archive_strlen(&t->path);
+ if (chdir(t->stack->name.s) != 0)
+ {
+ t->tree_errno = errno;
+ r = TREE_ERROR_DIR;
+ } else {
+ t->depth++;
+ t->working_dir_fd = open(".", O_RDONLY);
+ t->openCount++;
+ if (t->openCount > t->maxOpenCount)
+ t->maxOpenCount = t->openCount;
+ }
+#endif
+ return (r);
+}
+
+/*
+ * We've finished a directory; ascend back to the parent.
+ */
+static int
+tree_ascend(struct tree *t)
+{
+ struct tree_entry *te;
+ int r = 0, prev_dir_fd;
+
+ te = t->stack;
+ prev_dir_fd = t->working_dir_fd;
+#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR)
+ if (te->flags & isDirLink)
+ t->working_dir_fd = te->symlink_parent_fd;
+ else {
+ int new_fd = openat(t->working_dir_fd, "..", O_RDONLY);
+ if (new_fd < 0) {
+ t->tree_errno = errno;
+ r = TREE_ERROR_FATAL;
+ } else
+ t->working_dir_fd = new_fd;
+ }
+#else
+ if (te->flags & isDirLink) {
+ if (fchdir(te->symlink_parent_fd) != 0) {
+ t->tree_errno = errno;
+ r = TREE_ERROR_FATAL;
+ } else
+ t->working_dir_fd = te->symlink_parent_fd;
+ } else {
+ if (chdir("..") != 0) {
+ t->tree_errno = errno;
+ r = TREE_ERROR_FATAL;
+ } else
+ t->working_dir_fd = open(".", O_RDONLY);
+ }
+#endif
+ if (r == 0) {
+ /* Current directory has been changed, we should
+ * close an fd of previous working directory. */
+ close_and_restore_time(prev_dir_fd, t, &te->restore_time);
+ if (te->flags & isDirLink) {
+ t->openCount--;
+ te->symlink_parent_fd = -1;
+ }
+ t->depth--;
+ }
+ return (r);
+}
+
+/*
+ * Return to the initial directory where tree_open() was performed.
+ */
+static int
+tree_enter_initial_dir(struct tree *t)
+{
+ int r = 0;
+
+ if (t->flags & onWorkingDir) {
+ r = fchdir(t->initial_dir_fd);
+ if (r == 0)
+ t->flags &= ~onWorkingDir;
+ }
+ return (r);
+}
+
+/*
+ * Restore working directory of directory traversals.
+ */
+static int
+tree_enter_working_dir(struct tree *t)
+{
+ int r = 0;
+
+ /*
+ * Change the current directory if really needed.
+ * Sometimes this is unneeded when we did not do
+ * descent.
+ */
+ if (t->depth > 0 && (t->flags & onWorkingDir) == 0) {
+ r = fchdir(t->working_dir_fd);
+ if (r == 0)
+ t->flags |= onWorkingDir;
+ }
+ return (r);
+}
+
+static int
+tree_current_dir_fd(struct tree *t)
+{
+ return (t->working_dir_fd);
+}
+
+/*
+ * Pop the working stack.
+ */
+static void
+tree_pop(struct tree *t)
+{
+ struct tree_entry *te;
+
+ t->path.s[t->dirname_length] = '\0';
+ t->path.length = t->dirname_length;
+ if (t->stack == t->current && t->current != NULL)
+ t->current = t->current->parent;
+ te = t->stack;
+ t->stack = te->next;
+ t->dirname_length = te->dirname_length;
+ t->basename = t->path.s + t->dirname_length;
+ while (t->basename[0] == '/')
+ t->basename++;
+ archive_string_free(&te->name);
+ free(te);
+}
+
+/*
+ * Get the next item in the tree traversal.
+ */
+static int
+tree_next(struct tree *t)
+{
+ int r;
+
+ while (t->stack != NULL) {
+ /* If there's an open dir, get the next entry from there. */
+ if (t->d != INVALID_DIR_HANDLE) {
+ r = tree_dir_next_posix(t);
+ if (r == 0)
+ continue;
+ return (r);
+ }
+
+ if (t->stack->flags & needsFirstVisit) {
+ /* Top stack item needs a regular visit. */
+ t->current = t->stack;
+ tree_append(t, t->stack->name.s,
+ archive_strlen(&(t->stack->name)));
+ /* t->dirname_length = t->path_length; */
+ /* tree_pop(t); */
+ t->stack->flags &= ~needsFirstVisit;
+ return (t->visit_type = TREE_REGULAR);
+ } else if (t->stack->flags & needsDescent) {
+ /* Top stack item is dir to descend into. */
+ t->current = t->stack;
+ tree_append(t, t->stack->name.s,
+ archive_strlen(&(t->stack->name)));
+ t->stack->flags &= ~needsDescent;
+ r = tree_descent(t);
+ if (r != 0) {
+ tree_pop(t);
+ t->visit_type = r;
+ } else
+ t->visit_type = TREE_POSTDESCENT;
+ return (t->visit_type);
+ } else if (t->stack->flags & needsOpen) {
+ t->stack->flags &= ~needsOpen;
+ r = tree_dir_next_posix(t);
+ if (r == 0)
+ continue;
+ return (r);
+ } else if (t->stack->flags & needsAscent) {
+ /* Top stack item is dir and we're done with it. */
+ r = tree_ascend(t);
+ tree_pop(t);
+ t->visit_type = r != 0 ? r : TREE_POSTASCENT;
+ return (t->visit_type);
+ } else {
+ /* Top item on stack is dead. */
+ tree_pop(t);
+ t->flags &= ~hasLstat;
+ t->flags &= ~hasStat;
+ }
+ }
+ return (t->visit_type = 0);
+}
+
+static int
+tree_dir_next_posix(struct tree *t)
+{
+ int r;
+ const char *name;
+ size_t namelen;
+
+ if (t->d == NULL) {
+#if defined(HAVE_READDIR_R)
+ size_t dirent_size;
+#endif
+
+#if defined(HAVE_FDOPENDIR)
+ if ((t->d = fdopendir(dup(t->working_dir_fd))) == NULL) {
+#else
+ if ((t->d = opendir(".")) == NULL) {
+#endif
+ r = tree_ascend(t); /* Undo "chdir" */
+ tree_pop(t);
+ t->tree_errno = errno;
+ t->visit_type = r != 0 ? r : TREE_ERROR_DIR;
+ return (t->visit_type);
+ }
+#if defined(HAVE_READDIR_R)
+ dirent_size = offsetof(struct dirent, d_name) +
+ t->filesystem_table[t->current->filesystem_id].name_max + 1;
+ if (t->dirent == NULL || t->dirent_allocated < dirent_size) {
+ free(t->dirent);
+ t->dirent = malloc(dirent_size);
+ if (t->dirent == NULL) {
+ closedir(t->d);
+ t->d = INVALID_DIR_HANDLE;
+ (void)tree_ascend(t);
+ tree_pop(t);
+ t->tree_errno = ENOMEM;
+ t->visit_type = TREE_ERROR_DIR;
+ return (t->visit_type);
+ }
+ t->dirent_allocated = dirent_size;
+ }
+#endif /* HAVE_READDIR_R */
+ }
+ for (;;) {
+#if defined(HAVE_READDIR_R)
+ r = readdir_r(t->d, t->dirent, &t->de);
+ if (r != 0 || t->de == NULL) {
+#else
+ errno = 0;
+ t->de = readdir(t->d);
+ if (t->de == NULL) {
+ r = errno;
+#endif
+ closedir(t->d);
+ t->d = INVALID_DIR_HANDLE;
+ if (r != 0) {
+ t->tree_errno = r;
+ t->visit_type = TREE_ERROR_DIR;
+ return (t->visit_type);
+ } else
+ return (0);
+ }
+ name = t->de->d_name;
+ namelen = D_NAMELEN(t->de);
+ t->flags &= ~hasLstat;
+ t->flags &= ~hasStat;
+ if (name[0] == '.' && name[1] == '\0')
+ continue;
+ if (name[0] == '.' && name[1] == '.' && name[2] == '\0')
+ continue;
+ tree_append(t, name, namelen);
+ return (t->visit_type = TREE_REGULAR);
+ }
+}
+
+
+/*
+ * Get the stat() data for the entry just returned from tree_next().
+ */
+static const struct stat *
+tree_current_stat(struct tree *t)
+{
+ if (!(t->flags & hasStat)) {
+#ifdef HAVE_FSTATAT
+ if (fstatat(tree_current_dir_fd(t),
+ tree_current_access_path(t), &t->st, 0) != 0)
+#else
+ if (stat(tree_current_access_path(t), &t->st) != 0)
+#endif
+ return NULL;
+ t->flags |= hasStat;
+ }
+ return (&t->st);
+}
+
+/*
+ * Get the lstat() data for the entry just returned from tree_next().
+ */
+static const struct stat *
+tree_current_lstat(struct tree *t)
+{
+ if (!(t->flags & hasLstat)) {
+#ifdef HAVE_FSTATAT
+ if (fstatat(tree_current_dir_fd(t),
+ tree_current_access_path(t), &t->lst,
+ AT_SYMLINK_NOFOLLOW) != 0)
+#else
+ if (lstat(tree_current_access_path(t), &t->lst) != 0)
+#endif
+ return NULL;
+ t->flags |= hasLstat;
+ }
+ return (&t->lst);
+}
+
+/*
+ * Test whether current entry is a dir or link to a dir.
+ */
+static int
+tree_current_is_dir(struct tree *t)
+{
+ const struct stat *st;
+ /*
+ * If we already have lstat() info, then try some
+ * cheap tests to determine if this is a dir.
+ */
+ if (t->flags & hasLstat) {
+ /* If lstat() says it's a dir, it must be a dir. */
+ if (S_ISDIR(tree_current_lstat(t)->st_mode))
+ return 1;
+ /* Not a dir; might be a link to a dir. */
+ /* If it's not a link, then it's not a link to a dir. */
+ if (!S_ISLNK(tree_current_lstat(t)->st_mode))
+ return 0;
+ /*
+ * It's a link, but we don't know what it's a link to,
+ * so we'll have to use stat().
+ */
+ }
+
+ st = tree_current_stat(t);
+ /* If we can't stat it, it's not a dir. */
+ if (st == NULL)
+ return 0;
+ /* Use the definitive test. Hopefully this is cached. */
+ return (S_ISDIR(st->st_mode));
+}
+
+/*
+ * Test whether current entry is a physical directory. Usually, we
+ * already have at least one of stat() or lstat() in memory, so we
+ * use tricks to try to avoid an extra trip to the disk.
+ */
+static int
+tree_current_is_physical_dir(struct tree *t)
+{
+ const struct stat *st;
+
+ /*
+ * If stat() says it isn't a dir, then it's not a dir.
+ * If stat() data is cached, this check is free, so do it first.
+ */
+ if ((t->flags & hasStat)
+ && (!S_ISDIR(tree_current_stat(t)->st_mode)))
+ return 0;
+
+ /*
+ * Either stat() said it was a dir (in which case, we have
+ * to determine whether it's really a link to a dir) or
+ * stat() info wasn't available. So we use lstat(), which
+ * hopefully is already cached.
+ */
+
+ st = tree_current_lstat(t);
+ /* If we can't stat it, it's not a dir. */
+ if (st == NULL)
+ return 0;
+ /* Use the definitive test. Hopefully this is cached. */
+ return (S_ISDIR(st->st_mode));
+}
+
+/*
+ * Test whether the same file has been in the tree as its parent.
+ */
+static int
+tree_target_is_same_as_parent(struct tree *t, const struct stat *st)
+{
+ struct tree_entry *te;
+
+ for (te = t->current->parent; te != NULL; te = te->parent) {
+ if (te->dev == st->st_dev && te->ino == st->st_ino)
+ return (1);
+ }
+ return (0);
+}
+
+/*
+ * Test whether the current file is symbolic link target and
+ * on the other filesystem.
+ */
+static int
+tree_current_is_symblic_link_target(struct tree *t)
+{
+ static const struct stat *lst, *st;
+
+ lst = tree_current_lstat(t);
+ st = tree_current_stat(t);
+ return (st != NULL && st->st_dev == t->current_filesystem->dev &&
+ st->st_dev != lst->st_dev);
+}
+
+/*
+ * Return the access path for the entry just returned from tree_next().
+ */
+static const char *
+tree_current_access_path(struct tree *t)
+{
+ return (t->basename);
+}
+
+/*
+ * Return the full path for the entry just returned from tree_next().
+ */
+static const char *
+tree_current_path(struct tree *t)
+{
+ return (t->path.s);
+}
+
+/*
+ * Terminate the traversal.
+ */
+static void
+tree_close(struct tree *t)
+{
+
+ if (t == NULL)
+ return;
+ if (t->entry_fd >= 0) {
+ close_and_restore_time(t->entry_fd, t, &t->restore_time);
+ t->entry_fd = -1;
+ }
+ /* Close the handle of readdir(). */
+ if (t->d != INVALID_DIR_HANDLE) {
+ closedir(t->d);
+ t->d = INVALID_DIR_HANDLE;
+ }
+ /* Release anything remaining in the stack. */
+ while (t->stack != NULL) {
+ if (t->stack->flags & isDirLink)
+ close(t->stack->symlink_parent_fd);
+ tree_pop(t);
+ }
+ if (t->working_dir_fd >= 0) {
+ close(t->working_dir_fd);
+ t->working_dir_fd = -1;
+ }
+ if (t->initial_dir_fd >= 0) {
+ close(t->initial_dir_fd);
+ t->initial_dir_fd = -1;
+ }
+}
+
+/*
+ * Release any resources.
+ */
+static void
+tree_free(struct tree *t)
+{
+ int i;
+
+ if (t == NULL)
+ return;
+ archive_string_free(&t->path);
+#if defined(HAVE_READDIR_R)
+ free(t->dirent);
+#endif
+ free(t->sparse_list);
+ for (i = 0; i < t->max_filesystem_id; i++)
+ free(t->filesystem_table[i].allocation_ptr);
+ free(t->filesystem_table);
+ free(t);
+}
+
+#endif
diff --git a/libarchive/archive_read_disk_private.h b/libarchive/archive_read_disk_private.h
index b674b7106d73..4446474ebeaf 100644
--- a/libarchive/archive_read_disk_private.h
+++ b/libarchive/archive_read_disk_private.h
@@ -33,6 +33,8 @@
#ifndef ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED
#define ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED
+struct tree;
+
struct archive_read_disk {
struct archive archive;
@@ -51,10 +53,17 @@ struct archive_read_disk {
*/
char follow_symlinks; /* Either 'L' or 'P'. */
- const char * (*lookup_gname)(void *private, gid_t gid);
+ /* Directory traversals. */
+ struct tree *tree;
+
+ /* Set 1 if users request to restore atime . */
+ int restore_time;
+ int entry_wd_fd;
+
+ const char * (*lookup_gname)(void *private, int64_t gid);
void (*cleanup_gname)(void *private);
void *lookup_gname_data;
- const char * (*lookup_uname)(void *private, gid_t gid);
+ const char * (*lookup_uname)(void *private, int64_t uid);
void (*cleanup_uname)(void *private);
void *lookup_uname_data;
};
diff --git a/libarchive/archive_read_disk_set_standard_lookup.c b/libarchive/archive_read_disk_set_standard_lookup.c
index 97a568e057af..3bc52c70dbcb 100644
--- a/libarchive/archive_read_disk_set_standard_lookup.c
+++ b/libarchive/archive_read_disk_set_standard_lookup.c
@@ -72,8 +72,8 @@ struct name_cache {
} cache[name_cache_size];
};
-static const char * lookup_gname(void *, gid_t);
-static const char * lookup_uname(void *, uid_t);
+static const char * lookup_gname(void *, int64_t);
+static const char * lookup_uname(void *, int64_t);
static void cleanup(void *);
static const char * lookup_gname_helper(struct name_cache *, id_t gid);
static const char * lookup_uname_helper(struct name_cache *, id_t uid);
@@ -175,7 +175,7 @@ lookup_name(struct name_cache *cache,
}
static const char *
-lookup_uname(void *data, uid_t uid)
+lookup_uname(void *data, int64_t uid)
{
struct name_cache *uname_cache = (struct name_cache *)data;
return (lookup_name(uname_cache,
@@ -187,6 +187,8 @@ static const char *
lookup_uname_helper(struct name_cache *cache, id_t id)
{
struct passwd pwent, *result;
+ char * nbuff;
+ size_t nbuff_size;
int r;
if (cache->buff_size == 0) {
@@ -208,10 +210,12 @@ lookup_uname_helper(struct name_cache *cache, id_t id)
* we just double it and try again. Because the buffer
* is kept around in the cache object, we shouldn't
* have to do this very often. */
- cache->buff_size *= 2;
- cache->buff = realloc(cache->buff, cache->buff_size);
- if (cache->buff == NULL)
+ nbuff_size = cache->buff_size * 2;
+ nbuff = realloc(cache->buff, nbuff_size);
+ if (nbuff == NULL)
break;
+ cache->buff = nbuff;
+ cache->buff_size = nbuff_size;
}
if (r != 0) {
archive_set_error(cache->archive, errno,
@@ -239,7 +243,7 @@ lookup_uname_helper(struct name_cache *cache, id_t id)
#endif
static const char *
-lookup_gname(void *data, gid_t gid)
+lookup_gname(void *data, int64_t gid)
{
struct name_cache *gname_cache = (struct name_cache *)data;
return (lookup_name(gname_cache,
@@ -251,6 +255,8 @@ static const char *
lookup_gname_helper(struct name_cache *cache, id_t id)
{
struct group grent, *result;
+ char * nbuff;
+ size_t nbuff_size;
int r;
if (cache->buff_size == 0) {
@@ -270,10 +276,12 @@ lookup_gname_helper(struct name_cache *cache, id_t id)
/* ERANGE means our buffer was too small, but POSIX
* doesn't tell us how big the buffer should be, so
* we just double it and try again. */
- cache->buff_size *= 2;
- cache->buff = realloc(cache->buff, cache->buff_size);
- if (cache->buff == NULL)
+ nbuff_size = cache->buff_size * 2;
+ nbuff = realloc(cache->buff, nbuff_size);
+ if (nbuff == NULL)
break;
+ cache->buff = nbuff;
+ cache->buff_size = nbuff_size;
}
if (r != 0) {
archive_set_error(cache->archive, errno,
diff --git a/libarchive/archive_read_disk_windows.c b/libarchive/archive_read_disk_windows.c
new file mode 100644
index 000000000000..d8a1f5577b18
--- /dev/null
+++ b/libarchive/archive_read_disk_windows.c
@@ -0,0 +1,1983 @@
+/*-
+ * Copyright (c) 2003-2009 Tim Kientzle
+ * Copyright (c) 2010-2011 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "archive_platform.h"
+__FBSDID("$FreeBSD$");
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_MOUNT_H
+#include <sys/mount.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_STATVFS_H
+#include <sys/statvfs.h>
+#endif
+#ifdef HAVE_SYS_VFS_H
+#include <sys/vfs.h>
+#endif
+#ifdef HAVE_LINUX_MAGIC_H
+#include <linux/magic.h>
+#endif
+#ifdef HAVE_DIRECT_H
+#include <direct.h>
+#endif
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if defined(HAVE_WINIOCTL_H) && !defined(__CYGWIN__)
+#include <winioctl.h>
+#endif
+
+#include "archive.h"
+#include "archive_string.h"
+#include "archive_entry.h"
+#include "archive_private.h"
+#include "archive_read_disk_private.h"
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+#ifndef IO_REPARSE_TAG_SYMLINK
+/* Old SDKs do not provide IO_REPARSE_TAG_SYMLINK */
+#define IO_REPARSE_TAG_SYMLINK 0xA000000CL
+#endif
+
+static BOOL SetFilePointerEx_perso(HANDLE hFile,
+ LARGE_INTEGER liDistanceToMove,
+ PLARGE_INTEGER lpNewFilePointer,
+ DWORD dwMoveMethod)
+{
+ LARGE_INTEGER li;
+ li.QuadPart = liDistanceToMove.QuadPart;
+ li.LowPart = SetFilePointer(
+ hFile, li.LowPart, &li.HighPart, dwMoveMethod);
+ if(lpNewFilePointer) {
+ lpNewFilePointer->QuadPart = li.QuadPart;
+ }
+ return li.LowPart != -1 || GetLastError() == NO_ERROR;
+}
+
+/*-
+ * This is a new directory-walking system that addresses a number
+ * of problems I've had with fts(3). In particular, it has no
+ * pathname-length limits (other than the size of 'int'), handles
+ * deep logical traversals, uses considerably less memory, and has
+ * an opaque interface (easier to modify in the future).
+ *
+ * Internally, it keeps a single list of "tree_entry" items that
+ * represent filesystem objects that require further attention.
+ * Non-directories are not kept in memory: they are pulled from
+ * readdir(), returned to the client, then freed as soon as possible.
+ * Any directory entry to be traversed gets pushed onto the stack.
+ *
+ * There is surprisingly little information that needs to be kept for
+ * each item on the stack. Just the name, depth (represented here as the
+ * string length of the parent directory's pathname), and some markers
+ * indicating how to get back to the parent (via chdir("..") for a
+ * regular dir or via fchdir(2) for a symlink).
+ */
+/*
+ * TODO:
+ * 1) Loop checking.
+ * 3) Arbitrary logical traversals by closing/reopening intermediate fds.
+ */
+
+struct restore_time {
+ const wchar_t *full_path;
+ FILETIME lastWriteTime;
+ FILETIME lastAccessTime;
+ mode_t filetype;
+};
+
+struct tree_entry {
+ int depth;
+ struct tree_entry *next;
+ struct tree_entry *parent;
+ size_t full_path_dir_length;
+ struct archive_wstring name;
+ struct archive_wstring full_path;
+ size_t dirname_length;
+ int64_t dev;
+ int64_t ino;
+ int flags;
+ int filesystem_id;
+ /* How to restore time of a directory. */
+ struct restore_time restore_time;
+};
+
+struct filesystem {
+ int64_t dev;
+ int synthetic;
+ int remote;
+};
+
+/* Definitions for tree_entry.flags bitmap. */
+#define isDir 1 /* This entry is a regular directory. */
+#define isDirLink 2 /* This entry is a symbolic link to a directory. */
+#define needsFirstVisit 4 /* This is an initial entry. */
+#define needsDescent 8 /* This entry needs to be previsited. */
+#define needsOpen 16 /* This is a directory that needs to be opened. */
+#define needsAscent 32 /* This entry needs to be postvisited. */
+
+/*
+ * On Windows, "first visit" is handled as a pattern to be handed to
+ * _findfirst(). This is consistent with Windows conventions that
+ * file patterns are handled within the application. On Posix,
+ * "first visit" is just returned to the client.
+ */
+
+/*
+ * Local data for this package.
+ */
+struct tree {
+ struct tree_entry *stack;
+ struct tree_entry *current;
+ HANDLE d;
+#define INVALID_DIR_HANDLE INVALID_HANDLE_VALUE
+ WIN32_FIND_DATAW _findData;
+ WIN32_FIND_DATAW *findData;
+ int flags;
+ int visit_type;
+ /* Error code from last failed operation. */
+ int tree_errno;
+
+ /* A full path with "\\?\" prefix. */
+ struct archive_wstring full_path;
+ size_t full_path_dir_length;
+ /* Dynamically-sized buffer for holding path */
+ struct archive_wstring path;
+
+ /* Last path element */
+ const wchar_t *basename;
+ /* Leading dir length */
+ size_t dirname_length;
+
+ int depth;
+
+ BY_HANDLE_FILE_INFORMATION lst;
+ BY_HANDLE_FILE_INFORMATION st;
+ int descend;
+ /* How to restore time of a file. */
+ struct restore_time restore_time;
+
+ struct entry_sparse {
+ int64_t length;
+ int64_t offset;
+ } *sparse_list, *current_sparse;
+ int sparse_count;
+ int sparse_list_size;
+
+ char initial_symlink_mode;
+ char symlink_mode;
+ struct filesystem *current_filesystem;
+ struct filesystem *filesystem_table;
+ int current_filesystem_id;
+ int max_filesystem_id;
+ int allocated_filesytem;
+
+ HANDLE entry_fh;
+ int entry_eof;
+ int64_t entry_remaining_bytes;
+ int64_t entry_total;
+ unsigned char *entry_buff;
+ size_t entry_buff_size;
+};
+
+#define bhfi_dev(bhfi) ((bhfi)->dwVolumeSerialNumber)
+/* Treat FileIndex as i-node. We should remove a sequence number
+ * which is high-16-bits of nFileIndexHigh. */
+#define bhfi_ino(bhfi) \
+ ((((int64_t)((bhfi)->nFileIndexHigh & 0x0000FFFFUL)) << 32) \
+ + (bhfi)->nFileIndexLow)
+
+/* Definitions for tree.flags bitmap. */
+#define hasStat 16 /* The st entry is valid. */
+#define hasLstat 32 /* The lst entry is valid. */
+#define needsRestoreTimes 128
+
+static int
+tree_dir_next_windows(struct tree *t, const wchar_t *pattern);
+
+#ifdef HAVE_DIRENT_D_NAMLEN
+/* BSD extension; avoids need for a strlen() call. */
+#define D_NAMELEN(dp) (dp)->d_namlen
+#else
+#define D_NAMELEN(dp) (strlen((dp)->d_name))
+#endif
+
+/* Initiate/terminate a tree traversal. */
+static struct tree *tree_open(const wchar_t *, int, int);
+static struct tree *tree_reopen(struct tree *, const wchar_t *, int);
+static void tree_close(struct tree *);
+static void tree_free(struct tree *);
+static void tree_push(struct tree *, const wchar_t *, const wchar_t *,
+ int, int64_t, int64_t, struct restore_time *);
+
+/*
+ * tree_next() returns Zero if there is no next entry, non-zero if
+ * there is. Note that directories are visited three times.
+ * Directories are always visited first as part of enumerating their
+ * parent; that is a "regular" visit. If tree_descend() is invoked at
+ * that time, the directory is added to a work list and will
+ * subsequently be visited two more times: once just after descending
+ * into the directory ("postdescent") and again just after ascending
+ * back to the parent ("postascent").
+ *
+ * TREE_ERROR_DIR is returned if the descent failed (because the
+ * directory couldn't be opened, for instance). This is returned
+ * instead of TREE_POSTDESCENT/TREE_POSTASCENT. TREE_ERROR_DIR is not a
+ * fatal error, but it does imply that the relevant subtree won't be
+ * visited. TREE_ERROR_FATAL is returned for an error that left the
+ * traversal completely hosed. Right now, this is only returned for
+ * chdir() failures during ascent.
+ */
+#define TREE_REGULAR 1
+#define TREE_POSTDESCENT 2
+#define TREE_POSTASCENT 3
+#define TREE_ERROR_DIR -1
+#define TREE_ERROR_FATAL -2
+
+static int tree_next(struct tree *);
+
+/*
+ * Return information about the current entry.
+ */
+
+/*
+ * The current full pathname, length of the full pathname, and a name
+ * that can be used to access the file. Because tree does use chdir
+ * extensively, the access path is almost never the same as the full
+ * current path.
+ *
+ */
+static const wchar_t *tree_current_path(struct tree *);
+static const wchar_t *tree_current_access_path(struct tree *);
+
+/*
+ * Request the lstat() or stat() data for the current path. Since the
+ * tree package needs to do some of this anyway, and caches the
+ * results, you should take advantage of it here if you need it rather
+ * than make a redundant stat() or lstat() call of your own.
+ */
+static const BY_HANDLE_FILE_INFORMATION *tree_current_stat(struct tree *);
+static const BY_HANDLE_FILE_INFORMATION *tree_current_lstat(struct tree *);
+
+/* The following functions use tricks to avoid a certain number of
+ * stat()/lstat() calls. */
+/* "is_physical_dir" is equivalent to S_ISDIR(tree_current_lstat()->st_mode) */
+static int tree_current_is_physical_dir(struct tree *);
+/* "is_physical_link" is equivalent to S_ISLNK(tree_current_lstat()->st_mode) */
+static int tree_current_is_physical_link(struct tree *);
+/* Instead of archive_entry_copy_stat for BY_HANDLE_FILE_INFORMATION */
+static void tree_archive_entry_copy_bhfi(struct archive_entry *,
+ struct tree *, const BY_HANDLE_FILE_INFORMATION *);
+/* "is_dir" is equivalent to S_ISDIR(tree_current_stat()->st_mode) */
+static int tree_current_is_dir(struct tree *);
+static int update_current_filesystem(struct archive_read_disk *a,
+ int64_t dev);
+static int setup_current_filesystem(struct archive_read_disk *);
+static int tree_target_is_same_as_parent(struct tree *,
+ const BY_HANDLE_FILE_INFORMATION *);
+
+static int _archive_read_disk_open_w(struct archive *, const wchar_t *);
+static int _archive_read_free(struct archive *);
+static int _archive_read_close(struct archive *);
+static int _archive_read_data_block(struct archive *,
+ const void **, size_t *, int64_t *);
+static int _archive_read_next_header2(struct archive *,
+ struct archive_entry *);
+static const char *trivial_lookup_gname(void *, int64_t gid);
+static const char *trivial_lookup_uname(void *, int64_t uid);
+static int setup_sparse(struct archive_read_disk *, struct archive_entry *);
+static int close_and_restore_time(HANDLE, struct tree *,
+ struct restore_time *);
+static int setup_sparse_from_disk(struct archive_read_disk *,
+ struct archive_entry *, HANDLE);
+
+
+
+static struct archive_vtable *
+archive_read_disk_vtable(void)
+{
+ static struct archive_vtable av;
+ static int inited = 0;
+
+ if (!inited) {
+ av.archive_free = _archive_read_free;
+ av.archive_close = _archive_read_close;
+ av.archive_read_data_block = _archive_read_data_block;
+ av.archive_read_next_header2 = _archive_read_next_header2;
+ inited = 1;
+ }
+ return (&av);
+}
+
+const char *
+archive_read_disk_gname(struct archive *_a, int64_t gid)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_gname"))
+ return (NULL);
+ if (a->lookup_gname == NULL)
+ return (NULL);
+ return ((*a->lookup_gname)(a->lookup_gname_data, gid));
+}
+
+const char *
+archive_read_disk_uname(struct archive *_a, int64_t uid)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_uname"))
+ return (NULL);
+ if (a->lookup_uname == NULL)
+ return (NULL);
+ return ((*a->lookup_uname)(a->lookup_uname_data, uid));
+}
+
+int
+archive_read_disk_set_gname_lookup(struct archive *_a,
+ void *private_data,
+ const char * (*lookup_gname)(void *private, int64_t gid),
+ void (*cleanup_gname)(void *private))
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_set_gname_lookup");
+
+ if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL)
+ (a->cleanup_gname)(a->lookup_gname_data);
+
+ a->lookup_gname = lookup_gname;
+ a->cleanup_gname = cleanup_gname;
+ a->lookup_gname_data = private_data;
+ return (ARCHIVE_OK);
+}
+
+int
+archive_read_disk_set_uname_lookup(struct archive *_a,
+ void *private_data,
+ const char * (*lookup_uname)(void *private, int64_t uid),
+ void (*cleanup_uname)(void *private))
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_set_uname_lookup");
+
+ if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL)
+ (a->cleanup_uname)(a->lookup_uname_data);
+
+ a->lookup_uname = lookup_uname;
+ a->cleanup_uname = cleanup_uname;
+ a->lookup_uname_data = private_data;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Create a new archive_read_disk object and initialize it with global state.
+ */
+struct archive *
+archive_read_disk_new(void)
+{
+ struct archive_read_disk *a;
+
+ a = (struct archive_read_disk *)malloc(sizeof(*a));
+ if (a == NULL)
+ return (NULL);
+ memset(a, 0, sizeof(*a));
+ a->archive.magic = ARCHIVE_READ_DISK_MAGIC;
+ a->archive.state = ARCHIVE_STATE_NEW;
+ a->archive.vtable = archive_read_disk_vtable();
+ a->lookup_uname = trivial_lookup_uname;
+ a->lookup_gname = trivial_lookup_gname;
+ a->entry_wd_fd = -1;
+ return (&a->archive);
+}
+
+static int
+_archive_read_free(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ int r;
+
+ if (_a == NULL)
+ return (ARCHIVE_OK);
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_free");
+
+ if (a->archive.state != ARCHIVE_STATE_CLOSED)
+ r = _archive_read_close(&a->archive);
+ else
+ r = ARCHIVE_OK;
+
+ tree_free(a->tree);
+ if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL)
+ (a->cleanup_gname)(a->lookup_gname_data);
+ if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL)
+ (a->cleanup_uname)(a->lookup_uname_data);
+ archive_string_free(&a->archive.error_string);
+ a->archive.magic = 0;
+ free(a);
+ return (r);
+}
+
+static int
+_archive_read_close(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_close");
+
+ if (a->archive.state != ARCHIVE_STATE_FATAL)
+ a->archive.state = ARCHIVE_STATE_CLOSED;
+
+ tree_close(a->tree);
+
+ return (ARCHIVE_OK);
+}
+
+static void
+setup_symlink_mode(struct archive_read_disk *a, char symlink_mode,
+ int follow_symlinks)
+{
+ a->symlink_mode = symlink_mode;
+ a->follow_symlinks = follow_symlinks;
+ if (a->tree != NULL) {
+ a->tree->initial_symlink_mode = a->symlink_mode;
+ a->tree->symlink_mode = a->symlink_mode;
+ }
+}
+
+int
+archive_read_disk_set_symlink_logical(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_logical");
+ setup_symlink_mode(a, 'L', 1);
+ return (ARCHIVE_OK);
+}
+
+int
+archive_read_disk_set_symlink_physical(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_physical");
+ setup_symlink_mode(a, 'P', 0);
+ return (ARCHIVE_OK);
+}
+
+int
+archive_read_disk_set_symlink_hybrid(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_hybrid");
+ setup_symlink_mode(a, 'H', 1);/* Follow symlinks initially. */
+ return (ARCHIVE_OK);
+}
+
+int
+archive_read_disk_set_atime_restored(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_restore_atime");
+ a->restore_time = 1;
+ if (a->tree != NULL)
+ a->tree->flags |= needsRestoreTimes;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Trivial implementations of gname/uname lookup functions.
+ * These are normally overridden by the client, but these stub
+ * versions ensure that we always have something that works.
+ */
+static const char *
+trivial_lookup_gname(void *private_data, int64_t gid)
+{
+ (void)private_data; /* UNUSED */
+ (void)gid; /* UNUSED */
+ return (NULL);
+}
+
+static const char *
+trivial_lookup_uname(void *private_data, int64_t uid)
+{
+ (void)private_data; /* UNUSED */
+ (void)uid; /* UNUSED */
+ return (NULL);
+}
+
+static int
+_archive_read_data_block(struct archive *_a, const void **buff,
+ size_t *size, int64_t *offset)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ struct tree *t = a->tree;
+ int r;
+ int64_t bytes;
+ size_t buffbytes;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
+ "archive_read_data_block");
+
+ if (t->entry_eof || t->entry_remaining_bytes <= 0) {
+ r = ARCHIVE_EOF;
+ goto abort_read_data;
+ }
+
+ /* Allocate read buffer. */
+ if (t->entry_buff == NULL) {
+ t->entry_buff = malloc(1024 * 64);
+ if (t->entry_buff == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Couldn't allocate memory");
+ r = ARCHIVE_FATAL;
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ goto abort_read_data;
+ }
+ t->entry_buff_size = 1024 * 64;
+ }
+
+ buffbytes = t->entry_buff_size;
+ if (buffbytes > t->current_sparse->length)
+ buffbytes = t->current_sparse->length;
+
+ /*
+ * Skip hole.
+ */
+ if (t->current_sparse->offset > t->entry_total) {
+ LARGE_INTEGER distance;
+ distance.QuadPart = t->current_sparse->offset;
+ if (!SetFilePointerEx_perso(t->entry_fh, distance, NULL, FILE_BEGIN)) {
+ DWORD lasterr;
+
+ lasterr = GetLastError();
+ if (lasterr == ERROR_ACCESS_DENIED)
+ errno = EBADF;
+ else
+ la_dosmaperr(lasterr);
+ archive_set_error(&a->archive, errno, "Seek error");
+ r = ARCHIVE_FATAL;
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ goto abort_read_data;
+ }
+ bytes = t->current_sparse->offset - t->entry_total;
+ t->entry_remaining_bytes -= bytes;
+ t->entry_total += bytes;
+ }
+ if (buffbytes > 0) {
+ DWORD bytes_read;
+ if (!ReadFile(t->entry_fh, t->entry_buff,
+ (uint32_t)buffbytes, &bytes_read, NULL)) {
+ DWORD lasterr;
+
+ lasterr = GetLastError();
+ if (lasterr == ERROR_NO_DATA)
+ errno = EAGAIN;
+ else if (lasterr == ERROR_ACCESS_DENIED)
+ errno = EBADF;
+ else
+ la_dosmaperr(lasterr);
+ archive_set_error(&a->archive, errno, "Read error");
+ r = ARCHIVE_FATAL;
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ goto abort_read_data;
+ }
+ bytes = bytes_read;
+ } else
+ bytes = 0;
+ if (bytes == 0) {
+ /* Get EOF */
+ t->entry_eof = 1;
+ r = ARCHIVE_EOF;
+ goto abort_read_data;
+ }
+ *buff = t->entry_buff;
+ *size = bytes;
+ *offset = t->entry_total;
+ t->entry_total += bytes;
+ t->entry_remaining_bytes -= bytes;
+ if (t->entry_remaining_bytes == 0) {
+ /* Close the current file descriptor */
+ close_and_restore_time(t->entry_fh, t, &t->restore_time);
+ t->entry_fh = INVALID_HANDLE_VALUE;
+ t->entry_eof = 1;
+ }
+ t->current_sparse->offset += bytes;
+ t->current_sparse->length -= bytes;
+ if (t->current_sparse->length == 0 && !t->entry_eof)
+ t->current_sparse++;
+ return (ARCHIVE_OK);
+
+abort_read_data:
+ *buff = NULL;
+ *size = 0;
+ *offset = t->entry_total;
+ if (t->entry_fh != INVALID_HANDLE_VALUE) {
+ /* Close the current file descriptor */
+ close_and_restore_time(t->entry_fh, t, &t->restore_time);
+ t->entry_fh = INVALID_HANDLE_VALUE;
+ }
+ return (r);
+}
+
+static int
+_archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ struct tree *t;
+ const BY_HANDLE_FILE_INFORMATION *st;
+ const BY_HANDLE_FILE_INFORMATION *lst;
+ const char*name;
+ int descend, r;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
+ "archive_read_next_header2");
+
+ t = a->tree;
+ if (t->entry_fh != INVALID_HANDLE_VALUE) {
+ close_and_restore_time(t->entry_fh, t, &t->restore_time);
+ t->entry_fh = INVALID_HANDLE_VALUE;
+ }
+ st = NULL;
+ lst = NULL;
+ do {
+ switch (tree_next(t)) {
+ case TREE_ERROR_FATAL:
+ archive_set_error(&a->archive, t->tree_errno,
+ "%ls: Unable to continue traversing directory tree",
+ tree_current_path(t));
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+ case TREE_ERROR_DIR:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "%ls: Couldn't visit directory",
+ tree_current_path(t));
+ return (ARCHIVE_FAILED);
+ case 0:
+ return (ARCHIVE_EOF);
+ case TREE_POSTDESCENT:
+ case TREE_POSTASCENT:
+ break;
+ case TREE_REGULAR:
+ lst = tree_current_lstat(t);
+ if (lst == NULL) {
+ archive_set_error(&a->archive, errno,
+ "%ls: Cannot stat",
+ tree_current_path(t));
+ return (ARCHIVE_FAILED);
+ }
+ break;
+ }
+ } while (lst == NULL);
+
+ /*
+ * Distinguish 'L'/'P'/'H' symlink following.
+ */
+ switch(t->symlink_mode) {
+ case 'H':
+ /* 'H': After the first item, rest like 'P'. */
+ t->symlink_mode = 'P';
+ /* 'H': First item (from command line) like 'L'. */
+ /* FALLTHROUGH */
+ case 'L':
+ /* 'L': Do descend through a symlink to dir. */
+ descend = tree_current_is_dir(t);
+ /* 'L': Follow symlinks to files. */
+ a->symlink_mode = 'L';
+ a->follow_symlinks = 1;
+ /* 'L': Archive symlinks as targets, if we can. */
+ st = tree_current_stat(t);
+ if (st != NULL && !tree_target_is_same_as_parent(t, st))
+ break;
+ /* If stat fails, we have a broken symlink;
+ * in that case, don't follow the link. */
+ /* FALLTHROUGH */
+ default:
+ /* 'P': Don't descend through a symlink to dir. */
+ descend = tree_current_is_physical_dir(t);
+ /* 'P': Don't follow symlinks to files. */
+ a->symlink_mode = 'P';
+ a->follow_symlinks = 0;
+ /* 'P': Archive symlinks as symlinks. */
+ st = lst;
+ break;
+ }
+
+ if (update_current_filesystem(a, bhfi_dev(st)) != ARCHIVE_OK) {
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+ }
+ t->descend = descend;
+
+ archive_entry_copy_pathname_w(entry, tree_current_path(t));
+ archive_entry_copy_sourcepath_w(entry, tree_current_access_path(t));
+ tree_archive_entry_copy_bhfi(entry, t, st);
+
+ /* Save the times to be restored. */
+ t->restore_time.lastWriteTime = st->ftLastWriteTime;
+ t->restore_time.lastAccessTime = st->ftLastAccessTime;
+ t->restore_time.filetype = archive_entry_filetype(entry);
+
+ /* Lookup uname/gname */
+ name = archive_read_disk_uname(_a, archive_entry_uid(entry));
+ if (name != NULL)
+ archive_entry_copy_uname(entry, name);
+ name = archive_read_disk_gname(_a, archive_entry_gid(entry));
+ if (name != NULL)
+ archive_entry_copy_gname(entry, name);
+
+ r = ARCHIVE_OK;
+ if (archive_entry_filetype(entry) == AE_IFREG &&
+ archive_entry_size(entry) > 0) {
+ t->entry_fh = CreateFileW(tree_current_access_path(t),
+ GENERIC_READ, 0, NULL, OPEN_EXISTING,
+ FILE_FLAG_SEQUENTIAL_SCAN, NULL);
+ if (t->entry_fh == INVALID_HANDLE_VALUE) {
+ archive_set_error(&a->archive, errno,
+ "Couldn't open %ls", tree_current_path(a->tree));
+ return (ARCHIVE_FAILED);
+ }
+
+ /* Find sparse data from the disk. */
+ if (archive_entry_hardlink(entry) == NULL &&
+ (st->dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) != 0)
+ r = setup_sparse_from_disk(a, entry, t->entry_fh);
+ }
+
+ /*
+ * EOF and FATAL are persistent at this layer. By
+ * modifying the state, we guarantee that future calls to
+ * read a header or read data will fail.
+ */
+ switch (r) {
+ case ARCHIVE_EOF:
+ a->archive.state = ARCHIVE_STATE_EOF;
+ break;
+ case ARCHIVE_OK:
+ case ARCHIVE_WARN:
+ t->entry_total = 0;
+ if (archive_entry_filetype(entry) == AE_IFREG) {
+ t->entry_remaining_bytes = archive_entry_size(entry);
+ t->entry_eof = (t->entry_remaining_bytes == 0)? 1: 0;
+ if (!t->entry_eof &&
+ setup_sparse(a, entry) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ } else {
+ t->entry_remaining_bytes = 0;
+ t->entry_eof = 1;
+ }
+ a->archive.state = ARCHIVE_STATE_DATA;
+ break;
+ case ARCHIVE_RETRY:
+ break;
+ case ARCHIVE_FATAL:
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ break;
+ }
+
+ return (r);
+}
+
+static int
+setup_sparse(struct archive_read_disk *a, struct archive_entry *entry)
+{
+ struct tree *t = a->tree;
+ int64_t length, offset;
+ int i;
+
+ t->sparse_count = archive_entry_sparse_reset(entry);
+ if (t->sparse_count+1 > t->sparse_list_size) {
+ free(t->sparse_list);
+ t->sparse_list_size = t->sparse_count + 1;
+ t->sparse_list = malloc(sizeof(t->sparse_list[0]) *
+ t->sparse_list_size);
+ if (t->sparse_list == NULL) {
+ t->sparse_list_size = 0;
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate data");
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+ }
+ }
+ for (i = 0; i < t->sparse_count; i++) {
+ archive_entry_sparse_next(entry, &offset, &length);
+ t->sparse_list[i].offset = offset;
+ t->sparse_list[i].length = length;
+ }
+ if (i == 0) {
+ t->sparse_list[i].offset = 0;
+ t->sparse_list[i].length = archive_entry_size(entry);
+ } else {
+ t->sparse_list[i].offset = archive_entry_size(entry);
+ t->sparse_list[i].length = 0;
+ }
+ t->current_sparse = t->sparse_list;
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Called by the client to mark the directory just returned from
+ * tree_next() as needing to be visited.
+ */
+int
+archive_read_disk_descend(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ struct tree *t = a->tree;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
+ "archive_read_disk_descend");
+
+ if (t->visit_type != TREE_REGULAR || !t->descend) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Ignored the request descending the current object");
+ return (ARCHIVE_WARN);
+ }
+
+ if (tree_current_is_physical_dir(t)) {
+ tree_push(t, t->basename, t->full_path.s,
+ t->current_filesystem_id,
+ bhfi_dev(&(t->lst)), bhfi_ino(&(t->lst)),
+ &t->restore_time);
+ t->stack->flags |= isDir;
+ } else if (tree_current_is_dir(t)) {
+ tree_push(t, t->basename, t->full_path.s,
+ t->current_filesystem_id,
+ bhfi_dev(&(t->st)), bhfi_ino(&(t->st)),
+ &t->restore_time);
+ t->stack->flags |= isDirLink;
+ }
+ t->descend = 0;
+ return (ARCHIVE_OK);
+}
+
+int
+archive_read_disk_open(struct archive *_a, const char *pathname)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ struct archive_wstring wpath;
+ int ret;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_NEW | ARCHIVE_STATE_CLOSED,
+ "archive_read_disk_open");
+ archive_clear_error(&a->archive);
+
+ /* Make a wchar_t string from a char string. */
+ archive_string_init(&wpath);
+ if (archive_wstring_append_from_mbs(&wpath, pathname,
+ strlen(pathname)) != 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Can't convert a path to a wchar_t string");
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ ret = ARCHIVE_FATAL;
+ } else
+ ret = _archive_read_disk_open_w(_a, wpath.s);
+
+ archive_wstring_free(&wpath);
+ return (ret);
+}
+
+int
+archive_read_disk_open_w(struct archive *_a, const wchar_t *pathname)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_NEW | ARCHIVE_STATE_CLOSED,
+ "archive_read_disk_open_w");
+ archive_clear_error(&a->archive);
+
+ return (_archive_read_disk_open_w(_a, pathname));
+}
+
+static int
+_archive_read_disk_open_w(struct archive *_a, const wchar_t *pathname)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+
+ if (a->tree != NULL)
+ a->tree = tree_reopen(a->tree, pathname, a->restore_time);
+ else
+ a->tree = tree_open(pathname, a->symlink_mode, a->restore_time);
+ if (a->tree == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate direcotry traversal data");
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+ }
+ a->archive.state = ARCHIVE_STATE_HEADER;
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Return a current filesystem ID which is index of the filesystem entry
+ * you've visited through archive_read_disk.
+ */
+int
+archive_read_disk_current_filesystem(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
+ "archive_read_disk_current_filesystem");
+
+ return (a->tree->current_filesystem_id);
+}
+
+static int
+update_current_filesystem(struct archive_read_disk *a, int64_t dev)
+{
+ struct tree *t = a->tree;
+ int i, fid;
+
+ if (t->current_filesystem != NULL &&
+ t->current_filesystem->dev == dev)
+ return (ARCHIVE_OK);
+
+ for (i = 0; i < t->max_filesystem_id; i++) {
+ if (t->filesystem_table[i].dev == dev) {
+ /* There is the filesytem ID we've already generated. */
+ t->current_filesystem_id = i;
+ t->current_filesystem = &(t->filesystem_table[i]);
+ return (ARCHIVE_OK);
+ }
+ }
+
+ /*
+ * There is a new filesytem, we generate a new ID for.
+ */
+ fid = t->max_filesystem_id++;
+ if (t->max_filesystem_id > t->allocated_filesytem) {
+ size_t s;
+
+ s = t->max_filesystem_id * 2;
+ t->filesystem_table = realloc(t->filesystem_table,
+ s * sizeof(*t->filesystem_table));
+ if (t->filesystem_table == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate tar data");
+ return (ARCHIVE_FATAL);
+ }
+ t->allocated_filesytem = s;
+ }
+ t->current_filesystem_id = fid;
+ t->current_filesystem = &(t->filesystem_table[fid]);
+ t->current_filesystem->dev = dev;
+
+ return (setup_current_filesystem(a));
+}
+
+/*
+ * Returns 1 if current filesystem is generated filesystem, 0 if it is not
+ * or -1 if it is unknown.
+ */
+int
+archive_read_disk_current_filesystem_is_synthetic(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
+ "archive_read_disk_current_filesystem");
+
+ return (a->tree->current_filesystem->synthetic);
+}
+
+/*
+ * Returns 1 if current filesystem is remote filesystem, 0 if it is not
+ * or -1 if it is unknown.
+ */
+int
+archive_read_disk_current_filesystem_is_remote(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
+ "archive_read_disk_current_filesystem");
+
+ return (a->tree->current_filesystem->remote);
+}
+
+/*
+ * If symlink is broken, statfs or statvfs will fail.
+ * Use its directory path instead.
+ */
+static wchar_t *
+safe_path_for_statfs(struct tree *t)
+{
+ const wchar_t *path;
+ wchar_t *cp, *p = NULL;
+
+ path = tree_current_access_path(t);
+ if (tree_current_stat(t) == NULL) {
+ p = _wcsdup(path);
+ cp = wcsrchr(p, '/');
+ if (cp != NULL && wcslen(cp) >= 2) {
+ cp[1] = '.';
+ cp[2] = '\0';
+ path = p;
+ }
+ } else
+ p = _wcsdup(path);
+ return (p);
+}
+
+/*
+ * Get conditions of synthetic and remote on Windows
+ */
+static int
+setup_current_filesystem(struct archive_read_disk *a)
+{
+ struct tree *t = a->tree;
+ wchar_t vol[256];
+ wchar_t *path;
+
+ t->current_filesystem->synthetic = -1;/* Not supported */
+ path = safe_path_for_statfs(t);
+ if (!GetVolumePathNameW(path, vol, sizeof(vol)/sizeof(vol[0]))) {
+ free(path);
+ t->current_filesystem->remote = -1;
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "GetVolumePathName failed: %d", (int)GetLastError());
+ return (ARCHIVE_FAILED);
+ }
+ free(path);
+ switch (GetDriveTypeW(vol)) {
+ case DRIVE_UNKNOWN:
+ case DRIVE_NO_ROOT_DIR:
+ t->current_filesystem->remote = -1;
+ break;
+ case DRIVE_REMOTE:
+ t->current_filesystem->remote = 1;
+ break;
+ default:
+ t->current_filesystem->remote = 0;
+ break;
+ }
+
+ return (ARCHIVE_OK);
+}
+
+static int
+close_and_restore_time(HANDLE h, struct tree *t, struct restore_time *rt)
+{
+ HANDLE handle;
+ int r = 0;
+
+ if (h == INVALID_HANDLE_VALUE && AE_IFLNK == rt->filetype)
+ return (0);
+
+ /* Close a file descritor.
+ * It will not be used for SetFileTime() because it has been opened
+ * by a read only mode.
+ */
+ if (h != INVALID_HANDLE_VALUE)
+ CloseHandle(h);
+ if ((t->flags & needsRestoreTimes) == 0)
+ return (r);
+
+ handle = CreateFileW(rt->full_path, FILE_WRITE_ATTRIBUTES,
+ 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (handle == INVALID_HANDLE_VALUE) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (SetFileTime(handle, NULL, &rt->lastAccessTime,
+ &rt->lastWriteTime) == 0) {
+ errno = EINVAL;
+ r = -1;
+ } else
+ r = 0;
+ CloseHandle(handle);
+ return (r);
+}
+
+/*
+ * Add a directory path to the current stack.
+ */
+static void
+tree_push(struct tree *t, const wchar_t *path, const wchar_t *full_path,
+ int filesystem_id, int64_t dev, int64_t ino, struct restore_time *rt)
+{
+ struct tree_entry *te;
+
+ te = malloc(sizeof(*te));
+ memset(te, 0, sizeof(*te));
+ te->next = t->stack;
+ te->parent = t->current;
+ if (te->parent)
+ te->depth = te->parent->depth + 1;
+ t->stack = te;
+ archive_string_init(&te->name);
+ archive_wstrcpy(&te->name, path);
+ archive_string_init(&te->full_path);
+ archive_wstrcpy(&te->full_path, full_path);
+ te->flags = needsDescent | needsOpen | needsAscent;
+ te->filesystem_id = filesystem_id;
+ te->dev = dev;
+ te->ino = ino;
+ te->dirname_length = t->dirname_length;
+ te->full_path_dir_length = t->full_path_dir_length;
+ te->restore_time.full_path = te->full_path.s;
+ if (rt != NULL) {
+ te->restore_time.lastWriteTime = rt->lastWriteTime;
+ te->restore_time.lastAccessTime = rt->lastAccessTime;
+ te->restore_time.filetype = rt->filetype;
+ }
+}
+
+/*
+ * Append a name to the current dir path.
+ */
+static void
+tree_append(struct tree *t, const wchar_t *name, size_t name_length)
+{
+ size_t size_needed;
+
+ t->path.s[t->dirname_length] = L'\0';
+ t->path.length = t->dirname_length;
+ /* Strip trailing '/' from name, unless entire name is "/". */
+ while (name_length > 1 && name[name_length - 1] == L'/')
+ name_length--;
+
+ /* Resize pathname buffer as needed. */
+ size_needed = name_length + t->dirname_length + 2;
+ archive_wstring_ensure(&t->path, size_needed);
+ /* Add a separating '/' if it's needed. */
+ if (t->dirname_length > 0 &&
+ t->path.s[archive_strlen(&t->path)-1] != L'/')
+ archive_wstrappend_wchar(&t->path, L'/');
+ t->basename = t->path.s + archive_strlen(&t->path);
+ archive_wstrncat(&t->path, name, name_length);
+ t->restore_time.full_path = t->basename;
+ if (t->full_path_dir_length > 0) {
+ t->full_path.s[t->full_path_dir_length] = L'\0';
+ t->full_path.length = t->full_path_dir_length;
+ size_needed = name_length + t->full_path_dir_length + 2;
+ archive_wstring_ensure(&t->full_path, size_needed);
+ /* Add a separating '\' if it's needed. */
+ if (t->full_path.s[archive_strlen(&t->full_path)-1] != L'\\')
+ archive_wstrappend_wchar(&t->full_path, L'\\');
+ archive_wstrncat(&t->full_path, name, name_length);
+ t->restore_time.full_path = t->full_path.s;
+ }
+}
+
+/*
+ * Open a directory tree for traversal.
+ */
+static struct tree *
+tree_open(const wchar_t *path, int symlink_mode, int restore_time)
+{
+ struct tree *t;
+
+ t = malloc(sizeof(*t));
+ memset(t, 0, sizeof(*t));
+ archive_string_init(&(t->full_path));
+ archive_string_init(&t->path);
+ archive_wstring_ensure(&t->path, 15);
+ t->initial_symlink_mode = symlink_mode;
+ return (tree_reopen(t, path, restore_time));
+}
+
+static struct tree *
+tree_reopen(struct tree *t, const wchar_t *path, int restore_time)
+{
+ struct archive_wstring ws;
+ wchar_t *pathname, *p, *base;
+
+ t->flags = (restore_time)?needsRestoreTimes:0;
+ t->visit_type = 0;
+ t->tree_errno = 0;
+ t->full_path_dir_length = 0;
+ t->dirname_length = 0;
+ t->depth = 0;
+ t->descend = 0;
+ t->current = NULL;
+ t->d = INVALID_DIR_HANDLE;
+ t->symlink_mode = t->initial_symlink_mode;
+ archive_string_empty(&(t->full_path));
+ archive_string_empty(&t->path);
+ t->entry_fh = INVALID_HANDLE_VALUE;
+ t->entry_eof = 0;
+ t->entry_remaining_bytes = 0;
+
+ /* Get wchar_t strings from char strings. */
+ archive_string_init(&ws);
+ archive_wstrcpy(&ws, path);
+ pathname = ws.s;
+ /* Get a full-path-name. */
+ p = __la_win_permissive_name_w(pathname);
+ if (p == NULL)
+ goto failed;
+ archive_wstrcpy(&(t->full_path), p);
+ free(p);
+
+ /* Convert path separators from '\' to '/' */
+ for (p = pathname; *p != L'\0'; ++p) {
+ if (*p == L'\\')
+ *p = L'/';
+ }
+ base = pathname;
+
+ /* First item is set up a lot like a symlink traversal. */
+ /* printf("Looking for wildcard in %s\n", path); */
+ /* TODO: wildcard detection here screws up on \\?\c:\ UNC names */
+ if (wcschr(base, L'*') || wcschr(base, L'?')) {
+ // It has a wildcard in it...
+ // Separate the last element.
+ p = wcsrchr(base, L'/');
+ if (p != NULL) {
+ *p = L'\0';
+ tree_append(t, base, p - base);
+ t->dirname_length = archive_strlen(&t->path);
+ base = p + 1;
+ }
+ p = wcsrchr(t->full_path.s, L'\\');
+ if (p != NULL) {
+ *p = L'\0';
+ t->full_path.length = wcslen(t->full_path.s);
+ t->full_path_dir_length = archive_strlen(&t->full_path);
+ }
+ }
+ tree_push(t, base, t->full_path.s, 0, 0, 0, NULL);
+ archive_wstring_free(&ws);
+ t->stack->flags = needsFirstVisit;
+ return (t);
+failed:
+ archive_wstring_free(&ws);
+ tree_free(t);
+ return (NULL);
+}
+
+static int
+tree_descent(struct tree *t)
+{
+ t->dirname_length = archive_strlen(&t->path);
+ t->full_path_dir_length = archive_strlen(&t->full_path);
+ t->depth++;
+ return (0);
+}
+
+/*
+ * We've finished a directory; ascend back to the parent.
+ */
+static int
+tree_ascend(struct tree *t)
+{
+ struct tree_entry *te;
+
+ te = t->stack;
+ t->depth--;
+ close_and_restore_time(INVALID_DIR_HANDLE, t, &te->restore_time);
+ return (0);
+}
+
+/*
+ * Pop the working stack.
+ */
+static void
+tree_pop(struct tree *t)
+{
+ struct tree_entry *te;
+
+ t->full_path.s[t->full_path_dir_length] = L'\0';
+ t->full_path.length = t->full_path_dir_length;
+ t->path.s[t->dirname_length] = L'\0';
+ t->path.length = t->dirname_length;
+ if (t->stack == t->current && t->current != NULL)
+ t->current = t->current->parent;
+ te = t->stack;
+ t->stack = te->next;
+ t->dirname_length = te->dirname_length;
+ t->basename = t->path.s + t->dirname_length;
+ t->full_path_dir_length = te->full_path_dir_length;
+ while (t->basename[0] == L'/')
+ t->basename++;
+ archive_wstring_free(&te->name);
+ archive_wstring_free(&te->full_path);
+ free(te);
+}
+
+/*
+ * Get the next item in the tree traversal.
+ */
+static int
+tree_next(struct tree *t)
+{
+ int r;
+
+ while (t->stack != NULL) {
+ /* If there's an open dir, get the next entry from there. */
+ if (t->d != INVALID_DIR_HANDLE) {
+ r = tree_dir_next_windows(t, NULL);
+ if (r == 0)
+ continue;
+ return (r);
+ }
+
+ if (t->stack->flags & needsFirstVisit) {
+ wchar_t *d = t->stack->name.s;
+ t->stack->flags &= ~needsFirstVisit;
+ if (wcschr(d, L'*') || wcschr(d, L'?')) {
+ r = tree_dir_next_windows(t, d);
+ if (r == 0)
+ continue;
+ return (r);
+ } else {
+ HANDLE h = FindFirstFileW(d, &t->_findData);
+ if (h == INVALID_DIR_HANDLE) {
+ t->tree_errno = errno;
+ t->visit_type = TREE_ERROR_DIR;
+ return (t->visit_type);
+ }
+ t->findData = &t->_findData;
+ FindClose(h);
+ }
+ /* Top stack item needs a regular visit. */
+ t->current = t->stack;
+ tree_append(t, t->stack->name.s,
+ archive_strlen(&(t->stack->name)));
+ //t->dirname_length = t->path_length;
+ //tree_pop(t);
+ t->stack->flags &= ~needsFirstVisit;
+ return (t->visit_type = TREE_REGULAR);
+ } else if (t->stack->flags & needsDescent) {
+ /* Top stack item is dir to descend into. */
+ t->current = t->stack;
+ tree_append(t, t->stack->name.s,
+ archive_strlen(&(t->stack->name)));
+ t->stack->flags &= ~needsDescent;
+ r = tree_descent(t);
+ if (r != 0) {
+ tree_pop(t);
+ t->visit_type = r;
+ } else
+ t->visit_type = TREE_POSTDESCENT;
+ return (t->visit_type);
+ } else if (t->stack->flags & needsOpen) {
+ t->stack->flags &= ~needsOpen;
+ r = tree_dir_next_windows(t, L"*");
+ if (r == 0)
+ continue;
+ return (r);
+ } else if (t->stack->flags & needsAscent) {
+ /* Top stack item is dir and we're done with it. */
+ r = tree_ascend(t);
+ tree_pop(t);
+ t->visit_type = r != 0 ? r : TREE_POSTASCENT;
+ return (t->visit_type);
+ } else {
+ /* Top item on stack is dead. */
+ tree_pop(t);
+ t->flags &= ~hasLstat;
+ t->flags &= ~hasStat;
+ }
+ }
+ return (t->visit_type = 0);
+}
+
+static int
+tree_dir_next_windows(struct tree *t, const wchar_t *pattern)
+{
+ const wchar_t *name;
+ size_t namelen;
+ int r;
+
+ for (;;) {
+ if (pattern != NULL) {
+ struct archive_wstring pt;
+
+ archive_string_init(&pt);
+ archive_wstring_ensure(&pt,
+ archive_strlen(&(t->full_path))
+ + 2 + wcslen(pattern));
+ archive_wstring_copy(&pt, &(t->full_path));
+ archive_wstrappend_wchar(&pt, L'\\');
+ archive_wstrcat(&pt, pattern);
+ t->d = FindFirstFileW(pt.s, &t->_findData);
+ archive_wstring_free(&pt);
+ if (t->d == INVALID_DIR_HANDLE) {
+ r = tree_ascend(t); /* Undo "chdir" */
+ tree_pop(t);
+ t->tree_errno = errno;
+ t->visit_type = r != 0 ? r : TREE_ERROR_DIR;
+ return (t->visit_type);
+ }
+ t->findData = &t->_findData;
+ pattern = NULL;
+ } else if (!FindNextFileW(t->d, &t->_findData)) {
+ FindClose(t->d);
+ t->d = INVALID_DIR_HANDLE;
+ t->findData = NULL;
+ return (0);
+ }
+ name = t->findData->cFileName;
+ namelen = wcslen(name);
+ t->flags &= ~hasLstat;
+ t->flags &= ~hasStat;
+ if (name[0] == L'.' && name[1] == L'\0')
+ continue;
+ if (name[0] == L'.' && name[1] == L'.' && name[2] == L'\0')
+ continue;
+ tree_append(t, name, namelen);
+ return (t->visit_type = TREE_REGULAR);
+ }
+}
+
+#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
+static void
+fileTimeToUtc(const FILETIME *filetime, time_t *time, long *ns)
+{
+ ULARGE_INTEGER utc;
+
+ utc.HighPart = filetime->dwHighDateTime;
+ utc.LowPart = filetime->dwLowDateTime;
+ if (utc.QuadPart >= EPOC_TIME) {
+ utc.QuadPart -= EPOC_TIME;
+ /* milli seconds base */
+ *time = (time_t)(utc.QuadPart / 10000000);
+ /* nano seconds base */
+ *ns = (long)(utc.QuadPart % 10000000) * 100;
+ } else {
+ *time = 0;
+ *ns = 0;
+ }
+}
+
+static void
+entry_copy_bhfi(struct archive_entry *entry, const wchar_t *path,
+ const WIN32_FIND_DATAW *findData,
+ const BY_HANDLE_FILE_INFORMATION *bhfi)
+{
+ time_t secs;
+ long nsecs;
+ mode_t mode;
+
+ fileTimeToUtc(&bhfi->ftLastAccessTime, &secs, &nsecs);
+ archive_entry_set_atime(entry, secs, nsecs);
+ fileTimeToUtc(&bhfi->ftLastWriteTime, &secs, &nsecs);
+ archive_entry_set_mtime(entry, secs, nsecs);
+ fileTimeToUtc(&bhfi->ftCreationTime, &secs, &nsecs);
+ archive_entry_set_birthtime(entry, secs, nsecs);
+ archive_entry_set_ctime(entry, secs, nsecs);
+ archive_entry_set_dev(entry, bhfi_dev(bhfi));
+ archive_entry_set_ino64(entry, bhfi_ino(bhfi));
+ if (bhfi->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ archive_entry_set_nlink(entry, bhfi->nNumberOfLinks + 1);
+ else
+ archive_entry_set_nlink(entry, bhfi->nNumberOfLinks);
+ archive_entry_set_size(entry,
+ (((int64_t)bhfi->nFileSizeHigh) << 32)
+ + bhfi->nFileSizeLow);
+ archive_entry_set_uid(entry, 0);
+ archive_entry_set_gid(entry, 0);
+ archive_entry_set_rdev(entry, 0);
+
+ mode = S_IRUSR | S_IRGRP | S_IROTH;
+ if ((bhfi->dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0)
+ mode |= S_IWUSR | S_IWGRP | S_IWOTH;
+ if ((bhfi->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
+ findData != NULL &&
+ findData->dwReserved0 == IO_REPARSE_TAG_SYMLINK)
+ mode |= S_IFLNK;
+ else if (bhfi->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
+ else {
+ const wchar_t *p;
+
+ mode |= S_IFREG;
+ p = wcsrchr(path, L'.');
+ if (p != NULL && wcslen(p) == 4) {
+ switch (p[1]) {
+ case L'B': case L'b':
+ if ((p[2] == L'A' || p[2] == L'a' ) &&
+ (p[3] == L'T' || p[3] == L't' ))
+ mode |= S_IXUSR | S_IXGRP | S_IXOTH;
+ break;
+ case L'C': case L'c':
+ if (((p[2] == L'M' || p[2] == L'm' ) &&
+ (p[3] == L'D' || p[3] == L'd' )) ||
+ ((p[2] == L'M' || p[2] == L'm' ) &&
+ (p[3] == L'D' || p[3] == L'd' )))
+ mode |= S_IXUSR | S_IXGRP | S_IXOTH;
+ break;
+ case L'E': case L'e':
+ if ((p[2] == L'X' || p[2] == L'x' ) &&
+ (p[3] == L'E' || p[3] == L'e' ))
+ mode |= S_IXUSR | S_IXGRP | S_IXOTH;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ archive_entry_set_mode(entry, mode);
+}
+
+static void
+tree_archive_entry_copy_bhfi(struct archive_entry *entry, struct tree *t,
+ const BY_HANDLE_FILE_INFORMATION *bhfi)
+{
+ entry_copy_bhfi(entry, tree_current_path(t), t->findData, bhfi);
+}
+
+static int
+tree_current_file_information(struct tree *t, BY_HANDLE_FILE_INFORMATION *st,
+ int sim_lstat)
+{
+ HANDLE h;
+ int r;
+ DWORD flag = FILE_FLAG_BACKUP_SEMANTICS;
+
+ if (sim_lstat && tree_current_is_physical_link(t))
+ flag |= FILE_FLAG_OPEN_REPARSE_POINT;
+ h = CreateFileW(tree_current_access_path(t), 0, 0, NULL,
+ OPEN_EXISTING, flag, NULL);
+ if (h == INVALID_HANDLE_VALUE)
+ return (0);
+ r = GetFileInformationByHandle(h, st);
+ CloseHandle(h);
+ return (r);
+}
+
+/*
+ * Get the stat() data for the entry just returned from tree_next().
+ */
+static const BY_HANDLE_FILE_INFORMATION *
+tree_current_stat(struct tree *t)
+{
+ if (!(t->flags & hasStat)) {
+ if (!tree_current_file_information(t, &t->st, 0))
+ return NULL;
+ t->flags |= hasStat;
+ }
+ return (&t->st);
+}
+
+/*
+ * Get the lstat() data for the entry just returned from tree_next().
+ */
+static const BY_HANDLE_FILE_INFORMATION *
+tree_current_lstat(struct tree *t)
+{
+ if (!(t->flags & hasLstat)) {
+ if (!tree_current_file_information(t, &t->lst, 1))
+ return NULL;
+ t->flags |= hasLstat;
+ }
+ return (&t->lst);
+}
+
+/*
+ * Test whether current entry is a dir or link to a dir.
+ */
+static int
+tree_current_is_dir(struct tree *t)
+{
+ if (t->findData)
+ return (t->findData->dwFileAttributes
+ & FILE_ATTRIBUTE_DIRECTORY);
+ return (0);
+}
+
+/*
+ * Test whether current entry is a physical directory. Usually, we
+ * already have at least one of stat() or lstat() in memory, so we
+ * use tricks to try to avoid an extra trip to the disk.
+ */
+static int
+tree_current_is_physical_dir(struct tree *t)
+{
+ if (tree_current_is_physical_link(t))
+ return (0);
+ return (tree_current_is_dir(t));
+}
+
+/*
+ * Test whether current entry is a symbolic link.
+ */
+static int
+tree_current_is_physical_link(struct tree *t)
+{
+ if (t->findData)
+ return ((t->findData->dwFileAttributes
+ & FILE_ATTRIBUTE_REPARSE_POINT) &&
+ (t->findData->dwReserved0
+ == IO_REPARSE_TAG_SYMLINK));
+ return (0);
+}
+
+/*
+ * Test whether the same file has been in the tree as its parent.
+ */
+static int
+tree_target_is_same_as_parent(struct tree *t,
+ const BY_HANDLE_FILE_INFORMATION *st)
+{
+ struct tree_entry *te;
+ int64_t dev = bhfi_dev(st);
+ int64_t ino = bhfi_ino(st);
+
+ for (te = t->current->parent; te != NULL; te = te->parent) {
+ if (te->dev == dev && te->ino == ino)
+ return (1);
+ }
+ return (0);
+}
+
+/*
+ * Return the access path for the entry just returned from tree_next().
+ */
+static const wchar_t *
+tree_current_access_path(struct tree *t)
+{
+ return (t->full_path.s);
+}
+
+/*
+ * Return the full path for the entry just returned from tree_next().
+ */
+static const wchar_t *
+tree_current_path(struct tree *t)
+{
+ return (t->path.s);
+}
+
+/*
+ * Terminate the traversal.
+ */
+static void
+tree_close(struct tree *t)
+{
+
+ if (t == NULL)
+ return;
+ if (t->entry_fh != INVALID_HANDLE_VALUE) {
+ close_and_restore_time(t->entry_fh, t, &t->restore_time);
+ t->entry_fh = INVALID_HANDLE_VALUE;
+ }
+ /* Close the handle of FindFirstFileW */
+ if (t->d != INVALID_DIR_HANDLE) {
+ FindClose(t->d);
+ t->d = INVALID_DIR_HANDLE;
+ t->findData = NULL;
+ }
+ /* Release anything remaining in the stack. */
+ while (t->stack != NULL)
+ tree_pop(t);
+}
+
+/*
+ * Release any resources.
+ */
+static void
+tree_free(struct tree *t)
+{
+ if (t == NULL)
+ return;
+ archive_wstring_free(&t->path);
+ archive_wstring_free(&t->full_path);
+ free(t->sparse_list);
+ free(t->filesystem_table);
+ free(t->entry_buff);
+ free(t);
+}
+
+
+/*
+ * Populate the archive_entry with metadata from the disk.
+ */
+int
+archive_read_disk_entry_from_file(struct archive *_a,
+ struct archive_entry *entry, int fd, const struct stat *st)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ const wchar_t *path;
+ const wchar_t *wname;
+ const char *name;
+ HANDLE h;
+ BY_HANDLE_FILE_INFORMATION bhfi;
+ DWORD fileAttributes = 0;
+ int r;
+
+ archive_clear_error(_a);
+ wname = archive_entry_sourcepath_w(entry);
+ if (wname == NULL)
+ wname = archive_entry_pathname_w(entry);
+ if (wname == NULL) {
+ archive_set_error(&a->archive, EINVAL,
+ "Can't get a wide character version of the path");
+ return (ARCHIVE_FAILED);
+ }
+ path = __la_win_permissive_name_w(wname);
+
+ if (st == NULL) {
+ /*
+ * Get metadata through GetFileInformationByHandle().
+ */
+ if (fd >= 0) {
+ h = (HANDLE)_get_osfhandle(fd);
+ r = GetFileInformationByHandle(h, &bhfi);
+ if (r == 0) {
+ archive_set_error(&a->archive, GetLastError(),
+ "Can't GetFileInformationByHandle");
+ return (ARCHIVE_FAILED);
+ }
+ entry_copy_bhfi(entry, path, NULL, &bhfi);
+ } else {
+ WIN32_FIND_DATAW findData;
+ DWORD flag, desiredAccess;
+
+ h = FindFirstFileW(path, &findData);
+ if (h == INVALID_DIR_HANDLE) {
+ archive_set_error(&a->archive, GetLastError(),
+ "Can't FindFirstFileW");
+ return (ARCHIVE_FAILED);
+ }
+ FindClose(h);
+
+ flag = FILE_FLAG_BACKUP_SEMANTICS;
+ if (!a->follow_symlinks &&
+ (findData.dwFileAttributes
+ & FILE_ATTRIBUTE_REPARSE_POINT) &&
+ (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK)) {
+ flag |= FILE_FLAG_OPEN_REPARSE_POINT;
+ desiredAccess = 0;
+ } else if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ desiredAccess = 0;
+ } else
+ desiredAccess = GENERIC_READ;
+
+ h = CreateFileW(path, desiredAccess, 0, NULL,
+ OPEN_EXISTING, flag, NULL);
+ if (h == INVALID_HANDLE_VALUE) {
+ archive_set_error(&a->archive,
+ GetLastError(),
+ "Can't CreateFileW");
+ return (ARCHIVE_FAILED);
+ }
+ r = GetFileInformationByHandle(h, &bhfi);
+ if (r == 0) {
+ archive_set_error(&a->archive,
+ GetLastError(),
+ "Can't GetFileInformationByHandle");
+ CloseHandle(h);
+ return (ARCHIVE_FAILED);
+ }
+ entry_copy_bhfi(entry, path, &findData, &bhfi);
+ }
+ fileAttributes = bhfi.dwFileAttributes;
+ } else {
+ archive_entry_copy_stat(entry, st);
+ h = INVALID_DIR_HANDLE;
+ }
+
+ /* Lookup uname/gname */
+ name = archive_read_disk_uname(_a, archive_entry_uid(entry));
+ if (name != NULL)
+ archive_entry_copy_uname(entry, name);
+ name = archive_read_disk_gname(_a, archive_entry_gid(entry));
+ if (name != NULL)
+ archive_entry_copy_gname(entry, name);
+
+ /*
+ * Can this file be sparse file ?
+ */
+ if (archive_entry_filetype(entry) != AE_IFREG
+ || archive_entry_size(entry) <= 0
+ || archive_entry_hardlink(entry) != NULL) {
+ if (h != INVALID_HANDLE_VALUE && fd < 0)
+ CloseHandle(h);
+ return (ARCHIVE_OK);
+ }
+
+ if (h == INVALID_HANDLE_VALUE) {
+ if (fd >= 0) {
+ h = (HANDLE)_get_osfhandle(fd);
+ } else {
+ h = CreateFileW(path, GENERIC_READ, 0, NULL,
+ OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (h == INVALID_HANDLE_VALUE) {
+ archive_set_error(&a->archive, GetLastError(),
+ "Can't CreateFileW");
+ return (ARCHIVE_FAILED);
+ }
+ }
+ r = GetFileInformationByHandle(h, &bhfi);
+ if (r == 0) {
+ archive_set_error(&a->archive, GetLastError(),
+ "Can't GetFileInformationByHandle");
+ if (h != INVALID_HANDLE_VALUE && fd < 0)
+ CloseHandle(h);
+ return (ARCHIVE_FAILED);
+ }
+ fileAttributes = bhfi.dwFileAttributes;
+ }
+
+ /* Sparse file must be set a mark, FILE_ATTRIBUTE_SPARSE_FILE */
+ if ((fileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) == 0) {
+ if (fd < 0)
+ CloseHandle(h);
+ return (ARCHIVE_OK);
+ }
+
+ r = setup_sparse_from_disk(a, entry, h);
+ if (fd < 0)
+ CloseHandle(h);
+
+ return (r);
+}
+
+/*
+ * Windows sparse interface.
+ */
+#if defined(__MINGW32__) && !defined(FSCTL_QUERY_ALLOCATED_RANGES)
+#define FSCTL_QUERY_ALLOCATED_RANGES 0x940CF
+typedef struct {
+ LARGE_INTEGER FileOffset;
+ LARGE_INTEGER Length;
+} FILE_ALLOCATED_RANGE_BUFFER;
+#endif
+
+static int
+setup_sparse_from_disk(struct archive_read_disk *a,
+ struct archive_entry *entry, HANDLE handle)
+{
+ FILE_ALLOCATED_RANGE_BUFFER range, *outranges = NULL;
+ size_t outranges_size;
+ int64_t entry_size = archive_entry_size(entry);
+ int exit_sts = ARCHIVE_OK;
+
+ range.FileOffset.QuadPart = 0;
+ range.Length.QuadPart = entry_size;
+ outranges_size = 2048;
+ outranges = (FILE_ALLOCATED_RANGE_BUFFER *)malloc(outranges_size);
+ if (outranges == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Couldn't allocate memory");
+ exit_sts = ARCHIVE_FATAL;
+ goto exit_setup_sparse;
+ }
+
+ for (;;) {
+ DWORD retbytes;
+ BOOL ret;
+
+ for (;;) {
+ ret = DeviceIoControl(handle,
+ FSCTL_QUERY_ALLOCATED_RANGES,
+ &range, sizeof(range), outranges,
+ outranges_size, &retbytes, NULL);
+ if (ret == 0 && GetLastError() == ERROR_MORE_DATA) {
+ free(outranges);
+ outranges_size *= 2;
+ outranges = (FILE_ALLOCATED_RANGE_BUFFER *)
+ malloc(outranges_size);
+ if (outranges == NULL) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Couldn't allocate memory");
+ exit_sts = ARCHIVE_FATAL;
+ goto exit_setup_sparse;
+ }
+ continue;
+ } else
+ break;
+ }
+ if (ret != 0) {
+ if (retbytes > 0) {
+ DWORD i, n;
+
+ n = retbytes / sizeof(outranges[0]);
+ if (n == 1 &&
+ outranges[0].FileOffset.QuadPart == 0 &&
+ outranges[0].Length.QuadPart == entry_size)
+ break;/* This is not sparse. */
+ for (i = 0; i < n; i++)
+ archive_entry_sparse_add_entry(entry,
+ outranges[i].FileOffset.QuadPart,
+ outranges[i].Length.QuadPart);
+ range.FileOffset.QuadPart =
+ outranges[n-1].FileOffset.QuadPart
+ + outranges[n-1].Length.QuadPart;
+ range.Length.QuadPart =
+ entry_size - range.FileOffset.QuadPart;
+ if (range.Length.QuadPart > 0)
+ continue;
+ } else {
+ /* The remaining data is hole. */
+ archive_entry_sparse_add_entry(entry,
+ range.FileOffset.QuadPart,
+ range.Length.QuadPart);
+ }
+ break;
+ } else {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "DeviceIoControl Failed: %lu", GetLastError());
+ exit_sts = ARCHIVE_FAILED;
+ goto exit_setup_sparse;
+ }
+ }
+exit_setup_sparse:
+ free(outranges);
+
+ return (exit_sts);
+}
+
+#endif
diff --git a/libarchive/archive_read_extract.3 b/libarchive/archive_read_extract.3
new file mode 100644
index 000000000000..882c6e199ba1
--- /dev/null
+++ b/libarchive/archive_read_extract.3
@@ -0,0 +1,135 @@
+.\" Copyright (c) 2003-2011 Tim Kientzle
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd March 22, 2011
+.Dt ARCHIVE_READ_EXTRACT 3
+.Os
+.Sh NAME
+.Nm archive_read_extract ,
+.Nm archive_read_extract2 ,
+.Nm archive_read_extract_set_progress_callback
+.Nd functions for reading streaming archives
+.Sh SYNOPSIS
+.In archive.h
+.Ft int
+.Fo archive_read_extract
+.Fa "struct archive *"
+.Fa "struct archive_entry *"
+.Fa "int flags"
+.Fc
+.Ft int
+.Fo archive_read_extract2
+.Fa "struct archive *src"
+.Fa "struct archive_entry *"
+.Fa "struct archive *dest"
+.Fc
+.Ft void
+.Fo archive_read_extract_set_progress_callback
+.Fa "struct archive *"
+.Fa "void (*func)(void *)"
+.Fa "void *user_data"
+.Fc
+.Sh DESCRIPTION
+.Bl -tag -compact -width indent
+.It Fn archive_read_extract , Fn archive_read_extract_set_skip_file
+A convenience function that wraps the corresponding
+.Xr archive_write_disk 3
+interfaces.
+The first call to
+.Fn archive_read_extract
+creates a restore object using
+.Xr archive_write_disk_new 3
+and
+.Xr archive_write_disk_set_standard_lookup 3 ,
+then transparently invokes
+.Xr archive_write_disk_set_options 3 ,
+.Xr archive_write_header 3 ,
+.Xr archive_write_data 3 ,
+and
+.Xr archive_write_finish_entry 3
+to create the entry on disk and copy data into it.
+The
+.Va flags
+argument is passed unmodified to
+.Xr archive_write_disk_set_options 3 .
+.It Fn archive_read_extract2
+This is another version of
+.Fn archive_read_extract
+that allows you to provide your own restore object.
+In particular, this allows you to override the standard lookup functions
+using
+.Xr archive_write_disk_set_group_lookup 3 ,
+and
+.Xr archive_write_disk_set_user_lookup 3 .
+Note that
+.Fn archive_read_extract2
+does not accept a
+.Va flags
+argument; you should use
+.Fn archive_write_disk_set_options
+to set the restore options yourself.
+.It Fn archive_read_extract_set_progress_callback
+Sets a pointer to a user-defined callback that can be used
+for updating progress displays during extraction.
+The progress function will be invoked during the extraction of large
+regular files.
+The progress function will be invoked with the pointer provided to this call.
+Generally, the data pointed to should include a reference to the archive
+object and the archive_entry object so that various statistics
+can be retrieved for the progress display.
+.El
+.\"
+.Sh RETURN VALUES
+Most functions return zero on success, non-zero on error.
+The possible return codes include:
+.Cm ARCHIVE_OK
+(the operation succeeded),
+.Cm ARCHIVE_WARN
+(the operation succeeded but a non-critical error was encountered),
+.Cm ARCHIVE_EOF
+(end-of-archive was encountered),
+.Cm ARCHIVE_RETRY
+(the operation failed but can be retried),
+and
+.Cm ARCHIVE_FATAL
+(there was a fatal error; the archive should be closed immediately).
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_read 3 ,
+.Xr archive_read_data 3 ,
+.Xr archive_read_filter 3 ,
+.Xr archive_read_format 3 ,
+.Xr archive_read_open 3 ,
+.Xr archive_read_set_options 3 ,
+.Xr archive_util 3 ,
+.Xr tar 5
diff --git a/libarchive/archive_read_extract.c b/libarchive/archive_read_extract.c
index 013be05531b2..aad8ac5168df 100644
--- a/libarchive/archive_read_extract.c
+++ b/libarchive/archive_read_extract.c
@@ -100,8 +100,9 @@ archive_read_extract2(struct archive *_a, struct archive_entry *entry,
int r, r2;
/* Set up for this particular entry. */
- archive_write_disk_set_skip_file(ad,
- a->skip_file_dev, a->skip_file_ino);
+ if (a->skip_file_set)
+ archive_write_disk_set_skip_file(ad,
+ a->skip_file_dev, a->skip_file_ino);
r = archive_write_header(ad, entry);
if (r < ARCHIVE_WARN)
r = ARCHIVE_WARN;
@@ -116,7 +117,7 @@ archive_read_extract2(struct archive *_a, struct archive_entry *entry,
r2 = ARCHIVE_WARN;
/* Use the first message. */
if (r2 != ARCHIVE_OK && r == ARCHIVE_OK)
- archive_copy_error(&a->archive, ad);
+ archive_copy_error(&a->archive, ad);
/* Use the worst error return. */
if (r2 < r)
r = r2;
@@ -138,13 +139,15 @@ archive_read_extract_set_progress_callback(struct archive *_a,
static int
copy_data(struct archive *ar, struct archive *aw)
{
- off_t offset;
+ int64_t offset;
const void *buff;
struct extract *extract;
size_t size;
int r;
extract = get_extract((struct archive_read *)ar);
+ if (extract == NULL)
+ return (ARCHIVE_FATAL);
for (;;) {
r = archive_read_data_block(ar, &buff, &size, &offset);
if (r == ARCHIVE_EOF)
diff --git a/libarchive/archive_read_filter.3 b/libarchive/archive_read_filter.3
new file mode 100644
index 000000000000..1cfa2159917c
--- /dev/null
+++ b/libarchive/archive_read_filter.3
@@ -0,0 +1,127 @@
+.\" Copyright (c) 2003-2011 Tim Kientzle
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd March 19, 2011
+.Dt ARCHIVE_READ_FILTER 3
+.Os
+.Sh NAME
+.Nm archive_read_support_filter_all ,
+.Nm archive_read_support_filter_bzip2 ,
+.Nm archive_read_support_filter_compress ,
+.Nm archive_read_support_filter_gzip ,
+.Nm archive_read_support_filter_lzma ,
+.Nm archive_read_support_filter_none ,
+.Nm archive_read_support_filter_xz ,
+.Nm archive_read_support_filter_program ,
+.Nm archive_read_support_filter_program_signature
+.Nd functions for reading streaming archives
+.\"
+.Sh SYNOPSIS
+.In archive.h
+.Ft int
+.Fn archive_read_support_filter_all "struct archive *"
+.Ft int
+.Fn archive_read_support_filter_bzip2 "struct archive *"
+.Ft int
+.Fn archive_read_support_filter_compress "struct archive *"
+.Ft int
+.Fn archive_read_support_filter_gzip "struct archive *"
+.Ft int
+.Fn archive_read_support_filter_lzma "struct archive *"
+.Ft int
+.Fn archive_read_support_filter_none "struct archive *"
+.Ft int
+.Fn archive_read_support_filter_xz "struct archive *"
+.Ft int
+.Fo archive_read_support_filter_program
+.Fa "struct archive *"
+.Fa "const char *cmd"
+.Fc
+.Ft int
+.Fo archive_read_support_filter_program_signature
+.Fa "struct archive *"
+.Fa "const char *cmd"
+.Fa "const void *signature"
+.Fa "size_t signature_length"
+.Fc
+.\"
+.Sh DESCRIPTION
+.Bl -tag -compact -width indent
+.It Xo
+.Fn archive_read_support_filter_bzip2 ,
+.Fn archive_read_support_filter_compress ,
+.Fn archive_read_support_filter_gzip ,
+.Fn archive_read_support_filter_lzma ,
+.Fn archive_read_support_filter_none ,
+.Fn archive_read_support_filter_xz
+.Xc
+Enables auto-detection code and decompression support for the
+specified compression.
+These functions may fall back on external programs if an appropriate
+library was not available at build time.
+Decompression using an external program is usually slower than
+decompression through built-in libraries.
+Note that
+.Dq none
+is always enabled by default.
+.It Fn archive_read_support_filter_all
+Enables all available decompression filters.
+.It Fn archive_read_support_filter_program
+Data is fed through the specified external program before being dearchived.
+Note that this disables automatic detection of the compression format,
+so it makes no sense to specify this in conjunction with any other
+decompression option.
+.It Fn archive_read_support_filter_program_signature
+This feeds data through the specified external program
+but only if the initial bytes of the data match the specified
+signature value.
+.El
+.\"
+.\". Sh EXAMPLE
+.\"
+.Sh RETURN VALUES
+These functions return
+.Cm ARCHIVE_OK
+if the compression is fully supported,
+.Cm ARCHIVE_WARN
+if the compression is supported only through an external program.
+.Pp
+.Fn archive_read_support_filter_none
+always succeeds.
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.\"
+.Sh SEE ALSO
+.Xr libarchive 3 ,
+.Xr archive_read 3 ,
+.Xr archive_read_data 3 ,
+.Xr archive_read_format 3 ,
+.Xr archive_read_format 3
diff --git a/libarchive/archive_read_format.3 b/libarchive/archive_read_format.3
new file mode 100644
index 000000000000..e707e05f6de5
--- /dev/null
+++ b/libarchive/archive_read_format.3
@@ -0,0 +1,175 @@
+.\" Copyright (c) 2003-2011 Tim Kientzle
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD: head/lib/libarchive/archive_read.3 191595 2009-04-27 20:13:13Z kientzle $
+.\"
+.Dd March 19, 2011
+.Dt ARCHIVE_READ_FORMAT 3
+.Os
+.Sh NAME
+.Nm archive_read_support_format_7zip ,
+.Nm archive_read_support_format_all ,
+.Nm archive_read_support_format_ar ,
+.Nm archive_read_support_format_by_code ,
+.Nm archive_read_support_format_cab ,
+.Nm archive_read_support_format_cpio ,
+.Nm archive_read_support_format_empty ,
+.Nm archive_read_support_format_iso9660 ,
+.Nm archive_read_support_format_lha ,
+.Nm archive_read_support_format_mtree,
+.Nm archive_read_support_format_rar,
+.Nm archive_read_support_format_raw,
+.Nm archive_read_support_format_tar ,
+.Nm archive_read_support_format_xar ,
+.Nm archive_read_support_format_zip
+.Nd functions for reading streaming archives
+.\"
+.Sh SYNOPSIS
+.In archive.h
+.Ft int
+.Fn archive_read_support_format_7zip "struct archive *"
+.Ft int
+.Fn archive_read_support_format_all "struct archive *"
+.Ft int
+.Fn archive_read_support_format_ar "struct archive *"
+.Ft int
+.Fn archive_read_support_format_by_code "struct archive *" "int"
+.Ft int
+.Fn archive_read_support_format_cab "struct archive *"
+.Ft int
+.Fn archive_read_support_format_cpio "struct archive *"
+.Ft int
+.Fn archive_read_support_format_empty "struct archive *"
+.Ft int
+.Fn archive_read_support_format_iso9660 "struct archive *"
+.Ft int
+.Fn archive_read_support_format_lha "struct archive *"
+.Ft int
+.Fn archive_read_support_format_mtree "struct archive *"
+.Ft int
+.Fn archive_read_support_format_rar "struct archive *"
+.Ft int
+.Fn archive_read_support_format_raw "struct archive *"
+.Ft int
+.Fn archive_read_support_format_tar "struct archive *"
+.Ft int
+.Fn archive_read_support_format_xar "struct archive *"
+.Ft int
+.Fn archive_read_support_format_zip "struct archive *"
+.\"
+.Sh DESCRIPTION
+.Bl -tag -compact -width indent
+.It Xo
+.Fn archive_read_support_format_7zip ,
+.Fn archive_read_support_format_ar ,
+.Fn archive_read_support_format_cab ,
+.Fn archive_read_support_format_cpio ,
+.Fn archive_read_support_format_iso9660 ,
+.Fn archive_read_support_format_lha ,
+.Fn archive_read_support_format_mtree ,
+.Fn archive_read_support_format_rar ,
+.Fn archive_read_support_format_raw ,
+.Fn archive_read_support_format_tar ,
+.Fn archive_read_support_format_xar ,
+.Fn archive_read_support_format_zip
+.Xc
+Enables support---including auto-detection code---for the
+specified archive format.
+For example,
+.Fn archive_read_support_format_tar
+enables support for a variety of standard tar formats, old-style tar,
+ustar, pax interchange format, and many common variants.
+.It Fn archive_read_support_format_all
+Enables support for all available formats except the
+.Dq raw
+format (see below).
+.It Fn archive_read_support_format_by_code
+Enables a single format specified by the format code.
+This can be useful when reading a single archive twice;
+use
+.Fn archive_format
+after reading the first time and pass the resulting code
+to this function to selectively enable only the necessary
+format support.
+Note: In statically-linked executables, this will cause
+your program to include support for every format.
+If executable size is a concern, you may wish to avoid
+using this function.
+.It Fn archive_read_support_format_empty
+Enables support for treating empty files as empty archives.
+Because empty files are valid for several different formats,
+it is not possible to accurately determine a format for
+an empty file based purely on contents.
+So empty files are treated by libarchive as a distinct
+format.
+.It Fn archive_read_support_format_raw
+The
+.Dq raw
+format handler allows libarchive to be used to read arbitrary data.
+It treats any data stream as an archive with a single entry.
+The pathname of this entry is
+.Dq data ;
+all other entry fields are unset.
+This is not enabled by
+.Fn archive_read_support_format_all
+in order to avoid erroneous handling of damaged archives.
+.El
+.\" .Sh EXAMPLE
+.Sh RETURN VALUES
+These functions return
+.Cm ARCHIVE_OK
+on success, or
+.Cm ARCHIVE_FATAL .
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.\"
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_read_data 3 ,
+.Xr archive_read_filter 3 ,
+.Xr archive_read_set_options 3 ,
+.Xr archive_util 3 ,
+.Xr tar 5
+.Sh BUGS
+Many traditional archiver programs treat
+empty files as valid empty archives.
+For example, many implementations of
+.Xr tar 1
+allow you to append entries to an empty file.
+Of course, it is impossible to determine the format of an empty file
+by inspecting the contents, so this library treats empty files as
+having a special
+.Dq empty
+format.
+.Pp
+Using the
+.Dq raw
+handler together with any other handler will often work
+but can produce surprising results.
diff --git a/libarchive/archive_read_free.3 b/libarchive/archive_read_free.3
new file mode 100644
index 000000000000..f5f2515a83f5
--- /dev/null
+++ b/libarchive/archive_read_free.3
@@ -0,0 +1,91 @@
+.\" Copyright (c) 2003-2011 Tim Kientzle
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD: head/lib/libarchive/archive_read.3 191595 2009-04-27 20:13:13Z kientzle $
+.\"
+.Dd March 20, 2011
+.Dt ARCHIVE_READ_FREE 3
+.Os
+.Sh NAME
+.Nm archive_read_close ,
+.Nm archive_read_finish ,
+.Nm archive_read_free
+.Nd functions for reading streaming archives
+.Sh SYNOPSIS
+.In archive.h
+.Ft int
+.Fn archive_read_close "struct archive *"
+.Ft int
+.Fn archive_read_finish "struct archive *"
+.Ft int
+.Fn archive_read_free "struct archive *"
+.\"
+.Sh DESCRIPTION
+.Bl -tag -compact -width indent
+.It Fn archive_read_close
+Complete the archive and invoke the close callback.
+.It Fn archive_read_finish
+This is a deprecated synonym for
+.Fn archive_read_free .
+The new name was introduced with libarchive 3.0.
+Applications that need to compile with either libarchive 2
+or libarchive 3 should continue to use the
+.Fn archive_read_finish
+name.
+Both names will be supported until libarchive 4.0 is
+released, which is not expected to occur earlier
+than 2013.
+.It Fn archive_read_free
+Invokes
+.Fn archive_read_close
+if it was not invoked manually, then release all resources.
+Note: In libarchive 1.x, this function was declared to return
+.Ft void ,
+which made it impossible to detect certain errors when
+.Fn archive_read_close
+was invoked implicitly from this function.
+The declaration is corrected beginning with libarchive 2.0.
+.El
+.Sh RETURN VALUES
+These functions return
+.Cm ARCHIVE_OK
+on success, or
+.Cm ARCHIVE_FATAL .
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.\"
+.Sh SEE ALSO
+.Xr libarchive 3 ,
+.Xr archive_read_new 3 ,
+.Xr archive_read_data 3 ,
+.Xr archive_read_filter 3 ,
+.Xr archive_read_format 3 ,
+.Xr archive_read_open 3 ,
+.Xr archive_read_set_options 3 ,
+.Xr archive_util 3
diff --git a/libarchive/archive_read_header.3 b/libarchive/archive_read_header.3
new file mode 100644
index 000000000000..999e963cf6a9
--- /dev/null
+++ b/libarchive/archive_read_header.3
@@ -0,0 +1,89 @@
+.\" Copyright (c) 2003-2011 Tim Kientzle
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd March 22, 2011
+.Dt ARCHIVE_READ_HEADER 3
+.Os
+.Sh NAME
+.Nm archive_read_next_header ,
+.Nm archive_read_next_header2
+.Nd functions for reading streaming archives
+.Sh SYNOPSIS
+.In archive.h
+.Ft int
+.Fn archive_read_next_header "struct archive *" "struct archive_entry **"
+.Ft int
+.Fn archive_read_next_header2 "struct archive *" "struct archive_entry *"
+.\"
+.Sh DESCRIPTION
+.Bl -tag -compact -width indent
+.It Fn archive_read_next_header
+Read the header for the next entry and return a pointer to
+a
+.Tn struct archive_entry .
+This is a convenience wrapper around
+.Fn archive_read_next_header2
+that reuses an internal
+.Tn struct archive_entry
+object for each request.
+.It Fn archive_read_next_header2
+Read the header for the next entry and populate the provided
+.Tn struct archive_entry .
+.El
+.\"
+.Sh RETURN VALUES
+These functions return
+.Cm ARCHIVE_OK
+(the operation succeeded),
+.Cm ARCHIVE_WARN
+(the operation succeeded but a non-critical error was encountered),
+.Cm ARCHIVE_EOF
+(end-of-archive was encountered),
+.Cm ARCHIVE_RETRY
+(the operation failed but can be retried),
+and
+.Cm ARCHIVE_FATAL
+(there was a fatal error; the archive should be closed immediately).
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.\"
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_read 3 ,
+.Xr archive_read_data 3 ,
+.Xr archive_read_extract 3 ,
+.Xr archive_read_filter 3 ,
+.Xr archive_read_format 3 ,
+.Xr archive_read_open 3 ,
+.Xr archive_read_set_options 3 ,
+.Xr archive_util 3 ,
+.Xr tar 5
diff --git a/libarchive/archive_read_new.3 b/libarchive/archive_read_new.3
new file mode 100644
index 000000000000..e04406aa666e
--- /dev/null
+++ b/libarchive/archive_read_new.3
@@ -0,0 +1,57 @@
+.\" Copyright (c) 2003-2011 Tim Kientzle
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD: head/lib/libarchive/archive_read.3 191595 2009-04-27 20:13:13Z kientzle $
+.\"
+.Dd March 20, 2011
+.Dt ARCHIVE_READ_NEW 3
+.Os
+.Sh NAME
+.Nm archive_read_new
+.Nd functions for reading streaming archives
+.Sh SYNOPSIS
+.In archive.h
+.Ft struct archive *
+.Fn archive_read_new "void"
+.Sh DESCRIPTION
+Allocates and initializes a
+.Tn struct archive
+object suitable for reading from an archive.
+.Dv NULL
+is returned on error.
+.Pp
+A complete description of the
+.Tn struct archive
+object can be found in the overview manual page for
+.Xr libarchive 3 .
+.\" .Sh ERRORS
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_read_data 3 ,
+.Xr archive_read_filter 3 ,
+.Xr archive_read_format 3 ,
+.Xr archive_read_set_options 3 ,
+.Xr archive_util 3 ,
+.Xr tar 5
diff --git a/libarchive/archive_read_open.3 b/libarchive/archive_read_open.3
new file mode 100644
index 000000000000..09c0575686e2
--- /dev/null
+++ b/libarchive/archive_read_open.3
@@ -0,0 +1,231 @@
+.\" Copyright (c) 2003-2011 Tim Kientzle
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD: head/lib/libarchive/archive_read.3 191595 2009-04-27 20:13:13Z kientzle $
+.\"
+.Dd March 19, 2011
+.Dt ARCHIVE_READ_OPEN 3
+.Os
+.Sh NAME
+.Nm archive_read_open ,
+.Nm archive_read_open2 ,
+.Nm archive_read_open_fd ,
+.Nm archive_read_open_FILE ,
+.Nm archive_read_open_filename ,
+.Nm archive_read_open_memory ,
+.Nd functions for reading streaming archives
+.Sh SYNOPSIS
+.In archive.h
+.Ft int
+.Fo archive_read_open
+.Fa "struct archive *"
+.Fa "void *client_data"
+.Fa "archive_open_callback *"
+.Fa "archive_read_callback *"
+.Fa "archive_close_callback *"
+.Fc
+.Ft int
+.Fo archive_read_open2
+.Fa "struct archive *"
+.Fa "void *client_data"
+.Fa "archive_open_callback *"
+.Fa "archive_read_callback *"
+.Fa "archive_skip_callback *"
+.Fa "archive_close_callback *"
+.Fc
+.Ft int
+.Fn archive_read_open_FILE "struct archive *" "FILE *file"
+.Ft int
+.Fn archive_read_open_fd "struct archive *" "int fd" "size_t block_size"
+.Ft int
+.Fo archive_read_open_filename
+.Fa "struct archive *"
+.Fa "const char *filename"
+.Fa "size_t block_size"
+.Fc
+.Ft int
+.Fn archive_read_open_memory "struct archive *" "void *buff" "size_t size"
+.Sh DESCRIPTION
+.Bl -tag -compact -width indent
+.It Fn archive_read_open
+The same as
+.Fn archive_read_open2 ,
+except that the skip callback is assumed to be
+.Dv NULL .
+.It Fn archive_read_open2
+Freeze the settings, open the archive, and prepare for reading entries.
+This is the most generic version of this call, which accepts
+four callback functions.
+Most clients will want to use
+.Fn archive_read_open_filename ,
+.Fn archive_read_open_FILE ,
+.Fn archive_read_open_fd ,
+or
+.Fn archive_read_open_memory
+instead.
+The library invokes the client-provided functions to obtain
+raw bytes from the archive.
+.It Fn archive_read_open_FILE
+Like
+.Fn archive_read_open ,
+except that it accepts a
+.Ft "FILE *"
+pointer.
+This function should not be used with tape drives or other devices
+that require strict I/O blocking.
+.It Fn archive_read_open_fd
+Like
+.Fn archive_read_open ,
+except that it accepts a file descriptor and block size rather than
+a set of function pointers.
+Note that the file descriptor will not be automatically closed at
+end-of-archive.
+This function is safe for use with tape drives or other blocked devices.
+.It Fn archive_read_open_file
+This is a deprecated synonym for
+.Fn archive_read_open_filename .
+.It Fn archive_read_open_filename
+Like
+.Fn archive_read_open ,
+except that it accepts a simple filename and a block size.
+A NULL filename represents standard input.
+This function is safe for use with tape drives or other blocked devices.
+.It Fn archive_read_open_memory
+Like
+.Fn archive_read_open ,
+except that it accepts a pointer and size of a block of
+memory containing the archive data.
+.El
+.Pp
+A complete description of the
+.Tn struct archive
+and
+.Tn struct archive_entry
+objects can be found in the overview manual page for
+.Xr libarchive 3 .
+.Sh CLIENT CALLBACKS
+The callback functions must match the following prototypes:
+.Bl -item -offset indent
+.It
+.Ft typedef ssize_t
+.Fo archive_read_callback
+.Fa "struct archive *"
+.Fa "void *client_data"
+.Fa "const void **buffer"
+.Fc
+.It
+.Ft typedef off_t
+.Fo archive_skip_callback
+.Fa "struct archive *"
+.Fa "void *client_data"
+.Fa "off_t request"
+.Fc
+.It
+.Ft typedef int
+.Fn archive_open_callback "struct archive *" "void *client_data"
+.It
+.Ft typedef int
+.Fn archive_close_callback "struct archive *" "void *client_data"
+.El
+.Pp
+The open callback is invoked by
+.Fn archive_open .
+It should return
+.Cm ARCHIVE_OK
+if the underlying file or data source is successfully
+opened.
+If the open fails, it should call
+.Fn archive_set_error
+to register an error code and message and return
+.Cm ARCHIVE_FATAL .
+.Pp
+The read callback is invoked whenever the library
+requires raw bytes from the archive.
+The read callback should read data into a buffer,
+set the
+.Li const void **buffer
+argument to point to the available data, and
+return a count of the number of bytes available.
+The library will invoke the read callback again
+only after it has consumed this data.
+The library imposes no constraints on the size
+of the data blocks returned.
+On end-of-file, the read callback should
+return zero.
+On error, the read callback should invoke
+.Fn archive_set_error
+to register an error code and message and
+return -1.
+.Pp
+The skip callback is invoked when the
+library wants to ignore a block of data.
+The return value is the number of bytes actually
+skipped, which may differ from the request.
+If the callback cannot skip data, it should return
+zero.
+If the skip callback is not provided (the
+function pointer is
+.Dv NULL ),
+the library will invoke the read function
+instead and simply discard the result.
+A skip callback can provide significant
+performance gains when reading uncompressed
+archives from slow disk drives or other media
+that can skip quickly.
+.Pp
+The close callback is invoked by archive_close when
+the archive processing is complete.
+The callback should return
+.Cm ARCHIVE_OK
+on success.
+On failure, the callback should invoke
+.Fn archive_set_error
+to register an error code and message and
+return
+.Cm ARCHIVE_FATAL.
+.\" .Sh EXAMPLE
+.\"
+.Sh RETURN VALUES
+These functions return
+.Cm ARCHIVE_OK
+on success, or
+.Cm ARCHIVE_FATAL .
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.\"
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_read 3 ,
+.Xr archive_read_data 3 ,
+.Xr archive_read_filter 3 ,
+.Xr archive_read_format 3 ,
+.Xr archive_read_set_options 3 ,
+.Xr archive_util 3 ,
+.Xr tar 5
diff --git a/libarchive/archive_read_open_fd.c b/libarchive/archive_read_open_fd.c
index 9660da8f9600..d8f657295789 100644
--- a/libarchive/archive_read_open_fd.c
+++ b/libarchive/archive_read_open_fd.c
@@ -53,17 +53,13 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_open_fd.c 201103 2009-12-28
struct read_fd_data {
int fd;
size_t block_size;
- char can_skip;
+ char use_lseek;
void *buffer;
};
static int file_close(struct archive *, void *);
static ssize_t file_read(struct archive *, void *, const void **buff);
-#if ARCHIVE_API_VERSION < 2
-static ssize_t file_skip(struct archive *, void *, size_t request);
-#else
-static off_t file_skip(struct archive *, void *, off_t request);
-#endif
+static int64_t file_skip(struct archive *, void *, int64_t request);
int
archive_read_open_fd(struct archive *a, int fd, size_t block_size)
@@ -78,7 +74,7 @@ archive_read_open_fd(struct archive *a, int fd, size_t block_size)
return (ARCHIVE_FATAL);
}
- mine = (struct read_fd_data *)malloc(sizeof(*mine));
+ mine = (struct read_fd_data *)calloc(1, sizeof(*mine));
b = malloc(block_size);
if (mine == NULL || b == NULL) {
archive_set_error(a, ENOMEM, "No memory");
@@ -98,15 +94,17 @@ archive_read_open_fd(struct archive *a, int fd, size_t block_size)
*/
if (S_ISREG(st.st_mode)) {
archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino);
- mine->can_skip = 1;
- } else
- mine->can_skip = 0;
+ mine->use_lseek = 1;
+ }
#if defined(__CYGWIN__) || defined(_WIN32)
setmode(mine->fd, O_BINARY);
#endif
- return (archive_read_open2(a, mine,
- NULL, file_read, file_skip, file_close));
+ archive_read_set_read_callback(a, file_read);
+ archive_read_set_skip_callback(a, file_skip);
+ archive_read_set_close_callback(a, file_close);
+ archive_read_set_callback_data(a, mine);
+ return (archive_read_open1(a));
}
static ssize_t
@@ -127,55 +125,48 @@ file_read(struct archive *a, void *client_data, const void **buff)
}
}
-#if ARCHIVE_API_VERSION < 2
-static ssize_t
-file_skip(struct archive *a, void *client_data, size_t request)
-#else
-static off_t
-file_skip(struct archive *a, void *client_data, off_t request)
-#endif
+static int64_t
+file_skip(struct archive *a, void *client_data, int64_t request)
{
struct read_fd_data *mine = (struct read_fd_data *)client_data;
+ off_t skip = (off_t)request;
off_t old_offset, new_offset;
+ int skip_bits = sizeof(skip) * 8 - 1; /* off_t is a signed type. */
- if (!mine->can_skip)
+ if (!mine->use_lseek)
return (0);
+ /* Reduce a request that would overflow the 'skip' variable. */
+ if (sizeof(request) > sizeof(skip)) {
+ int64_t max_skip =
+ (((int64_t)1 << (skip_bits - 1)) - 1) * 2 + 1;
+ if (request > max_skip)
+ skip = max_skip;
+ }
+
/* Reduce request to the next smallest multiple of block_size */
request = (request / mine->block_size) * mine->block_size;
if (request == 0)
return (0);
+ if (((old_offset = lseek(mine->fd, 0, SEEK_CUR)) >= 0) &&
+ ((new_offset = lseek(mine->fd, skip, SEEK_CUR)) >= 0))
+ return (new_offset - old_offset);
+
+ /* If seek failed once, it will probably fail again. */
+ mine->use_lseek = 0;
+
+ /* Let libarchive recover with read+discard. */
+ if (errno == ESPIPE)
+ return (0);
+
/*
- * Hurray for lazy evaluation: if the first lseek fails, the second
- * one will not be executed.
+ * There's been an error other than ESPIPE. This is most
+ * likely caused by a programmer error (too large request)
+ * or a corrupted archive file.
*/
- if (((old_offset = lseek(mine->fd, 0, SEEK_CUR)) < 0) ||
- ((new_offset = lseek(mine->fd, request, SEEK_CUR)) < 0))
- {
- /* If seek failed once, it will probably fail again. */
- mine->can_skip = 0;
-
- if (errno == ESPIPE)
- {
- /*
- * Failure to lseek() can be caused by the file
- * descriptor pointing to a pipe, socket or FIFO.
- * Return 0 here, so the compression layer will use
- * read()s instead to advance the file descriptor.
- * It's slower of course, but works as well.
- */
- return (0);
- }
- /*
- * There's been an error other than ESPIPE. This is most
- * likely caused by a programmer error (too large request)
- * or a corrupted archive file.
- */
- archive_set_error(a, errno, "Error seeking");
- return (-1);
- }
- return (new_offset - old_offset);
+ archive_set_error(a, errno, "Error seeking");
+ return (-1);
}
static int
diff --git a/libarchive/archive_read_open_file.c b/libarchive/archive_read_open_file.c
index 095ae6eb5ce0..b1aac0a7cbf0 100644
--- a/libarchive/archive_read_open_file.c
+++ b/libarchive/archive_read_open_file.c
@@ -59,11 +59,7 @@ struct read_FILE_data {
static int file_close(struct archive *, void *);
static ssize_t file_read(struct archive *, void *, const void **buff);
-#if ARCHIVE_API_VERSION < 2
-static ssize_t file_skip(struct archive *, void *, size_t request);
-#else
-static off_t file_skip(struct archive *, void *, off_t request);
-#endif
+static int64_t file_skip(struct archive *, void *, int64_t request);
int
archive_read_open_FILE(struct archive *a, FILE *f)
@@ -101,8 +97,11 @@ archive_read_open_FILE(struct archive *a, FILE *f)
setmode(fileno(mine->f), O_BINARY);
#endif
- return (archive_read_open2(a, mine, NULL, file_read,
- file_skip, file_close));
+ archive_read_set_read_callback(a, file_read);
+ archive_read_set_skip_callback(a, file_skip);
+ archive_read_set_close_callback(a, file_close);
+ archive_read_set_callback_data(a, mine);
+ return (archive_read_open1(a));
}
static ssize_t
@@ -119,15 +118,18 @@ file_read(struct archive *a, void *client_data, const void **buff)
return (bytes_read);
}
-#if ARCHIVE_API_VERSION < 2
-static ssize_t
-file_skip(struct archive *a, void *client_data, size_t request)
-#else
-static off_t
-file_skip(struct archive *a, void *client_data, off_t request)
-#endif
+static int64_t
+file_skip(struct archive *a, void *client_data, int64_t request)
{
struct read_FILE_data *mine = (struct read_FILE_data *)client_data;
+#if HAVE_FSEEKO
+ off_t skip = (off_t)request;
+#elif HAVE__FSEEKI64
+ int64_t skip = request;
+#else
+ long skip = (long)request;
+#endif
+ int skip_bits = sizeof(skip) * 8 - 1;
(void)a; /* UNUSED */
@@ -140,10 +142,20 @@ file_skip(struct archive *a, void *client_data, off_t request)
if (request == 0)
return (0);
+ /* If request is too big for a long or an off_t, reduce it. */
+ if (sizeof(request) > sizeof(skip)) {
+ int64_t max_skip =
+ (((int64_t)1 << (skip_bits - 1)) - 1) * 2 + 1;
+ if (request > max_skip)
+ skip = max_skip;
+ }
+
#if HAVE_FSEEKO
- if (fseeko(mine->f, request, SEEK_CUR) != 0)
+ if (fseeko(mine->f, skip, SEEK_CUR) != 0)
+#elif HAVE__FSEEKI64
+ if (_fseeki64(mine->f, skip, SEEK_CUR) != 0)
#else
- if (fseek(mine->f, request, SEEK_CUR) != 0)
+ if (fseek(mine->f, skip, SEEK_CUR) != 0)
#endif
{
mine->can_skip = 0;
diff --git a/libarchive/archive_read_open_filename.c b/libarchive/archive_read_open_filename.c
index 74f3e60c43ed..bf5269724996 100644
--- a/libarchive/archive_read_open_filename.c
+++ b/libarchive/archive_read_open_filename.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2003-2010 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,6 +26,9 @@
#include "archive_platform.h"
__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_open_filename.c 201093 2009-12-28 02:28:44Z kientzle $");
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
@@ -47,8 +50,17 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_open_filename.c 201093 2009
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#include <sys/disk.h>
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+#include <sys/disklabel.h>
+#include <sys/dkio.h>
+#elif defined(__DragonFly__)
+#include <sys/diskslice.h>
+#endif
#include "archive.h"
+#include "archive_string.h"
#ifndef O_BINARY
#define O_BINARY 0
@@ -59,17 +71,21 @@ struct read_file_data {
size_t block_size;
void *buffer;
mode_t st_mode; /* Mode bits for opened file. */
- char can_skip; /* This file supports skipping. */
- char filename[1]; /* Must be last! */
+ char use_lseek;
+ enum fnt_e { FNT_STDIN, FNT_MBS, FNT_WCS } filename_type;
+ union {
+ char m[1];/* MBS filename. */
+ wchar_t w[1];/* WCS filename. */
+ } filename; /* Must be last! */
};
static int file_close(struct archive *, void *);
+static int file_open_filename(struct archive *, enum fnt_e, const void *,
+ size_t);
static ssize_t file_read(struct archive *, void *, const void **buff);
-#if ARCHIVE_API_VERSION < 2
-static ssize_t file_skip(struct archive *, void *, size_t request);
-#else
-static off_t file_skip(struct archive *, void *, off_t request);
-#endif
+static int64_t file_seek(struct archive *, void *, int64_t request, int);
+static int64_t file_skip(struct archive *, void *, int64_t request);
+static int64_t file_skip_lseek(struct archive *, void *, int64_t request);
int
archive_read_open_file(struct archive *a, const char *filename,
@@ -82,14 +98,75 @@ int
archive_read_open_filename(struct archive *a, const char *filename,
size_t block_size)
{
+ enum fnt_e filename_type;
+
+ if (filename == NULL || filename[0] == '\0') {
+ filename_type = FNT_STDIN;
+ } else
+ filename_type = FNT_MBS;
+ return (file_open_filename(a, filename_type, filename, block_size));
+}
+
+int
+archive_read_open_filename_w(struct archive *a, const wchar_t *wfilename,
+ size_t block_size)
+{
+ enum fnt_e filename_type;
+
+ if (wfilename == NULL || wfilename[0] == L'\0') {
+ filename_type = FNT_STDIN;
+ } else {
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ filename_type = FNT_WCS;
+#else
+ /*
+ * POSIX system does not support a wchar_t interface for
+ * open() system call, so we have to translate a whcar_t
+ * filename to multi-byte one and use it.
+ */
+ struct archive_string fn;
+ int r;
+
+ archive_string_init(&fn);
+ if (archive_string_append_from_wcs(&fn, wfilename,
+ wcslen(wfilename)) != 0) {
+ archive_set_error(a, EINVAL,
+ "Failed to convert a wide-character filename to"
+ " a multi-byte filename");
+ archive_string_free(&fn);
+ return (ARCHIVE_FATAL);
+ }
+ r = file_open_filename(a, FNT_MBS, fn.s, block_size);
+ archive_string_free(&fn);
+ return (r);
+#endif
+ }
+ return (file_open_filename(a, filename_type, wfilename, block_size));
+}
+
+static int
+file_open_filename(struct archive *a, enum fnt_e filename_type,
+ const void *_filename, size_t block_size)
+{
struct stat st;
struct read_file_data *mine;
- void *b;
+ void *buffer;
+ const char *filename = NULL;
+ const wchar_t *wfilename = NULL;
int fd;
+ int is_disk_like = 0;
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+ off_t mediasize = 0; /* FreeBSD-specific, so off_t okay here. */
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+ struct disklabel dl;
+#elif defined(__DragonFly__)
+ struct partinfo pi;
+#endif
archive_clear_error(a);
- if (filename == NULL || filename[0] == '\0') {
- /* We used to invoke archive_read_open_fd(a,0,block_size)
+ if (filename_type == FNT_STDIN) {
+ /* We used to delegate stdin support by
+ * directly calling archive_read_open_fd(a,0,block_size)
* here, but that doesn't (and shouldn't) handle the
* end-of-file flush when reading stdout from a pipe.
* Basically, read_open_fd() is intended for folks who
@@ -97,60 +174,152 @@ archive_read_open_filename(struct archive *a, const char *filename,
* API is intended to be a little smarter for folks who
* want easy handling of the common case.
*/
- filename = ""; /* Normalize NULL to "" */
fd = 0;
#if defined(__CYGWIN__) || defined(_WIN32)
setmode(0, O_BINARY);
#endif
- } else {
+ filename = "";
+ } else if (filename_type == FNT_MBS) {
+ filename = (const char *)_filename;
fd = open(filename, O_RDONLY | O_BINARY);
if (fd < 0) {
archive_set_error(a, errno,
"Failed to open '%s'", filename);
return (ARCHIVE_FATAL);
}
+ } else {
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ wfilename = (const wchar_t *)_filename;
+ fd = _wopen(wfilename, O_RDONLY | O_BINARY);
+ if (fd < 0 && errno == ENOENT) {
+ wchar_t *fullpath;
+ fullpath = __la_win_permissive_name_w(wfilename);
+ if (fullpath != NULL) {
+ fd = _wopen(fullpath, O_RDONLY | O_BINARY);
+ free(fullpath);
+ }
+ }
+ if (fd < 0) {
+ archive_set_error(a, errno,
+ "Failed to open '%S'", wfilename);
+ return (ARCHIVE_FATAL);
+ }
+#else
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Unexpedted operation in archive_read_open_filename");
+ return (ARCHIVE_FATAL);
+#endif
}
if (fstat(fd, &st) != 0) {
- archive_set_error(a, errno, "Can't stat '%s'", filename);
+ if (filename_type == FNT_WCS)
+ archive_set_error(a, errno, "Can't stat '%S'",
+ wfilename);
+ else
+ archive_set_error(a, errno, "Can't stat '%s'",
+ filename);
return (ARCHIVE_FATAL);
}
- mine = (struct read_file_data *)calloc(1,
- sizeof(*mine) + strlen(filename));
- b = malloc(block_size);
- if (mine == NULL || b == NULL) {
+ /*
+ * Determine whether the input looks like a disk device or a
+ * tape device. The results are used below to select an I/O
+ * strategy:
+ * = "disk-like" devices support arbitrary lseek() and will
+ * support I/O requests of any size. So we get easy skipping
+ * and can cheat on block sizes to get better performance.
+ * = "tape-like" devices require strict blocking and use
+ * specialized ioctls for seeking.
+ * = "socket-like" devices cannot seek at all but can improve
+ * performance by using nonblocking I/O to read "whatever is
+ * available right now".
+ *
+ * Right now, we only specially recognize disk-like devices,
+ * but it should be straightforward to add probes and strategy
+ * here for tape-like and socket-like devices.
+ */
+ if (S_ISREG(st.st_mode)) {
+ /* Safety: Tell the extractor not to overwrite the input. */
+ archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino);
+ /* Regular files act like disks. */
+ is_disk_like = 1;
+ }
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+ /* FreeBSD: if it supports DIOCGMEDIASIZE ioctl, it's disk-like. */
+ else if (S_ISCHR(st.st_mode) &&
+ ioctl(fd, DIOCGMEDIASIZE, &mediasize) == 0 &&
+ mediasize > 0) {
+ is_disk_like = 1;
+ }
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+ /* Net/OpenBSD: if it supports DIOCGDINFO ioctl, it's disk-like. */
+ else if ((S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) &&
+ ioctl(fd, DIOCGDINFO, &dl) == 0 &&
+ dl.d_partitions[DISKPART(st.st_rdev)].p_size > 0) {
+ is_disk_like = 1;
+ }
+#elif defined(__DragonFly__)
+ /* DragonFly BSD: if it supports DIOCGPART ioctl, it's disk-like. */
+ else if (S_ISCHR(st.st_mode) &&
+ ioctl(fd, DIOCGPART, &pi) == 0 &&
+ pi.media_size > 0) {
+ is_disk_like = 1;
+ }
+#elif defined(__linux__)
+ /* Linux: All block devices are disk-like. */
+ else if (S_ISBLK(st.st_mode) &&
+ lseek(fd, 0, SEEK_CUR) == 0 &&
+ lseek(fd, 0, SEEK_SET) == 0 &&
+ lseek(fd, 0, SEEK_END) > 0 &&
+ lseek(fd, 0, SEEK_SET) == 0) {
+ is_disk_like = 1;
+ }
+#endif
+ /* TODO: Add an "is_tape_like" variable and appropriate tests. */
+
+ if (filename_type == FNT_WCS)
+ mine = (struct read_file_data *)calloc(1,
+ sizeof(*mine) + wcslen(wfilename) * sizeof(wchar_t));
+ else
+ mine = (struct read_file_data *)calloc(1,
+ sizeof(*mine) + strlen(filename));
+ /* Disk-like devices prefer power-of-two block sizes. */
+ /* Use provided block_size as a guide so users have some control. */
+ if (is_disk_like) {
+ size_t new_block_size = 64 * 1024;
+ while (new_block_size < block_size
+ && new_block_size < 64 * 1024 * 1024)
+ new_block_size *= 2;
+ block_size = new_block_size;
+ }
+ buffer = malloc(block_size);
+ if (mine == NULL || buffer == NULL) {
archive_set_error(a, ENOMEM, "No memory");
free(mine);
- free(b);
+ free(buffer);
return (ARCHIVE_FATAL);
}
- strcpy(mine->filename, filename);
+ if (filename_type == FNT_WCS)
+ wcscpy(mine->filename.w, wfilename);
+ else
+ strcpy(mine->filename.m, filename);
+ mine->filename_type = filename_type;
mine->block_size = block_size;
- mine->buffer = b;
+ mine->buffer = buffer;
mine->fd = fd;
/* Remember mode so close can decide whether to flush. */
mine->st_mode = st.st_mode;
- /* If we're reading a file from disk, ensure that we don't
- overwrite it with an extracted file. */
- if (S_ISREG(st.st_mode)) {
- archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino);
- /*
- * Enabling skip here is a performance optimization
- * for anything that supports lseek(). On FreeBSD
- * (and probably many other systems), only regular
- * files and raw disk devices support lseek() (on
- * other input types, lseek() returns success but
- * doesn't actually change the file pointer, which
- * just completely screws up the position-tracking
- * logic). In addition, I've yet to find a portable
- * way to determine if a device is a raw disk device.
- * So I don't see a way to do much better than to only
- * enable this optimization for regular files.
- */
- mine->can_skip = 1;
+
+ /* Disk-like inputs can use lseek(). */
+ if (is_disk_like) {
+ archive_read_set_seek_callback(a, file_seek);
+ mine->use_lseek = 1;
}
- return (archive_read_open2(a, mine,
- NULL, file_read, file_skip, file_close));
+
+ archive_read_set_read_callback(a, file_read);
+ archive_read_set_skip_callback(a, file_skip);
+ archive_read_set_close_callback(a, file_close);
+ archive_read_set_callback_data(a, mine);
+ return (archive_read_open1(a));
}
static ssize_t
@@ -159,79 +328,146 @@ file_read(struct archive *a, void *client_data, const void **buff)
struct read_file_data *mine = (struct read_file_data *)client_data;
ssize_t bytes_read;
+ /* TODO: If a recent lseek() operation has left us
+ * mis-aligned, read and return a short block to try to get
+ * us back in alignment. */
+
+ /* TODO: Someday, try mmap() here; if that succeeds, give
+ * the entire file to libarchive as a single block. That
+ * could be a lot faster than block-by-block manual I/O. */
+
+ /* TODO: We might be able to improve performance on pipes and
+ * sockets by setting non-blocking I/O and just accepting
+ * whatever we get here instead of waiting for a full block
+ * worth of data. */
+
*buff = mine->buffer;
for (;;) {
bytes_read = read(mine->fd, mine->buffer, mine->block_size);
if (bytes_read < 0) {
if (errno == EINTR)
continue;
- else if (mine->filename[0] == '\0')
- archive_set_error(a, errno, "Error reading stdin");
+ else if (mine->filename_type == FNT_STDIN)
+ archive_set_error(a, errno,
+ "Error reading stdin");
+ else if (mine->filename_type == FNT_MBS)
+ archive_set_error(a, errno,
+ "Error reading '%s'", mine->filename.m);
else
- archive_set_error(a, errno, "Error reading '%s'",
- mine->filename);
+ archive_set_error(a, errno,
+ "Error reading '%S'", mine->filename.w);
}
return (bytes_read);
}
}
-#if ARCHIVE_API_VERSION < 2
-static ssize_t
-file_skip(struct archive *a, void *client_data, size_t request)
-#else
-static off_t
-file_skip(struct archive *a, void *client_data, off_t request)
-#endif
+/*
+ * Regular files and disk-like block devices can use simple lseek
+ * without needing to round the request to the block size.
+ *
+ * TODO: This can leave future reads mis-aligned. Since we know the
+ * offset here, we should store it and use it in file_read() above
+ * to determine whether we should perform a short read to get back
+ * into alignment. Long series of mis-aligned reads can negatively
+ * impact disk throughput. (Of course, the performance impact should
+ * be carefully tested; extra code complexity is only worthwhile if
+ * it does provide measurable improvement.)
+ *
+ * TODO: Be lazy about the actual seek. There are a few pathological
+ * cases where libarchive makes a bunch of seek requests in a row
+ * without any intervening reads. This isn't a huge performance
+ * problem, since the kernel handles seeks lazily already, but
+ * it would be very slightly faster if we simply remembered the
+ * seek request here and then actually performed the seek at the
+ * top of the read callback above.
+ */
+static int64_t
+file_skip_lseek(struct archive *a, void *client_data, int64_t request)
{
struct read_file_data *mine = (struct read_file_data *)client_data;
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ /* We use _lseeki64() on Windows. */
+ int64_t old_offset, new_offset;
+#else
off_t old_offset, new_offset;
+#endif
+
+ /* We use off_t here because lseek() is declared that way. */
+
+ /* TODO: Deal with case where off_t isn't 64 bits.
+ * This shouldn't be a problem on Linux or other POSIX
+ * systems, since the configuration logic for libarchive
+ * tries to obtain a 64-bit off_t. It's still an issue
+ * on Windows, though, so it might suffice to just use
+ * _lseeki64() on Windows.
+ */
+ if ((old_offset = lseek(mine->fd, 0, SEEK_CUR)) >= 0 &&
+ (new_offset = lseek(mine->fd, request, SEEK_CUR)) >= 0)
+ return (new_offset - old_offset);
- if (!mine->can_skip) /* We can't skip, so ... */
- return (0); /* ... skip zero bytes. */
+ /* If lseek() fails, don't bother trying again. */
+ mine->use_lseek = 0;
- /* Reduce request to the next smallest multiple of block_size */
- request = (request / mine->block_size) * mine->block_size;
- if (request == 0)
+ /* Let libarchive recover with read+discard */
+ if (errno == ESPIPE)
return (0);
- /*
- * Hurray for lazy evaluation: if the first lseek fails, the second
- * one will not be executed.
- */
- if (((old_offset = lseek(mine->fd, 0, SEEK_CUR)) < 0) ||
- ((new_offset = lseek(mine->fd, request, SEEK_CUR)) < 0))
- {
- /* If skip failed once, it will probably fail again. */
- mine->can_skip = 0;
-
- if (errno == ESPIPE)
- {
- /*
- * Failure to lseek() can be caused by the file
- * descriptor pointing to a pipe, socket or FIFO.
- * Return 0 here, so the compression layer will use
- * read()s instead to advance the file descriptor.
- * It's slower of course, but works as well.
- */
- return (0);
- }
- /*
- * There's been an error other than ESPIPE. This is most
- * likely caused by a programmer error (too large request)
- * or a corrupted archive file.
- */
- if (mine->filename[0] == '\0')
- /*
- * Should never get here, since lseek() on stdin ought
- * to return an ESPIPE error.
- */
- archive_set_error(a, errno, "Error seeking in stdin");
- else
- archive_set_error(a, errno, "Error seeking in '%s'",
- mine->filename);
- return (-1);
- }
- return (new_offset - old_offset);
+ /* If the input is corrupted or truncated, fail. */
+ if (mine->filename_type == FNT_STDIN)
+ archive_set_error(a, errno, "Error seeking in stdin");
+ else if (mine->filename_type == FNT_MBS)
+ archive_set_error(a, errno, "Error seeking in '%s'",
+ mine->filename.m);
+ else
+ archive_set_error(a, errno, "Error seeking in '%S'",
+ mine->filename.w);
+ return (-1);
+}
+
+
+/*
+ * TODO: Implement another file_skip_XXXX that uses MTIO ioctls to
+ * accelerate operation on tape drives.
+ */
+
+static int64_t
+file_skip(struct archive *a, void *client_data, int64_t request)
+{
+ struct read_file_data *mine = (struct read_file_data *)client_data;
+
+ /* Delegate skip requests. */
+ if (mine->use_lseek)
+ return (file_skip_lseek(a, client_data, request));
+
+ /* If we can't skip, return 0; libarchive will read+discard instead. */
+ return (0);
+}
+
+/*
+ * TODO: Store the offset and use it in the read callback.
+ */
+static int64_t
+file_seek(struct archive *a, void *client_data, int64_t request, int whence)
+{
+ struct read_file_data *mine = (struct read_file_data *)client_data;
+ off_t r;
+
+ /* We use off_t here because lseek() is declared that way. */
+ /* See above for notes about when off_t is less than 64 bits. */
+ r = lseek(mine->fd, request, whence);
+ if (r >= 0)
+ return r;
+
+ /* If the input is corrupted or truncated, fail. */
+ if (mine->filename_type == FNT_STDIN)
+ archive_set_error(a, errno, "Error seeking in stdin");
+ else if (mine->filename_type == FNT_MBS)
+ archive_set_error(a, errno, "Error seeking in '%s'",
+ mine->filename.m);
+ else
+ archive_set_error(a, errno, "Error seeking in '%S'",
+ mine->filename.w);
+ return (ARCHIVE_FATAL);
}
static int
@@ -246,7 +482,8 @@ file_close(struct archive *a, void *client_data)
/*
* Sometimes, we should flush the input before closing.
* Regular files: faster to just close without flush.
- * Devices: must not flush (user might need to
+ * Disk-like devices: Ditto.
+ * Tapes: must not flush (user might need to
* read the "next" item on a non-rewind device).
* Pipes and sockets: must flush (otherwise, the
* program feeding the pipe or socket may complain).
@@ -263,7 +500,7 @@ file_close(struct archive *a, void *client_data)
} while (bytesRead > 0);
}
/* If a named file was opened, then it needs to be closed. */
- if (mine->filename[0] != '\0')
+ if (mine->filename_type != FNT_STDIN)
close(mine->fd);
}
free(mine->buffer);
diff --git a/libarchive/archive_read_open_memory.c b/libarchive/archive_read_open_memory.c
index 61f574fa7705..07940a2ac0fd 100644
--- a/libarchive/archive_read_open_memory.c
+++ b/libarchive/archive_read_open_memory.c
@@ -41,18 +41,16 @@ __FBSDID("$FreeBSD: src/lib/libarchive/archive_read_open_memory.c,v 1.6 2007/07/
*/
struct read_memory_data {
- unsigned char *buffer;
+ unsigned char *start;
+ unsigned char *p;
unsigned char *end;
ssize_t read_size;
};
static int memory_read_close(struct archive *, void *);
static int memory_read_open(struct archive *, void *);
-#if ARCHIVE_API_VERSION < 2
-static ssize_t memory_read_skip(struct archive *, void *, size_t request);
-#else
-static off_t memory_read_skip(struct archive *, void *, off_t request);
-#endif
+static int64_t memory_read_seek(struct archive *, void *, int64_t offset, int whence);
+static int64_t memory_read_skip(struct archive *, void *, int64_t request);
static ssize_t memory_read(struct archive *, void *, const void **buff);
int
@@ -78,11 +76,16 @@ archive_read_open_memory2(struct archive *a, void *buff,
return (ARCHIVE_FATAL);
}
memset(mine, 0, sizeof(*mine));
- mine->buffer = (unsigned char *)buff;
- mine->end = mine->buffer + size;
+ mine->start = mine->p = (unsigned char *)buff;
+ mine->end = mine->start + size;
mine->read_size = read_size;
- return (archive_read_open2(a, mine, memory_read_open,
- memory_read, memory_read_skip, memory_read_close));
+ archive_read_set_open_callback(a, memory_read_open);
+ archive_read_set_read_callback(a, memory_read);
+ archive_read_set_seek_callback(a, memory_read_seek);
+ archive_read_set_skip_callback(a, memory_read_skip);
+ archive_read_set_close_callback(a, memory_read_close);
+ archive_read_set_callback_data(a, mine);
+ return (archive_read_open1(a));
}
/*
@@ -110,11 +113,11 @@ memory_read(struct archive *a, void *client_data, const void **buff)
ssize_t size;
(void)a; /* UNUSED */
- *buff = mine->buffer;
- size = mine->end - mine->buffer;
+ *buff = mine->p;
+ size = mine->end - mine->p;
if (size > mine->read_size)
size = mine->read_size;
- mine->buffer += size;
+ mine->p += size;
return (size);
}
@@ -123,27 +126,54 @@ memory_read(struct archive *a, void *client_data, const void **buff)
* necessary in order to better exercise internal code when used
* as a test harness.
*/
-#if ARCHIVE_API_VERSION < 2
-static ssize_t
-memory_read_skip(struct archive *a, void *client_data, size_t skip)
-#else
-static off_t
-memory_read_skip(struct archive *a, void *client_data, off_t skip)
-#endif
+static int64_t
+memory_read_skip(struct archive *a, void *client_data, int64_t skip)
{
struct read_memory_data *mine = (struct read_memory_data *)client_data;
(void)a; /* UNUSED */
- if ((off_t)skip > (off_t)(mine->end - mine->buffer))
- skip = mine->end - mine->buffer;
+ if ((int64_t)skip > (int64_t)(mine->end - mine->p))
+ skip = mine->end - mine->p;
/* Round down to block size. */
skip /= mine->read_size;
skip *= mine->read_size;
- mine->buffer += skip;
+ mine->p += skip;
return (skip);
}
/*
+ * Seeking.
+ */
+static int64_t
+memory_read_seek(struct archive *a, void *client_data, int64_t offset, int whence)
+{
+ struct read_memory_data *mine = (struct read_memory_data *)client_data;
+
+ switch (whence) {
+ case SEEK_SET:
+ mine->p = mine->start + offset;
+ break;
+ case SEEK_CUR:
+ mine->p += offset;
+ break;
+ case SEEK_END:
+ mine->p = mine->end + offset;
+ break;
+ default:
+ return ARCHIVE_FATAL;
+ }
+ if (mine->p < mine->start) {
+ mine->p = mine->start;
+ return ARCHIVE_FAILED;
+ }
+ if (mine->p > mine->end) {
+ mine->p = mine->end;
+ return ARCHIVE_FAILED;
+ }
+ return (mine->p - mine->start);
+}
+
+/*
* Close is just cleaning up our one small bit of data.
*/
static int
diff --git a/libarchive/archive_read_private.h b/libarchive/archive_read_private.h
index 5a850189042a..76d0b91d9e75 100644
--- a/libarchive/archive_read_private.h
+++ b/libarchive/archive_read_private.h
@@ -42,13 +42,18 @@ struct archive_read_filter;
/*
* How bidding works for filters:
- * * The bid manager reads the first block from the current source.
- * * It shows that block to each registered bidder.
+ * * The bid manager initializes the client-provided reader as the
+ * first filter.
+ * * It invokes the bidder for each registered filter with the
+ * current head filter.
+ * * The bidders can use archive_read_filter_ahead() to peek ahead
+ * at the incoming data to compose their bids.
* * The bid manager creates a new filter structure for the winning
* bidder and gives the winning bidder a chance to initialize it.
- * * The new filter becomes the top filter in the archive_read structure
- * and we repeat the process.
- * This ends only when no bidder provides a non-zero bid.
+ * * The new filter becomes the new top filter and we repeat the
+ * process.
+ * This ends only when no bidder provides a non-zero bid. Then
+ * we perform a similar dance with the registered format handlers.
*/
struct archive_read_filter_bidder {
/* Configuration data for the bidder. */
@@ -71,6 +76,7 @@ struct archive_read_filter_bidder {
* corresponding bidder above.
*/
struct archive_read_filter {
+ int64_t position;
/* Essentially all filters will need these values, so
* just declare them here. */
struct archive_read_filter_bidder *bidder; /* My bidder. */
@@ -80,6 +86,8 @@ struct archive_read_filter {
ssize_t (*read)(struct archive_read_filter *, const void **);
/* Skip forward this many bytes. */
int64_t (*skip)(struct archive_read_filter *self, int64_t request);
+ /* Seek to an absolute location. */
+ int64_t (*seek)(struct archive_read_filter *self, int64_t offset, int whence);
/* Close (just this filter) and free(self). */
int (*close)(struct archive_read_filter *self);
/* My private data. */
@@ -97,8 +105,8 @@ struct archive_read_filter {
size_t client_total;
const char *client_next;
size_t client_avail;
- int64_t position;
char end_of_file;
+ char closed;
char fatal;
};
@@ -111,9 +119,12 @@ struct archive_read_filter {
* so should be deferred at least until libarchive 3.0.
*/
struct archive_read_client {
+ archive_open_callback *opener;
archive_read_callback *reader;
archive_skip_callback *skipper;
+ archive_seek_callback *seeker;
archive_close_callback *closer;
+ void *data;
};
struct archive_read {
@@ -122,6 +133,7 @@ struct archive_read {
struct archive_entry *entry;
/* Dev/ino of the archive being read/written. */
+ int skip_file_set;
dev_t skip_file_dev;
ino_t skip_file_ino;
@@ -130,21 +142,21 @@ struct archive_read {
* data to client buffers, filling gaps with zero bytes.
*/
const char *read_data_block;
- off_t read_data_offset;
- off_t read_data_output_offset;
+ int64_t read_data_offset;
+ int64_t read_data_output_offset;
size_t read_data_remaining;
/* Callbacks to open/read/write/close client archive stream. */
struct archive_read_client client;
/* Registered filter bidders. */
- struct archive_read_filter_bidder bidders[8];
+ struct archive_read_filter_bidder bidders[9];
/* Last filter in chain */
struct archive_read_filter *filter;
/* File offset of beginning of most recently-read header. */
- off_t header_position;
+ int64_t header_position;
/*
* Format detection is mostly the same as compression
@@ -157,14 +169,14 @@ struct archive_read {
struct archive_format_descriptor {
void *data;
const char *name;
- int (*bid)(struct archive_read *);
+ int (*bid)(struct archive_read *, int best_bid);
int (*options)(struct archive_read *, const char *key,
const char *value);
int (*read_header)(struct archive_read *, struct archive_entry *);
- int (*read_data)(struct archive_read *, const void **, size_t *, off_t *);
+ int (*read_data)(struct archive_read *, const void **, size_t *, int64_t *);
int (*read_data_skip)(struct archive_read *);
int (*cleanup)(struct archive_read *);
- } formats[9];
+ } formats[16];
struct archive_format_descriptor *format; /* Active format. */
/*
@@ -177,23 +189,22 @@ struct archive_read {
int __archive_read_register_format(struct archive_read *a,
void *format_data,
const char *name,
- int (*bid)(struct archive_read *),
+ int (*bid)(struct archive_read *, int),
int (*options)(struct archive_read *, const char *, const char *),
int (*read_header)(struct archive_read *, struct archive_entry *),
- int (*read_data)(struct archive_read *, const void **, size_t *, off_t *),
+ int (*read_data)(struct archive_read *, const void **, size_t *, int64_t *),
int (*read_data_skip)(struct archive_read *),
int (*cleanup)(struct archive_read *));
-struct archive_read_filter_bidder
- *__archive_read_get_bidder(struct archive_read *a);
+int __archive_read_get_bidder(struct archive_read *a,
+ struct archive_read_filter_bidder **bidder);
const void *__archive_read_ahead(struct archive_read *, size_t, ssize_t *);
const void *__archive_read_filter_ahead(struct archive_read_filter *,
size_t, ssize_t *);
-ssize_t __archive_read_consume(struct archive_read *, size_t);
-ssize_t __archive_read_filter_consume(struct archive_read_filter *, size_t);
-int64_t __archive_read_skip(struct archive_read *, int64_t);
-int64_t __archive_read_skip_lenient(struct archive_read *, int64_t);
-int64_t __archive_read_filter_skip(struct archive_read_filter *, int64_t);
+int64_t __archive_read_seek(struct archive_read*, int64_t, int);
+int64_t __archive_read_filter_seek(struct archive_read_filter *, int64_t, int);
+int64_t __archive_read_consume(struct archive_read *, int64_t);
+int64_t __archive_read_filter_consume(struct archive_read_filter *, int64_t);
int __archive_read_program(struct archive_read_filter *, const char *);
#endif
diff --git a/libarchive/archive_read_set_options.3 b/libarchive/archive_read_set_options.3
new file mode 100644
index 000000000000..81efb08b5af2
--- /dev/null
+++ b/libarchive/archive_read_set_options.3
@@ -0,0 +1,207 @@
+.\" Copyright (c) 2011 Tim Kientzle
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd April 13, 2009
+.Dt ARCHIVE_READ_OPTIONS 3
+.Os
+.Sh NAME
+.Nm archive_read_set_filter_option ,
+.Nm archive_read_set_format_option ,
+.Nm archive_read_set_option ,
+.Nm archive_read_set_options
+.Nd functions controlling options for reading archives
+.\"
+.Sh SYNOPSIS
+.Ft int
+.Fo archive_read_set_filter_option
+.Fa "struct archive *"
+.Fa "const char *module"
+.Fa "const char *option"
+.Fa "const char *value"
+.Fc
+.Ft int
+.Fo archive_read_set_format_option
+.Fa "struct archive *"
+.Fa "const char *module"
+.Fa "const char *option"
+.Fa "const char *value"
+.Fc
+.Ft int
+.Fo archive_read_set_option
+.Fa "struct archive *"
+.Fa "const char *module"
+.Fa "const char *option"
+.Fa "const char *value"
+.Fc
+.Ft int
+.Fo archive_read_set_options
+.Fa "struct archive *"
+.Fa "const char *options"
+.Fc
+.Sh DESCRIPTION
+These functions provide a way for libarchive clients to configure
+specific read modules.
+.Bl -tag -width indent
+.It Xo
+.Fn archive_read_set_filter_option ,
+.Fn archive_read_set_format_option
+.Xc
+Specifies an option that will be passed to currently-registered
+filters (including decompression filters) or format readers.
+.Pp
+If
+.Ar option
+and
+.Ar value
+are both
+.Dv NULL ,
+these functions will do nothing and
+.Cm ARCHIVE_OK
+will be returned.
+If
+.Ar option
+is
+.Dv NULL
+but
+.Ar value
+is not, these functions will do nothing and
+.Cm ARCHIVE_FAILED
+will be returned.
+.Pp
+If
+.Ar module
+is not
+.Dv NULL ,
+.Ar option
+and
+.Ar value
+will be provided to the filter or reader named
+.Ar module .
+The return value will be that of the module.
+If there is no such module,
+.Cm ARCHIVE_FAILED
+will be returned.
+.Pp
+If
+.Ar module
+is
+.Dv NULL ,
+.Ar option
+and
+.Ar value
+will be provided to every registered module.
+If any module returns
+.Cm ARCHIVE_FATAL ,
+this value will be returned immediately.
+Otherwise,
+.Cm ARCHIVE_OK
+will be returned if any module accepts the option, and
+.Cm ARCHIVE_FAILED
+in all other cases.
+.\"
+.It Xo
+.Fn archive_read_set_option
+.Xc
+Calls
+.Fn archive_read_set_format_option ,
+then
+.Fn archive_read_set_filter_option .
+If either function returns
+.Cm ARCHIVE_FATAL ,
+.Cm ARCHIVE_FATAL
+will be returned
+immediately.
+Otherwise, greater of the two values will be returned.
+.\"
+.It Xo
+.Fn archive_read_set_options
+.Xc
+.Ar options
+is a comma-separated list of options.
+If
+.Ar options
+is
+.Dv NULL
+or empty,
+.Cm ARCHIVE_OK
+will be returned immediately.
+.Pp
+Calls
+.Fn archive_read_set_option
+with each option in turn.
+If any
+.Fn archive_read_set_option
+call returns
+.Cm ARCHIVE_FATAL ,
+.Cm ARCHIVE_FATAL
+will be returned immediately.
+.Pp
+Individual options have one of the following forms:
+.Bl -tag -compact -width indent
+.It Ar option=value
+The option/value pair will be provided to every module.
+Modules that do not accept an option with this name will ignore it.
+.It Ar option
+The option will be provided to every module with a value of
+.Dq 1 .
+.It Ar !option
+The option will be provided to every module with a NULL value.
+.It Ar module:option=value , Ar module:option , Ar module:!option
+As above, but the corresponding option and value will be provided
+only to modules whose name matches
+.Ar module .
+.El
+.El
+.\"
+.Sh OPTIONS
+.Bl -tag -compact -width indent
+.It Format iso9660
+.Bl -tag -compact -width indent
+.It Cm joliet
+Support Joliet extensions.
+Defaults to enabled, use
+.Cm !joliet
+to disable.
+.It Cm rockridge
+Support RockRidge extensions.
+Defaults to enabled, use
+.Cm !rockridge
+to disable.
+.El
+.El
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.\"
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_write_set_options 3 ,
+.Xr archive_read 3
diff --git a/libarchive/archive_read_set_options.c b/libarchive/archive_read_set_options.c
new file mode 100644
index 000000000000..d6a5f45cca5f
--- /dev/null
+++ b/libarchive/archive_read_set_options.c
@@ -0,0 +1,148 @@
+/*-
+ * Copyright (c) 2011 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+__FBSDID("$FreeBSD$");
+
+#include "archive_read_private.h"
+#include "archive_options_private.h"
+
+static int archive_set_format_option(struct archive *a,
+ const char *m, const char *o, const char *v);
+static int archive_set_filter_option(struct archive *a,
+ const char *m, const char *o, const char *v);
+static int archive_set_option(struct archive *a,
+ const char *m, const char *o, const char *v);
+
+int
+archive_read_set_format_option(struct archive *a, const char *m, const char *o,
+ const char *v)
+{
+ return _archive_set_option(a, m, o, v,
+ ARCHIVE_READ_MAGIC, "archive_read_set_format_option",
+ archive_set_format_option);
+}
+
+int
+archive_read_set_filter_option(struct archive *a, const char *m, const char *o,
+ const char *v)
+{
+ return _archive_set_option(a, m, o, v,
+ ARCHIVE_READ_MAGIC, "archive_read_set_filter_option",
+ archive_set_filter_option);
+}
+
+int
+archive_read_set_option(struct archive *a, const char *m, const char *o,
+ const char *v)
+{
+ return _archive_set_option(a, m, o, v,
+ ARCHIVE_READ_MAGIC, "archive_read_set_option",
+ archive_set_option);
+}
+
+int
+archive_read_set_options(struct archive *a, const char *options)
+{
+ return _archive_set_options(a, options,
+ ARCHIVE_READ_MAGIC, "archive_read_set_options",
+ archive_set_option);
+}
+
+static int
+archive_set_format_option(struct archive *_a, const char *m, const char *o,
+ const char *v)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct archive_format_descriptor *format;
+ size_t i;
+ int r, rv = ARCHIVE_FAILED;
+
+ for (i = 0; i < sizeof(a->formats)/sizeof(a->formats[0]); i++) {
+ format = &a->formats[i];
+ if (format == NULL || format->options == NULL ||
+ format->name == NULL)
+ /* This format does not support option. */
+ continue;
+ if (m != NULL && strcmp(format->name, m) != 0)
+ continue;
+
+ a->format = format;
+ r = format->options(a, o, v);
+ a->format = NULL;
+
+ if (r == ARCHIVE_FATAL)
+ return (ARCHIVE_FATAL);
+
+ if (m != NULL)
+ return (r);
+
+ if (r == ARCHIVE_OK)
+ rv = ARCHIVE_OK;
+ }
+ return (rv);
+}
+
+static int
+archive_set_filter_option(struct archive *_a, const char *m, const char *o,
+ const char *v)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct archive_read_filter *filter;
+ struct archive_read_filter_bidder *bidder;
+ int r, rv = ARCHIVE_FAILED;
+
+ for (filter = a->filter; filter != NULL; filter = filter->upstream) {
+ bidder = filter->bidder;
+ if (bidder == NULL)
+ continue;
+ if (bidder->options == NULL)
+ /* This bidder does not support option */
+ continue;
+ if (m != NULL && strcmp(filter->name, m) != 0)
+ continue;
+
+ r = bidder->options(bidder, o, v);
+
+ if (r == ARCHIVE_FATAL)
+ return (ARCHIVE_FATAL);
+
+ if (m != NULL)
+ return (r);
+
+ if (r == ARCHIVE_OK)
+ rv = ARCHIVE_OK;
+ }
+ return (rv);
+}
+
+static int
+archive_set_option(struct archive *a, const char *m, const char *o,
+ const char *v)
+{
+ return _archive_set_either_option(a, m, o, v,
+ archive_set_format_option,
+ archive_set_filter_option);
+}
diff --git a/libarchive/archive_read_support_compression_all.c b/libarchive/archive_read_support_filter_all.c
index a6db7364d098..733d86298434 100644
--- a/libarchive/archive_read_support_compression_all.c
+++ b/libarchive/archive_read_support_filter_all.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2003-2011 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,30 +24,45 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_compression_all.c 201248 2009-12-30 06:12:03Z kientzle $");
+__FBSDID("$FreeBSD$");
#include "archive.h"
+#include "archive_private.h"
+#if ARCHIVE_VERSION_NUMBER < 4000000
+/* Deprecated; remove in libarchive 4.0 */
int
archive_read_support_compression_all(struct archive *a)
{
+ return archive_read_support_filter_all(a);
+}
+#endif
+
+int
+archive_read_support_filter_all(struct archive *a)
+{
+ archive_check_magic(a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_filter_all");
+
/* Bzip falls back to "bunzip2" command-line */
- archive_read_support_compression_bzip2(a);
+ archive_read_support_filter_bzip2(a);
/* The decompress code doesn't use an outside library. */
- archive_read_support_compression_compress(a);
+ archive_read_support_filter_compress(a);
/* Gzip decompress falls back to "gunzip" command-line. */
- archive_read_support_compression_gzip(a);
+ archive_read_support_filter_gzip(a);
+ /* Lzip falls back to "unlzip" command-line program. */
+ archive_read_support_filter_lzip(a);
/* The LZMA file format has a very weak signature, so it
* may not be feasible to keep this here, but we'll try.
* This will come back out if there are problems. */
/* Lzma falls back to "unlzma" command-line program. */
- archive_read_support_compression_lzma(a);
+ archive_read_support_filter_lzma(a);
/* Xz falls back to "unxz" command-line program. */
- archive_read_support_compression_xz(a);
+ archive_read_support_filter_xz(a);
/* The decode code doesn't use an outside library. */
- archive_read_support_compression_uu(a);
+ archive_read_support_filter_uu(a);
/* The decode code doesn't use an outside library. */
- archive_read_support_compression_rpm(a);
+ archive_read_support_filter_rpm(a);
/* Note: We always return ARCHIVE_OK here, even if some of the
* above return ARCHIVE_WARN. The intent here is to enable
diff --git a/libarchive/archive_read_support_compression_bzip2.c b/libarchive/archive_read_support_filter_bzip2.c
index 8381c9a578c6..8d5bd1c4aca6 100644
--- a/libarchive/archive_read_support_compression_bzip2.c
+++ b/libarchive/archive_read_support_filter_bzip2.c
@@ -25,7 +25,7 @@
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_compression_bzip2.c 201108 2009-12-28 03:28:21Z kientzle $");
+__FBSDID("$FreeBSD$");
#ifdef HAVE_ERRNO_H
#include <errno.h>
@@ -72,13 +72,25 @@ static int bzip2_reader_bid(struct archive_read_filter_bidder *, struct archive_
static int bzip2_reader_init(struct archive_read_filter *);
static int bzip2_reader_free(struct archive_read_filter_bidder *);
+#if ARCHIVE_VERSION_NUMBER < 4000000
+/* Deprecated; remove in libarchive 4.0 */
int
-archive_read_support_compression_bzip2(struct archive *_a)
+archive_read_support_compression_bzip2(struct archive *a)
+{
+ return archive_read_support_filter_bzip2(a);
+}
+#endif
+
+int
+archive_read_support_filter_bzip2(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
- struct archive_read_filter_bidder *reader = __archive_read_get_bidder(a);
+ struct archive_read_filter_bidder *reader;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_filter_bzip2");
- if (reader == NULL)
+ if (__archive_read_get_bidder(a, &reader) != ARCHIVE_OK)
return (ARCHIVE_FATAL);
reader->data = NULL;
@@ -124,7 +136,7 @@ bzip2_reader_bid(struct archive_read_filter_bidder *self, struct archive_read_fi
/* First three bytes must be "BZh" */
bits_checked = 0;
- if (buffer[0] != 'B' || buffer[1] != 'Z' || buffer[2] != 'h')
+ if (memcmp(buffer, "BZh", 3) != 0)
return (0);
bits_checked += 24;
@@ -185,7 +197,7 @@ bzip2_reader_init(struct archive_read_filter *self)
state = (struct private_data *)calloc(sizeof(*state), 1);
out_block = (unsigned char *)malloc(out_block_size);
- if (self == NULL || state == NULL || out_block == NULL) {
+ if (state == NULL || out_block == NULL) {
archive_set_error(&self->archive->archive, ENOMEM,
"Can't allocate data for bzip2 decompression");
free(out_block);
@@ -274,8 +286,12 @@ bzip2_filter_read(struct archive_read_filter *self, const void **p)
* doesn't declare it so. <sigh> */
read_buf =
__archive_read_filter_ahead(self->upstream, 1, &ret);
- if (read_buf == NULL)
+ if (read_buf == NULL) {
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "truncated bzip2 input");
return (ARCHIVE_FATAL);
+ }
state->stream.next_in = (char *)(uintptr_t)read_buf;
state->stream.avail_in = ret;
/* There is no more data, return whatever we have. */
@@ -343,6 +359,7 @@ bzip2_filter_close(struct archive_read_filter *self)
"Failed to clean up decompressor");
ret = ARCHIVE_FATAL;
}
+ state->valid = 0;
}
free(state->out_block);
diff --git a/libarchive/archive_read_support_compression_compress.c b/libarchive/archive_read_support_filter_compress.c
index 2461975e59bc..1b8530004fbb 100644
--- a/libarchive/archive_read_support_compression_compress.c
+++ b/libarchive/archive_read_support_filter_compress.c
@@ -64,7 +64,7 @@
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_compression_compress.c 201094 2009-12-28 02:29:21Z kientzle $");
+__FBSDID("$FreeBSD$");
#ifdef HAVE_ERRNO_H
#include <errno.h>
@@ -95,6 +95,7 @@ struct private_data {
/* Input variables. */
const unsigned char *next_in;
size_t avail_in;
+ size_t consume_unnotified;
int bit_buffer;
int bits_avail;
size_t bytes_in_section;
@@ -140,13 +141,25 @@ static int compress_filter_close(struct archive_read_filter *);
static int getbits(struct archive_read_filter *, int n);
static int next_code(struct archive_read_filter *);
+#if ARCHIVE_VERSION_NUMBER < 4000000
+/* Deprecated; remove in libarchive 4.0 */
int
-archive_read_support_compression_compress(struct archive *_a)
+archive_read_support_compression_compress(struct archive *a)
+{
+ return archive_read_support_filter_compress(a);
+}
+#endif
+
+int
+archive_read_support_filter_compress(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
- struct archive_read_filter_bidder *bidder = __archive_read_get_bidder(a);
+ struct archive_read_filter_bidder *bidder;
- if (bidder == NULL)
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_filter_compress");
+
+ if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK)
return (ARCHIVE_FATAL);
bidder->data = NULL;
@@ -159,10 +172,7 @@ archive_read_support_compression_compress(struct archive *_a)
/*
* Test whether we can handle this data.
- *
- * This logic returns zero if any part of the signature fails. It
- * also tries to Do The Right Thing if a very short buffer prevents us
- * from verifying as much as we would like.
+ * This logic returns zero if any part of the signature fails.
*/
static int
compress_bidder_bid(struct archive_read_filter_bidder *self,
@@ -180,13 +190,9 @@ compress_bidder_bid(struct archive_read_filter_bidder *self,
return (0);
bits_checked = 0;
- if (buffer[0] != 037) /* Verify first ID byte. */
- return (0);
- bits_checked += 8;
-
- if (buffer[1] != 0235) /* Verify second ID byte. */
+ if (buffer[0] != 0x1F || buffer[1] != 0x9D)
return (0);
- bits_checked += 8;
+ bits_checked += 16;
/*
* TODO: Verify more.
@@ -420,6 +426,11 @@ getbits(struct archive_read_filter *self, int n)
while (state->bits_avail < n) {
if (state->avail_in <= 0) {
+ if (state->consume_unnotified) {
+ __archive_read_filter_consume(self->upstream,
+ state->consume_unnotified);
+ state->consume_unnotified = 0;
+ }
state->next_in
= __archive_read_filter_ahead(self->upstream,
1, &ret);
@@ -427,8 +438,7 @@ getbits(struct archive_read_filter *self, int n)
return (-1);
if (ret < 0 || state->next_in == NULL)
return (ARCHIVE_FATAL);
- state->avail_in = ret;
- __archive_read_filter_consume(self->upstream, ret);
+ state->consume_unnotified = state->avail_in = ret;
}
state->bit_buffer |= *state->next_in++ << state->bits_avail;
state->avail_in--;
diff --git a/libarchive/archive_read_support_compression_gzip.c b/libarchive/archive_read_support_filter_gzip.c
index 8cc924c9fc13..f6d5595f0b6b 100644
--- a/libarchive/archive_read_support_compression_gzip.c
+++ b/libarchive/archive_read_support_filter_gzip.c
@@ -25,7 +25,7 @@
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_compression_gzip.c 201082 2009-12-28 02:05:28Z kientzle $");
+__FBSDID("$FreeBSD$");
#ifdef HAVE_ERRNO_H
@@ -78,13 +78,25 @@ static int gzip_bidder_bid(struct archive_read_filter_bidder *,
struct archive_read_filter *);
static int gzip_bidder_init(struct archive_read_filter *);
+#if ARCHIVE_VERSION_NUMBER < 4000000
+/* Deprecated; remove in libarchive 4.0 */
int
-archive_read_support_compression_gzip(struct archive *_a)
+archive_read_support_compression_gzip(struct archive *a)
+{
+ return archive_read_support_filter_gzip(a);
+}
+#endif
+
+int
+archive_read_support_filter_gzip(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
- struct archive_read_filter_bidder *bidder = __archive_read_get_bidder(a);
+ struct archive_read_filter_bidder *bidder;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_filter_gzip");
- if (bidder == NULL)
+ if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK)
return (ARCHIVE_FATAL);
bidder->data = NULL;
@@ -123,15 +135,10 @@ peek_at_header(struct archive_read_filter *filter, int *pbits)
p = __archive_read_filter_ahead(filter, len, &avail);
if (p == NULL || avail == 0)
return (0);
- if (p[0] != 037)
+ /* We only support deflation- third byte must be 0x08. */
+ if (memcmp(p, "\x1F\x8B\x08", 3) != 0)
return (0);
- bits += 8;
- if (p[1] != 0213)
- return (0);
- bits += 8;
- if (p[2] != 8) /* We only support deflation. */
- return (0);
- bits += 8;
+ bits += 24;
if ((p[3] & 0xE0)!= 0) /* No reserved flags set. */
return (0);
bits += 3;
@@ -394,8 +401,12 @@ gzip_filter_read(struct archive_read_filter *self, const void **p)
* it so, hence this ugly cast. */
state->stream.next_in = (unsigned char *)(uintptr_t)
__archive_read_filter_ahead(self->upstream, 1, &avail_in);
- if (state->stream.next_in == NULL)
+ if (state->stream.next_in == NULL) {
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "truncated gzip input");
return (ARCHIVE_FATAL);
+ }
state->stream.avail_in = avail_in;
/* Decompress and consume some of that data. */
diff --git a/libarchive/archive_read_support_compression_none.c b/libarchive/archive_read_support_filter_none.c
index 955d06d9aa18..95e5cfdb15dc 100644
--- a/libarchive/archive_read_support_compression_none.c
+++ b/libarchive/archive_read_support_filter_none.c
@@ -24,17 +24,29 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_compression_none.c 185679 2008-12-06 06:45:15Z kientzle $");
+__FBSDID("$FreeBSD$");
#include "archive.h"
+#include "archive_private.h"
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+/* Deprecated; remove in libarchive 4.0 */
+int
+archive_read_support_compression_none(struct archive *a)
+{
+ return archive_read_support_filter_none(a);
+}
+#endif
/*
* Uncompressed streams are handled implicitly by the read core,
* so this is now a no-op.
*/
int
-archive_read_support_compression_none(struct archive *a)
+archive_read_support_filter_none(struct archive *a)
{
- (void)a; /* UNUSED */
+ archive_check_magic(a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_filter_none");
+
return (ARCHIVE_OK);
}
diff --git a/libarchive/archive_read_support_compression_program.c b/libarchive/archive_read_support_filter_program.c
index 0c63f2e83129..b05eb03424d7 100644
--- a/libarchive/archive_read_support_compression_program.c
+++ b/libarchive/archive_read_support_filter_program.c
@@ -24,7 +24,7 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_compression_program.c 201112 2009-12-28 06:59:35Z kientzle $");
+__FBSDID("$FreeBSD$");
#ifdef HAVE_SYS_WAIT_H
# include <sys/wait.h>
@@ -55,10 +55,28 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_compression_program
#include "archive_private.h"
#include "archive_read_private.h"
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+/* Deprecated; remove in libarchive 4.0 */
int
archive_read_support_compression_program(struct archive *a, const char *cmd)
{
- return (archive_read_support_compression_program_signature(a, cmd, NULL, 0));
+ return archive_read_support_filter_program(a, cmd);
+}
+
+int
+archive_read_support_compression_program_signature(struct archive *a,
+ const char *cmd, const void *signature, size_t signature_len)
+{
+ return archive_read_support_filter_program_signature(a,
+ cmd, signature, signature_len);
+}
+#endif
+
+int
+archive_read_support_filter_program(struct archive *a, const char *cmd)
+{
+ return (archive_read_support_filter_program_signature(a, cmd, NULL, 0));
}
@@ -71,8 +89,8 @@ archive_read_support_compression_program(struct archive *a, const char *cmd)
* this function is actually invoked.
*/
int
-archive_read_support_compression_program_signature(struct archive *_a,
- const char *cmd, void *signature, size_t signature_len)
+archive_read_support_filter_program_signature(struct archive *_a,
+ const char *cmd, const void *signature, size_t signature_len)
{
(void)_a; /* UNUSED */
(void)cmd; /* UNUSED */
@@ -135,7 +153,7 @@ static ssize_t program_filter_read(struct archive_read_filter *,
static int program_filter_close(struct archive_read_filter *);
int
-archive_read_support_compression_program_signature(struct archive *_a,
+archive_read_support_filter_program_signature(struct archive *_a,
const char *cmd, const void *signature, size_t signature_len)
{
struct archive_read *a = (struct archive_read *)_a;
@@ -145,8 +163,7 @@ archive_read_support_compression_program_signature(struct archive *_a,
/*
* Get a bidder object from the read core.
*/
- bidder = __archive_read_get_bidder(a);
- if (bidder == NULL)
+ if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK)
return (ARCHIVE_FATAL);
/*
@@ -388,7 +405,7 @@ __archive_read_program(struct archive_read_filter *self, const char *cmd)
free(state->out_buf);
free(state);
archive_set_error(&self->archive->archive, EINVAL,
- "Can't initialise filter");
+ "Can't initialize filter; unable to run program \"%s\"", cmd);
return (ARCHIVE_FATAL);
}
diff --git a/libarchive/archive_read_support_compression_rpm.c b/libarchive/archive_read_support_filter_rpm.c
index 051baa5e1229..7dbfc0ebc117 100644
--- a/libarchive/archive_read_support_compression_rpm.c
+++ b/libarchive/archive_read_support_filter_rpm.c
@@ -63,15 +63,25 @@ static ssize_t rpm_filter_read(struct archive_read_filter *,
const void **);
static int rpm_filter_close(struct archive_read_filter *);
+#if ARCHIVE_VERSION_NUMBER < 4000000
+/* Deprecated; remove in libarchive 4.0 */
int
-archive_read_support_compression_rpm(struct archive *_a)
+archive_read_support_compression_rpm(struct archive *a)
+{
+ return archive_read_support_filter_rpm(a);
+}
+#endif
+
+int
+archive_read_support_filter_rpm(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
struct archive_read_filter_bidder *bidder;
- bidder = __archive_read_get_bidder(a);
- archive_clear_error(_a);
- if (bidder == NULL)
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_filter_rpm");
+
+ if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK)
return (ARCHIVE_FATAL);
bidder->data = NULL;
@@ -98,20 +108,11 @@ rpm_bidder_bid(struct archive_read_filter_bidder *self,
bits_checked = 0;
/*
- * Verify Header Magic Bytes : 0xed 0xab 0xee 0xdb
+ * Verify Header Magic Bytes : 0XED 0XAB 0XEE 0XDB
*/
- if (b[0] != 0xed)
+ if (memcmp(b, "\xED\xAB\xEE\xDB", 4) != 0)
return (0);
- bits_checked += 8;
- if (b[1] != 0xab)
- return (0);
- bits_checked += 8;
- if (b[2] != 0xee)
- return (0);
- bits_checked += 8;
- if (b[3] != 0xdb)
- return (0);
- bits_checked += 8;
+ bits_checked += 32;
/*
* Check major version.
*/
diff --git a/libarchive/archive_read_support_compression_uu.c b/libarchive/archive_read_support_filter_uu.c
index f7bea828fccd..a75ef756081b 100644
--- a/libarchive/archive_read_support_compression_uu.c
+++ b/libarchive/archive_read_support_filter_uu.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2009 Michihiro NAKAJIMA
+ * Copyright (c) 2009-2011 Michihiro NAKAJIMA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,7 +24,7 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_compression_uu.c 201248 2009-12-30 06:12:03Z kientzle $");
+__FBSDID("$FreeBSD$");
#ifdef HAVE_ERRNO_H
#include <errno.h>
@@ -40,6 +40,9 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_compression_uu.c 20
#include "archive_private.h"
#include "archive_read_private.h"
+/* Maximum lookahead during bid phase */
+#define UUENCODE_BID_MAX_READ 128*1024 /* in bytes */
+
struct uudecode {
int64_t total;
unsigned char *in_buff;
@@ -63,15 +66,25 @@ static ssize_t uudecode_filter_read(struct archive_read_filter *,
const void **);
static int uudecode_filter_close(struct archive_read_filter *);
+#if ARCHIVE_VERSION_NUMBER < 4000000
+/* Deprecated; remove in libarchive 4.0 */
int
-archive_read_support_compression_uu(struct archive *_a)
+archive_read_support_compression_uu(struct archive *a)
+{
+ return archive_read_support_filter_uu(a);
+}
+#endif
+
+int
+archive_read_support_filter_uu(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
struct archive_read_filter_bidder *bidder;
- bidder = __archive_read_get_bidder(a);
- archive_clear_error(_a);
- if (bidder == NULL)
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_filter_uu");
+
+ if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK)
return (ARCHIVE_FATAL);
bidder->data = NULL;
@@ -194,7 +207,8 @@ get_line(const unsigned char *b, ssize_t avail, ssize_t *nlsize)
static ssize_t
bid_get_line(struct archive_read_filter *filter,
- const unsigned char **b, ssize_t *avail, ssize_t *ravail, ssize_t *nl)
+ const unsigned char **b, ssize_t *avail, ssize_t *ravail,
+ ssize_t *nl, size_t* nbytes_read)
{
ssize_t len;
int quit;
@@ -205,24 +219,37 @@ bid_get_line(struct archive_read_filter *filter,
len = 0;
} else
len = get_line(*b, *avail, nl);
+
/*
* Read bytes more while it does not reach the end of line.
*/
- while (*nl == 0 && len == *avail && !quit) {
+ while (*nl == 0 && len == *avail && !quit &&
+ *nbytes_read < UUENCODE_BID_MAX_READ) {
ssize_t diff = *ravail - *avail;
+ size_t nbytes_req = (*ravail+1023) & ~1023U;
+ ssize_t tested;
+
+ /* Increase reading bytes if it is not enough to at least
+ * new two lines. */
+ if (nbytes_req < (size_t)*ravail + 160)
+ nbytes_req <<= 1;
- *b = __archive_read_filter_ahead(filter, 160 + *ravail, avail);
+ *b = __archive_read_filter_ahead(filter, nbytes_req, avail);
if (*b == NULL) {
if (*ravail >= *avail)
return (0);
- /* Reading bytes reaches the end of file. */
+ /* Reading bytes reaches the end of a stream. */
*b = __archive_read_filter_ahead(filter, *avail, avail);
quit = 1;
}
+ *nbytes_read = *avail;
*ravail = *avail;
*b += diff;
*avail -= diff;
- len = get_line(*b, *avail, nl);
+ tested = len;/* Skip some bytes we already determinated. */
+ len = get_line(*b + tested, *avail - tested, nl);
+ if (len >= 0)
+ len += tested;
}
return (len);
}
@@ -238,6 +265,7 @@ uudecode_bidder_bid(struct archive_read_filter_bidder *self,
ssize_t len, nl;
int l;
int firstline;
+ size_t nbytes_read;
(void)self; /* UNUSED */
@@ -247,13 +275,14 @@ uudecode_bidder_bid(struct archive_read_filter_bidder *self,
firstline = 20;
ravail = avail;
+ nbytes_read = avail;
for (;;) {
- len = bid_get_line(filter, &b, &avail, &ravail, &nl);
+ len = bid_get_line(filter, &b, &avail, &ravail, &nl, &nbytes_read);
if (len < 0 || nl == 0)
- return (0);/* Binary data. */
- if (memcmp(b, "begin ", 6) == 0 && len - nl >= 11)
+ return (0); /* No match found. */
+ if (len - nl >= 11 && memcmp(b, "begin ", 6) == 0)
l = 6;
- else if (memcmp(b, "begin-base64 ", 13) == 0 && len - nl >= 18)
+ else if (len -nl >= 18 && memcmp(b, "begin-base64 ", 13) == 0)
l = 13;
else
l = 0;
@@ -268,10 +297,14 @@ uudecode_bidder_bid(struct archive_read_filter_bidder *self,
if (l)
break;
firstline = 0;
+
+ /* Do not read more than UUENCODE_BID_MAX_READ bytes */
+ if (nbytes_read >= UUENCODE_BID_MAX_READ)
+ return (0);
}
if (!avail)
return (0);
- len = bid_get_line(filter, &b, &avail, &ravail, &nl);
+ len = bid_get_line(filter, &b, &avail, &ravail, &nl, &nbytes_read);
if (len < 0 || nl == 0)
return (0);/* There are non-ascii characters. */
avail -= len;
@@ -392,18 +425,19 @@ ensure_in_buff_size(struct archive_read_filter *self,
else
newsize += IN_BUFF_SIZE;
} while (size > newsize);
+ /* Allocate the new buffer. */
ptr = malloc(newsize);
- if (ptr == NULL ||
- newsize < uudecode->in_allocated) {
+ if (ptr == NULL) {
free(ptr);
archive_set_error(&self->archive->archive,
ENOMEM,
"Can't allocate data for uudecode");
return (ARCHIVE_FATAL);
}
+ /* Move the remaining data in in_buff into the new buffer. */
if (uudecode->in_cnt)
- memmove(ptr, uudecode->in_buff,
- uudecode->in_cnt);
+ memmove(ptr, uudecode->in_buff, uudecode->in_cnt);
+ /* Replace in_buff with the new buffer. */
free(uudecode->in_buff);
uudecode->in_buff = ptr;
uudecode->in_allocated = newsize;
@@ -483,11 +517,16 @@ read_more:
}
break;
}
- if (total + len * 2 > OUT_BUFF_SIZE)
- break;
switch (uudecode->state) {
default:
case ST_FIND_HEAD:
+ /* Do not read more than UUENCODE_BID_MAX_READ bytes */
+ if (total + len >= UUENCODE_BID_MAX_READ) {
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid format data");
+ return (ARCHIVE_FATAL);
+ }
if (len - nl >= 11 && memcmp(b, "begin ", 6) == 0)
l = 6;
else if (len - nl >= 18 &&
@@ -505,6 +544,8 @@ read_more:
}
break;
case ST_READ_UU:
+ if (total + len * 2 > OUT_BUFF_SIZE)
+ break;
body = len - nl;
if (!uuchar[*b] || body <= 0) {
archive_set_error(&self->archive->archive,
@@ -569,6 +610,8 @@ read_more:
}
break;
case ST_READ_BASE64:
+ if (total + len * 2 > OUT_BUFF_SIZE)
+ break;
l = len - nl;
if (l >= 3 && b[0] == '=' && b[1] == '=' &&
b[2] == '=') {
diff --git a/libarchive/archive_read_support_compression_xz.c b/libarchive/archive_read_support_filter_xz.c
index 28c4e2d9fc51..cf762a46d984 100644
--- a/libarchive/archive_read_support_compression_xz.c
+++ b/libarchive/archive_read_support_filter_xz.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2009 Michihiro NAKAJIMA
+ * Copyright (c) 2009-2011 Michihiro NAKAJIMA
* Copyright (c) 2003-2008 Tim Kientzle and Miklos Vajna
* All rights reserved.
*
@@ -26,7 +26,7 @@
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_compression_xz.c 201167 2009-12-29 06:06:20Z kientzle $");
+__FBSDID("$FreeBSD$");
#ifdef HAVE_ERRNO_H
#include <errno.h>
@@ -60,9 +60,24 @@ struct private_data {
size_t out_block_size;
int64_t total_out;
char eof; /* True = found end of compressed data. */
+ char in_stream;
+
+ /* Following variables are used for lzip only. */
+ char lzip_ver;
+ uint32_t crc32;
+ int64_t member_in;
+ int64_t member_out;
};
-/* Combined lzma/xz filter */
+#if LZMA_VERSION_MAJOR >= 5
+/* Effectively disable the limiter. */
+#define LZMA_MEMLIMIT UINT64_MAX
+#else
+/* NOTE: This needs to check memory size which running system has. */
+#define LZMA_MEMLIMIT (1U << 30)
+#endif
+
+/* Combined lzip/lzma/xz filter */
static ssize_t xz_filter_read(struct archive_read_filter *, const void **);
static int xz_filter_close(struct archive_read_filter *);
static int xz_lzma_bidder_init(struct archive_read_filter *);
@@ -94,15 +109,30 @@ static int xz_bidder_init(struct archive_read_filter *);
static int lzma_bidder_bid(struct archive_read_filter_bidder *,
struct archive_read_filter *);
static int lzma_bidder_init(struct archive_read_filter *);
+static int lzip_has_member(struct archive_read_filter *);
+static int lzip_bidder_bid(struct archive_read_filter_bidder *,
+ struct archive_read_filter *);
+static int lzip_bidder_init(struct archive_read_filter *);
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+/* Deprecated; remove in libarchive 4.0 */
+int
+archive_read_support_compression_xz(struct archive *a)
+{
+ return archive_read_support_filter_xz(a);
+}
+#endif
int
-archive_read_support_compression_xz(struct archive *_a)
+archive_read_support_filter_xz(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
- struct archive_read_filter_bidder *bidder = __archive_read_get_bidder(a);
+ struct archive_read_filter_bidder *bidder;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_filter_xz");
- archive_clear_error(_a);
- if (bidder == NULL)
+ if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK)
return (ARCHIVE_FATAL);
bidder->data = NULL;
@@ -119,14 +149,24 @@ archive_read_support_compression_xz(struct archive *_a)
#endif
}
+#if ARCHIVE_VERSION_NUMBER < 4000000
+int
+archive_read_support_compression_lzma(struct archive *a)
+{
+ return archive_read_support_filter_lzma(a);
+}
+#endif
+
int
-archive_read_support_compression_lzma(struct archive *_a)
+archive_read_support_filter_lzma(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
- struct archive_read_filter_bidder *bidder = __archive_read_get_bidder(a);
+ struct archive_read_filter_bidder *bidder;
- archive_clear_error(_a);
- if (bidder == NULL)
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_filter_lzma");
+
+ if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK)
return (ARCHIVE_FATAL);
bidder->data = NULL;
@@ -145,6 +185,41 @@ archive_read_support_compression_lzma(struct archive *_a)
#endif
}
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+int
+archive_read_support_compression_lzip(struct archive *a)
+{
+ return archive_read_support_filter_lzip(a);
+}
+#endif
+
+int
+archive_read_support_filter_lzip(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct archive_read_filter_bidder *bidder;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_filter_lzip");
+
+ if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ bidder->data = NULL;
+ bidder->bid = lzip_bidder_bid;
+ bidder->init = lzip_bidder_init;
+ bidder->options = NULL;
+ bidder->free = NULL;
+#if HAVE_LZMA_H && HAVE_LIBLZMA
+ return (ARCHIVE_OK);
+#else
+ archive_set_error(_a, ARCHIVE_ERRNO_MISC,
+ "Using external lzip program for lzip decompression");
+ return (ARCHIVE_WARN);
+#endif
+}
+
/*
* Test whether we can handle this data.
*/
@@ -154,7 +229,6 @@ xz_bidder_bid(struct archive_read_filter_bidder *self,
{
const unsigned char *buffer;
ssize_t avail;
- int bits_checked;
(void)self; /* UNUSED */
@@ -165,27 +239,10 @@ xz_bidder_bid(struct archive_read_filter_bidder *self,
/*
* Verify Header Magic Bytes : FD 37 7A 58 5A 00
*/
- bits_checked = 0;
- if (buffer[0] != 0xFD)
- return (0);
- bits_checked += 8;
- if (buffer[1] != 0x37)
- return (0);
- bits_checked += 8;
- if (buffer[2] != 0x7A)
- return (0);
- bits_checked += 8;
- if (buffer[3] != 0x58)
+ if (memcmp(buffer, "\xFD\x37\x7A\x58\x5A\x00", 6) != 0)
return (0);
- bits_checked += 8;
- if (buffer[4] != 0x5A)
- return (0);
- bits_checked += 8;
- if (buffer[5] != 0x00)
- return (0);
- bits_checked += 8;
- return (bits_checked);
+ return (48);
}
/*
@@ -307,6 +364,49 @@ lzma_bidder_bid(struct archive_read_filter_bidder *self,
return (bits_checked);
}
+static int
+lzip_has_member(struct archive_read_filter *filter)
+{
+ const unsigned char *buffer;
+ ssize_t avail;
+ int bits_checked;
+ int log2dic;
+
+ buffer = __archive_read_filter_ahead(filter, 6, &avail);
+ if (buffer == NULL)
+ return (0);
+
+ /*
+ * Verify Header Magic Bytes : 4C 5A 49 50 (`LZIP')
+ */
+ bits_checked = 0;
+ if (memcmp(buffer, "LZIP", 4) != 0)
+ return (0);
+ bits_checked += 32;
+
+ /* A version number must be 0 or 1 */
+ if (buffer[4] != 0 && buffer[4] != 1)
+ return (0);
+ bits_checked += 8;
+
+ /* Dictionary size. */
+ log2dic = buffer[5] & 0x1f;
+ if (log2dic < 12 || log2dic > 27)
+ return (0);
+ bits_checked += 8;
+
+ return (bits_checked);
+}
+
+static int
+lzip_bidder_bid(struct archive_read_filter_bidder *self,
+ struct archive_read_filter *filter)
+{
+
+ (void)self; /* UNUSED */
+ return (lzip_has_member(filter));
+}
+
#if HAVE_LZMA_H && HAVE_LIBLZMA
/*
@@ -328,6 +428,62 @@ lzma_bidder_init(struct archive_read_filter *self)
return (xz_lzma_bidder_init(self));
}
+static int
+lzip_bidder_init(struct archive_read_filter *self)
+{
+ self->code = ARCHIVE_COMPRESSION_LZIP;
+ self->name = "lzip";
+ return (xz_lzma_bidder_init(self));
+}
+
+/*
+ * Set an error code and choose an error message
+ */
+static void
+set_error(struct archive_read_filter *self, int ret)
+{
+
+ switch (ret) {
+ case LZMA_STREAM_END: /* Found end of stream. */
+ case LZMA_OK: /* Decompressor made some progress. */
+ break;
+ case LZMA_MEM_ERROR:
+ archive_set_error(&self->archive->archive, ENOMEM,
+ "Lzma library error: Cannot allocate memory");
+ break;
+ case LZMA_MEMLIMIT_ERROR:
+ archive_set_error(&self->archive->archive, ENOMEM,
+ "Lzma library error: Out of memory");
+ break;
+ case LZMA_FORMAT_ERROR:
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Lzma library error: format not recognized");
+ break;
+ case LZMA_OPTIONS_ERROR:
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Lzma library error: Invalid options");
+ break;
+ case LZMA_DATA_ERROR:
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Lzma library error: Corrupted input data");
+ break;
+ case LZMA_BUF_ERROR:
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Lzma library error: No progress is possible");
+ break;
+ default:
+ /* Return an error. */
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Lzma decompression failed: Unknown error");
+ break;
+ }
+}
+
/*
* Setup the callbacks.
*/
@@ -361,40 +517,32 @@ xz_lzma_bidder_init(struct archive_read_filter *self)
state->stream.next_out = state->out_block;
state->stream.avail_out = state->out_block_size;
- /* Initialize compression library.
- * TODO: I don't know what value is best for memlimit.
- * maybe, it needs to check memory size which
- * running system has.
- */
+ state->crc32 = 0;
+ if (self->code == ARCHIVE_COMPRESSION_LZIP) {
+ /*
+ * We have to read a lzip header and use it to initialize
+ * compression library, thus we cannot initialize the
+ * library for lzip here.
+ */
+ state->in_stream = 0;
+ return (ARCHIVE_OK);
+ } else
+ state->in_stream = 1;
+
+ /* Initialize compression library. */
if (self->code == ARCHIVE_COMPRESSION_XZ)
ret = lzma_stream_decoder(&(state->stream),
- (1U << 30),/* memlimit */
+ LZMA_MEMLIMIT,/* memlimit */
LZMA_CONCATENATED);
else
ret = lzma_alone_decoder(&(state->stream),
- (1U << 30));/* memlimit */
+ LZMA_MEMLIMIT);/* memlimit */
if (ret == LZMA_OK)
return (ARCHIVE_OK);
/* Library setup failed: Choose an error message and clean up. */
- switch (ret) {
- case LZMA_MEM_ERROR:
- archive_set_error(&self->archive->archive, ENOMEM,
- "Internal error initializing compression library: "
- "Cannot allocate memory");
- break;
- case LZMA_OPTIONS_ERROR:
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "Internal error initializing compression library: "
- "Invalid or unsupported options");
- break;
- default:
- archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
- "Internal error initializing lzma library");
- break;
- }
+ set_error(self, ret);
free(state->out_block);
free(state);
@@ -402,6 +550,122 @@ xz_lzma_bidder_init(struct archive_read_filter *self)
return (ARCHIVE_FATAL);
}
+static int
+lzip_init(struct archive_read_filter *self)
+{
+ struct private_data *state;
+ const unsigned char *h;
+ lzma_filter filters[2];
+ unsigned char props[5];
+ ssize_t avail_in;
+ uint32_t dicsize;
+ int log2dic, ret;
+
+ state = (struct private_data *)self->data;
+ h = __archive_read_filter_ahead(self->upstream, 6, &avail_in);
+ if (h == NULL)
+ return (ARCHIVE_FATAL);
+
+ /* Get a version number. */
+ state->lzip_ver = h[4];
+
+ /*
+ * Setup lzma property.
+ */
+ props[0] = 0x5d;
+
+ /* Get dictionary size. */
+ log2dic = h[5] & 0x1f;
+ if (log2dic < 12 || log2dic > 27)
+ return (ARCHIVE_FATAL);
+ dicsize = 1U << log2dic;
+ if (log2dic > 12)
+ dicsize -= (dicsize / 16) * (h[5] >> 5);
+ archive_le32enc(props+1, dicsize);
+
+ /* Consume lzip header. */
+ __archive_read_filter_consume(self->upstream, 6);
+ state->member_in = 6;
+
+ filters[0].id = LZMA_FILTER_LZMA1;
+ filters[0].options = NULL;
+ filters[1].id = LZMA_VLI_UNKNOWN;
+ filters[1].options = NULL;
+
+ ret = lzma_properties_decode(&filters[0], NULL, props, sizeof(props));
+ if (ret != LZMA_OK) {
+ set_error(self, ret);
+ return (ARCHIVE_FATAL);
+ }
+ ret = lzma_raw_decoder(&(state->stream), filters);
+#if LZMA_VERSION < 50000030
+ free(filters[0].options);
+#endif
+ if (ret != LZMA_OK) {
+ set_error(self, ret);
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+lzip_tail(struct archive_read_filter *self)
+{
+ struct private_data *state;
+ const unsigned char *f;
+ ssize_t avail_in;
+ int tail;
+
+ state = (struct private_data *)self->data;
+ if (state->lzip_ver == 0)
+ tail = 12;
+ else
+ tail = 20;
+ f = __archive_read_filter_ahead(self->upstream, tail, &avail_in);
+ if (f == NULL && avail_in < 0)
+ return (ARCHIVE_FATAL);
+ if (avail_in < tail) {
+ archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
+ "Lzip: Remaining data is less bytes");
+ return (ARCHIVE_FAILED);
+ }
+
+ /* Check the crc32 value of the uncompressed data of the current
+ * member */
+ if (state->crc32 != archive_le32dec(f)) {
+ archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
+ "Lzip: CRC32 error");
+ return (ARCHIVE_FAILED);
+ }
+
+ /* Check the uncompressed size of the current member */
+ if ((uint64_t)state->member_out != archive_le64dec(f + 4)) {
+ archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
+ "Lzip: Uncompressed size error");
+ return (ARCHIVE_FAILED);
+ }
+
+ /* Check the total size of the current member */
+ if (state->lzip_ver == 1 &&
+ (uint64_t)state->member_in + tail != archive_le64dec(f + 12)) {
+ archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
+ "Lzip: Member size error");
+ return (ARCHIVE_FAILED);
+ }
+ __archive_read_filter_consume(self->upstream, tail);
+
+ /* If current lzip data consists of multi member, try decompressing
+ * a next member. */
+ if (lzip_has_member(self->upstream) != 0) {
+ state->in_stream = 0;
+ state->crc32 = 0;
+ state->member_out = 0;
+ state->member_in = 0;
+ state->eof = 0;
+ }
+ return (ARCHIVE_OK);
+}
+
/*
* Return the next block of decompressed data.
*/
@@ -421,10 +685,23 @@ xz_filter_read(struct archive_read_filter *self, const void **p)
/* Try to fill the output buffer. */
while (state->stream.avail_out > 0 && !state->eof) {
+ if (!state->in_stream) {
+ /*
+ * Initialize liblzma for lzip
+ */
+ ret = lzip_init(self);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ state->in_stream = 1;
+ }
state->stream.next_in =
__archive_read_filter_ahead(self->upstream, 1, &avail_in);
- if (state->stream.next_in == NULL && avail_in < 0)
+ if (state->stream.next_in == NULL && avail_in < 0) {
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "truncated input");
return (ARCHIVE_FATAL);
+ }
state->stream.avail_in = avail_in;
/* Decompress as much as we can in one pass. */
@@ -437,50 +714,32 @@ xz_filter_read(struct archive_read_filter *self, const void **p)
case LZMA_OK: /* Decompressor made some progress. */
__archive_read_filter_consume(self->upstream,
avail_in - state->stream.avail_in);
+ state->member_in +=
+ avail_in - state->stream.avail_in;
break;
- case LZMA_MEM_ERROR:
- archive_set_error(&self->archive->archive, ENOMEM,
- "Lzma library error: Cannot allocate memory");
- return (ARCHIVE_FATAL);
- case LZMA_MEMLIMIT_ERROR:
- archive_set_error(&self->archive->archive, ENOMEM,
- "Lzma library error: Out of memory");
- return (ARCHIVE_FATAL);
- case LZMA_FORMAT_ERROR:
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "Lzma library error: format not recognized");
- return (ARCHIVE_FATAL);
- case LZMA_OPTIONS_ERROR:
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "Lzma library error: Invalid options");
- return (ARCHIVE_FATAL);
- case LZMA_DATA_ERROR:
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "Lzma library error: Corrupted input data");
- return (ARCHIVE_FATAL);
- case LZMA_BUF_ERROR:
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "Lzma library error: No progress is possible");
- return (ARCHIVE_FATAL);
default:
- /* Return an error. */
- archive_set_error(&self->archive->archive,
- ARCHIVE_ERRNO_MISC,
- "Lzma decompression failed: Unknown error");
+ set_error(self, ret);
return (ARCHIVE_FATAL);
}
}
decompressed = state->stream.next_out - state->out_block;
state->total_out += decompressed;
+ state->member_out += decompressed;
if (decompressed == 0)
*p = NULL;
- else
+ else {
*p = state->out_block;
+ if (self->code == ARCHIVE_COMPRESSION_LZIP) {
+ state->crc32 = lzma_crc32(state->out_block,
+ decompressed, state->crc32);
+ if (state->eof) {
+ ret = lzip_tail(self);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ }
+ }
+ }
return (decompressed);
}
@@ -600,8 +859,12 @@ lzma_filter_read(struct archive_read_filter *self, const void **p)
while (state->stream.avail_out > 0 && !state->eof) {
state->stream.next_in = (unsigned char *)(uintptr_t)
__archive_read_filter_ahead(self->upstream, 1, &avail_in);
- if (state->stream.next_in == NULL && avail_in < 0)
+ if (state->stream.next_in == NULL && avail_in < 0) {
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "truncated lzma input");
return (ARCHIVE_FATAL);
+ }
state->stream.avail_in = avail_in;
/* Decompress as much as we can in one pass. */
@@ -704,5 +967,19 @@ xz_bidder_init(struct archive_read_filter *self)
return (r);
}
+static int
+lzip_bidder_init(struct archive_read_filter *self)
+{
+ int r;
+
+ r = __archive_read_program(self, "unlzip");
+ /* Note: We set the format here even if __archive_read_program()
+ * above fails. We do, after all, know what the format is
+ * even if we weren't able to read it. */
+ self->code = ARCHIVE_COMPRESSION_LZIP;
+ self->name = "lzip";
+ return (r);
+}
+
#endif /* HAVE_LZMA_H */
diff --git a/libarchive/archive_read_support_format_7zip.c b/libarchive/archive_read_support_format_7zip.c
new file mode 100644
index 000000000000..e211e67bedb0
--- /dev/null
+++ b/libarchive/archive_read_support_format_7zip.c
@@ -0,0 +1,3706 @@
+/*-
+ * Copyright (c) 2011 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+__FBSDID("$FreeBSD$");
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_BZLIB_H
+#include <bzlib.h>
+#endif
+#ifdef HAVE_LZMA_H
+#include <lzma.h>
+#endif
+#ifdef HAVE_ZLIB_H
+#include <zlib.h>
+#endif
+
+#include "archive.h"
+#include "archive_entry.h"
+#include "archive_entry_locale.h"
+#include "archive_ppmd7_private.h"
+#include "archive_private.h"
+#include "archive_read_private.h"
+#include "archive_endian.h"
+
+#ifndef HAVE_ZLIB_H
+#include "archive_crc32.h"
+#endif
+
+#define _7ZIP_SIGNATURE "7z\xBC\xAF\x27\x1C"
+#define SFX_MIN_ADDR 0x27000
+#define SFX_MAX_ADDR 0x60000
+
+
+/*
+ * Codec ID
+ */
+#define _7Z_COPY 0
+#define _7Z_LZMA 0x030101
+#define _7Z_LZMA2 0x21
+#define _7Z_DEFLATE 0x040108
+#define _7Z_BZ2 0x040202
+#define _7Z_PPMD 0x030401
+#define _7Z_DELTA 0x03
+#define _7Z_CRYPTO 0x06F10701
+#define _7Z_X86 0x03030103
+#define _7Z_X86_BCJ2 0x0303011B
+#define _7Z_POWERPC 0x03030205
+#define _7Z_IA64 0x03030401
+#define _7Z_ARM 0x03030501
+#define _7Z_ARMTHUMB 0x03030701
+#define _7Z_SPARC 0x03030805
+
+/*
+ * 7-Zip header property IDs.
+ */
+#define kEnd 0x00
+#define kHeader 0x01
+#define kArchiveProperties 0x02
+#define kAdditionalStreamsInfo 0x03
+#define kMainStreamsInfo 0x04
+#define kFilesInfo 0x05
+#define kPackInfo 0x06
+#define kUnPackInfo 0x07
+#define kSubStreamsInfo 0x08
+#define kSize 0x09
+#define kCRC 0x0A
+#define kFolder 0x0B
+#define kCodersUnPackSize 0x0C
+#define kNumUnPackStream 0x0D
+#define kEmptyStream 0x0E
+#define kEmptyFile 0x0F
+#define kAnti 0x10
+#define kName 0x11
+#define kCTime 0x12
+#define kATime 0x13
+#define kMTime 0x14
+#define kAttributes 0x15
+#define kEncodedHeader 0x17
+
+struct _7z_digests {
+ unsigned char *defineds;
+ uint32_t *digests;
+};
+
+
+struct _7z_folder {
+ uint64_t numCoders;
+ struct _7z_coder {
+ unsigned long codec;
+ uint64_t numInStreams;
+ uint64_t numOutStreams;
+ uint64_t propertiesSize;
+ unsigned char *properties;
+ } *coders;
+ uint64_t numBindPairs;
+ struct {
+ uint64_t inIndex;
+ uint64_t outIndex;
+ } *bindPairs;
+ uint64_t numPackedStreams;
+ uint64_t *packedStreams;
+ uint64_t numInStreams;
+ uint64_t numOutStreams;
+ uint64_t *unPackSize;
+ unsigned char digest_defined;
+ uint32_t digest;
+ uint64_t numUnpackStreams;
+ uint32_t packIndex;
+ /* Unoperated bytes. */
+ uint64_t skipped_bytes;
+};
+
+struct _7z_coders_info {
+ uint64_t numFolders;
+ struct _7z_folder *folders;
+ uint64_t dataStreamIndex;
+};
+
+struct _7z_pack_info {
+ uint64_t pos;
+ uint64_t numPackStreams;
+ uint64_t *sizes;
+ struct _7z_digests digest;
+ /* Calculated from pos and numPackStreams. */
+ uint64_t *positions;
+};
+
+struct _7z_substream_info {
+ size_t unpack_streams;
+ uint64_t *unpackSizes;
+ unsigned char *digestsDefined;
+ uint32_t *digests;
+};
+
+struct _7z_stream_info {
+ struct _7z_pack_info pi;
+ struct _7z_coders_info ci;
+ struct _7z_substream_info ss;
+};
+
+struct _7z_header_info {
+ uint64_t dataIndex;
+
+ unsigned char *emptyStreamBools;
+ unsigned char *emptyFileBools;
+ unsigned char *antiBools;
+ unsigned char *attrBools;
+};
+
+struct _7zip_entry {
+ size_t name_len;
+ unsigned char *utf16name;
+#if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG)
+ const wchar_t *wname;
+#endif
+ uint32_t folderIndex;
+ uint32_t ssIndex;
+ unsigned flg;
+#define MTIME_IS_SET (1<<0)
+#define ATIME_IS_SET (1<<1)
+#define CTIME_IS_SET (1<<2)
+#define CRC32_IS_SET (1<<3)
+#define HAS_STREAM (1<<4)
+
+ time_t mtime;
+ time_t atime;
+ time_t ctime;
+ long mtime_ns;
+ long atime_ns;
+ long ctime_ns;
+ uint32_t mode;
+ uint32_t attr;
+};
+
+struct _7zip {
+ /* Structural information about the archive. */
+ struct _7z_stream_info si;
+
+ int header_is_being_read;
+ int header_is_encoded;
+ uint64_t header_bytes_remaining;
+ unsigned long header_crc32;
+ /* Header offset to check that reading pointes of the file contens
+ * will not exceed the header. */
+ uint64_t header_offset;
+ /* Base offset of the archive file for a seek in case reading SFX. */
+ uint64_t seek_base;
+
+ /* List of entries */
+ size_t entries_remaining;
+ uint64_t numFiles;
+ struct _7zip_entry *entries;
+ struct _7zip_entry *entry;
+ unsigned char *entry_names;
+
+ /* entry_bytes_remaining is the number of bytes we expect. */
+ int64_t entry_offset;
+ uint64_t entry_bytes_remaining;
+
+ /* Running CRC32 of the decompressed data */
+ unsigned long entry_crc32;
+
+ /* Flags to mark progress of decompression. */
+ char end_of_entry;
+
+ /* Uncompressed buffer control. */
+#define UBUFF_SIZE (64 * 1024)
+ unsigned char *uncompressed_buffer;
+ unsigned char *uncompressed_buffer_pointer;
+ size_t uncompressed_buffer_size;
+ size_t uncompressed_buffer_bytes_remaining;
+
+ /* Offset of the compressed data. */
+ int64_t stream_offset;
+
+ /*
+ * Decompressing control data.
+ */
+ unsigned folder_index;
+ uint64_t folder_outbytes_remaining;
+ unsigned pack_stream_index;
+ unsigned pack_stream_remaining;
+ uint64_t pack_stream_inbytes_remaining;
+ size_t pack_stream_bytes_unconsumed;
+
+ /* The codec information of a folder. */
+ unsigned long codec;
+ unsigned long codec2;
+
+ /*
+ * Decompressor controllers.
+ */
+ /* Decording LZMA1 and LZMA2 data. */
+#ifdef HAVE_LZMA_H
+ lzma_stream lzstream;
+ int lzstream_valid;
+#endif
+ /* Decording bzip2 data. */
+#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
+ bz_stream bzstream;
+ int bzstream_valid;
+#endif
+ /* Decording deflate data. */
+#ifdef HAVE_ZLIB_H
+ z_stream stream;
+ int stream_valid;
+#endif
+ /* Decording PPMd data. */
+ int ppmd7_stat;
+ CPpmd7 ppmd7_context;
+ CPpmd7z_RangeDec range_dec;
+ IByteIn bytein;
+ struct {
+ const unsigned char *next_in;
+ int64_t avail_in;
+ int64_t total_in;
+ unsigned char *next_out;
+ int64_t avail_out;
+ int64_t total_out;
+ int overconsumed;
+ } ppstream;
+ int ppmd7_valid;
+
+ /* Decoding BCJ and BCJ2 data. */
+ uint32_t bcj_state;
+ size_t odd_bcj_size;
+ unsigned char odd_bcj[4];
+ /* Decoding BCJ data. */
+ size_t bcj_prevPosT;
+ uint32_t bcj_prevMask;
+ uint32_t bcj_ip;
+
+ /* Decoding BCJ2 data. */
+ size_t main_stream_bytes_remaining;
+ unsigned char *sub_stream_buff[3];
+ size_t sub_stream_size[3];
+ size_t sub_stream_bytes_remaining[3];
+ unsigned char *tmp_stream_buff;
+ size_t tmp_stream_buff_size;
+ size_t tmp_stream_bytes_avail;
+ size_t tmp_stream_bytes_remaining;
+#ifdef _LZMA_PROB32
+#define CProb uint32_t
+#else
+#define CProb uint16_t
+#endif
+ CProb bcj2_p[256 + 2];
+ uint8_t bcj2_prevByte;
+ uint32_t bcj2_range;
+ uint32_t bcj2_code;
+ uint64_t bcj2_outPos;
+
+ /* Filename character-set conversion data. */
+ struct archive_string_conv *sconv;
+
+ char format_name[64];
+};
+
+static int archive_read_format_7zip_bid(struct archive_read *, int);
+static int archive_read_format_7zip_cleanup(struct archive_read *);
+static int archive_read_format_7zip_read_data(struct archive_read *,
+ const void **, size_t *, int64_t *);
+static int archive_read_format_7zip_read_data_skip(struct archive_read *);
+static int archive_read_format_7zip_read_header(struct archive_read *,
+ struct archive_entry *);
+static int check_7zip_header_in_sfx(const char *);
+static unsigned long decode_codec_id(const unsigned char *, size_t);
+static int decode_encoded_header_info(struct archive_read *,
+ struct _7z_stream_info *);
+static int decompress(struct archive_read *, struct _7zip *,
+ void *, size_t *, const void *, size_t *);
+static ssize_t extract_pack_stream(struct archive_read *, size_t);
+static void fileTimeToUtc(uint64_t, time_t *, long *);
+static uint64_t folder_uncompressed_size(struct _7z_folder *);
+static void free_CodersInfo(struct _7z_coders_info *);
+static void free_Digest(struct _7z_digests *);
+static void free_Folder(struct _7z_folder *);
+static void free_Header(struct _7z_header_info *);
+static void free_PackInfo(struct _7z_pack_info *);
+static void free_StreamsInfo(struct _7z_stream_info *);
+static void free_SubStreamsInfo(struct _7z_substream_info *);
+static int free_decompression(struct archive_read *, struct _7zip *);
+static ssize_t get_uncompressed_data(struct archive_read *, const void **,
+ size_t, size_t);
+static const unsigned char * header_bytes(struct archive_read *, size_t);
+static int init_decompression(struct archive_read *, struct _7zip *,
+ const struct _7z_coder *, const struct _7z_coder *);
+static int parse_7zip_uint64(struct archive_read *, uint64_t *);
+static int read_Bools(struct archive_read *, unsigned char *, size_t);
+static int read_CodersInfo(struct archive_read *,
+ struct _7z_coders_info *);
+static int read_Digests(struct archive_read *, struct _7z_digests *,
+ size_t);
+static int read_Folder(struct archive_read *, struct _7z_folder *);
+static int read_Header(struct archive_read *, struct _7z_header_info *,
+ int);
+static int read_PackInfo(struct archive_read *, struct _7z_pack_info *);
+static int read_StreamsInfo(struct archive_read *,
+ struct _7z_stream_info *);
+static int read_SubStreamsInfo(struct archive_read *,
+ struct _7z_substream_info *, struct _7z_folder *, size_t);
+static int read_Times(struct archive_read *, struct _7z_header_info *,
+ int);
+static void read_consume(struct archive_read *);
+static ssize_t read_stream(struct archive_read *, const void **, size_t,
+ size_t);
+static int seek_pack(struct archive_read *);
+static int64_t skip_stream(struct archive_read *, size_t);
+static int skip_sfx(struct archive_read *, ssize_t);
+static int slurp_central_directory(struct archive_read *, struct _7zip *,
+ struct _7z_header_info *);
+static int setup_decode_folder(struct archive_read *, struct _7z_folder *,
+ int);
+static void x86_Init(struct _7zip *);
+static size_t x86_Convert(struct _7zip *, uint8_t *, size_t);
+static ssize_t Bcj2_Decode(struct _7zip *, uint8_t *, size_t);
+
+
+int
+archive_read_support_format_7zip(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct _7zip *zip;
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_7zip");
+
+ zip = calloc(1, sizeof(*zip));
+ if (zip == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate 7zip data");
+ return (ARCHIVE_FATAL);
+ }
+
+ r = __archive_read_register_format(a,
+ zip,
+ "7zip",
+ archive_read_format_7zip_bid,
+ NULL,
+ archive_read_format_7zip_read_header,
+ archive_read_format_7zip_read_data,
+ archive_read_format_7zip_read_data_skip,
+ archive_read_format_7zip_cleanup);
+
+ if (r != ARCHIVE_OK)
+ free(zip);
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_read_format_7zip_bid(struct archive_read *a, int best_bid)
+{
+ const char *p;
+
+ /* If someone has already bid more than 32, then avoid
+ trashing the look-ahead buffers with a seek. */
+ if (best_bid > 32)
+ return (-1);
+
+ if ((p = __archive_read_ahead(a, 6, NULL)) == NULL)
+ return (0);
+
+ /* If first six bytes are the 7-Zip signature,
+ * return the bid right now. */
+ if (memcmp(p, _7ZIP_SIGNATURE, 6) == 0)
+ return (48);
+
+ /*
+ * It may a 7-Zip SFX archive file. If first two bytes are
+ * 'M' and 'Z' available on Windows or first four bytes are
+ * "\x7F\x45LF" available on posix like system, seek the 7-Zip
+ * signature. Although we will perform a seek when reading
+ * a header, what we do not use __archive_read_seek() here is
+ * due to a bidding performance.
+ */
+ if ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0) {
+ ssize_t offset = SFX_MIN_ADDR;
+ ssize_t window = 4096;
+ ssize_t bytes_avail;
+ while (offset + window <= (SFX_MAX_ADDR)) {
+ const char *buff = __archive_read_ahead(a,
+ offset + window, &bytes_avail);
+ if (buff == NULL) {
+ /* Remaining bytes are less than window. */
+ window >>= 1;
+ if (window < 0x40)
+ return (0);
+ continue;
+ }
+ p = buff + offset;
+ while (p + 32 < buff + bytes_avail) {
+ int step = check_7zip_header_in_sfx(p);
+ if (step == 0)
+ return (48);
+ p += step;
+ }
+ offset = p - buff;
+ }
+ }
+ return (0);
+}
+
+static int
+check_7zip_header_in_sfx(const char *p)
+{
+ switch ((unsigned char)p[5]) {
+ case 0x1C:
+ if (memcmp(p, _7ZIP_SIGNATURE, 6) != 0)
+ return (6);
+ /*
+ * Test the CRC because its extraction code has 7-Zip
+ * Magic Code, so we should do this in order not to
+ * make a mis-detection.
+ */
+ if (crc32(0, (unsigned char *)p + 12, 20)
+ != archive_le32dec(p + 8))
+ return (6);
+ /* Hit the header! */
+ return (0);
+ case 0x37: return (5);
+ case 0x7A: return (4);
+ case 0xBC: return (3);
+ case 0xAF: return (2);
+ case 0x27: return (1);
+ default: return (6);
+ }
+}
+
+static int
+skip_sfx(struct archive_read *a, ssize_t bytes_avail)
+{
+ const void *h;
+ const char *p, *q;
+ size_t skip, offset;
+ ssize_t bytes, window;
+
+ /*
+ * If bytes_avail > SFX_MIN_ADDR we do not have to call
+ * __archive_read_seek() at this time since we have
+ * alredy had enough data.
+ */
+ if (bytes_avail > SFX_MIN_ADDR)
+ __archive_read_consume(a, SFX_MIN_ADDR);
+ else if (__archive_read_seek(a, SFX_MIN_ADDR, SEEK_SET) < 0)
+ return (ARCHIVE_FATAL);
+
+ offset = 0;
+ window = 1;
+ while (offset + window <= SFX_MAX_ADDR - SFX_MIN_ADDR) {
+ h = __archive_read_ahead(a, window, &bytes);
+ if (h == NULL) {
+ /* Remaining bytes are less than window. */
+ window >>= 1;
+ if (window < 0x40)
+ goto fatal;
+ continue;
+ }
+ if (bytes < 6) {
+ /* This case might happen when window == 1. */
+ window = 4096;
+ continue;
+ }
+ p = (const char *)h;
+ q = p + bytes;
+
+ /*
+ * Scan ahead until we find something that looks
+ * like the 7-Zip header.
+ */
+ while (p + 32 < q) {
+ int step = check_7zip_header_in_sfx(p);
+ if (step == 0) {
+ struct _7zip *zip =
+ (struct _7zip *)a->format->data;
+ skip = p - (const char *)h;
+ __archive_read_consume(a, skip);
+ zip->seek_base = SFX_MIN_ADDR + offset + skip;
+ return (ARCHIVE_OK);
+ }
+ p += step;
+ }
+ skip = p - (const char *)h;
+ __archive_read_consume(a, skip);
+ offset += skip;
+ if (window == 1)
+ window = 4096;
+ }
+fatal:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Couldn't find out 7-Zip header");
+ return (ARCHIVE_FATAL);
+}
+
+static int
+archive_read_format_7zip_read_header(struct archive_read *a,
+ struct archive_entry *entry)
+{
+ struct _7zip *zip = (struct _7zip *)a->format->data;
+ struct _7zip_entry *zip_entry;
+ int r, ret = ARCHIVE_OK;
+
+ a->archive.archive_format = ARCHIVE_FORMAT_7ZIP;
+ if (a->archive.archive_format_name == NULL)
+ a->archive.archive_format_name = "7-Zip";
+
+ if (zip->entries == NULL) {
+ struct _7z_header_info header;
+
+ memset(&header, 0, sizeof(header));
+ r = slurp_central_directory(a, zip, &header);
+ free_Header(&header);
+ if (r != ARCHIVE_OK)
+ return (r);
+ zip->entries_remaining = zip->numFiles;
+ zip->entry = zip->entries;
+ } else {
+ ++zip->entry;
+ }
+ zip_entry = zip->entry;
+
+ if (zip->entries_remaining <= 0)
+ return ARCHIVE_EOF;
+ --zip->entries_remaining;
+
+ zip->entry_offset = 0;
+ zip->end_of_entry = 0;
+ zip->entry_crc32 = crc32(0, NULL, 0);
+
+ /* Setup a string conversion for a filename. */
+ if (zip->sconv == NULL) {
+ zip->sconv = archive_string_conversion_from_charset(
+ &a->archive, "UTF-16LE", 1);
+ if (zip->sconv == NULL)
+ return (ARCHIVE_FATAL);
+ }
+
+ if (archive_entry_copy_pathname_l(entry,
+ (const char *)zip_entry->utf16name,
+ zip_entry->name_len, zip->sconv) != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Pathname cannot be converted "
+ "from %s to current locale.",
+ archive_string_conversion_charset_name(zip->sconv));
+ ret = ARCHIVE_WARN;
+ }
+
+ /* Populate some additional entry fields: */
+ archive_entry_set_mode(entry, zip_entry->mode);
+ if (zip_entry->flg & MTIME_IS_SET)
+ archive_entry_set_mtime(entry, zip_entry->mtime,
+ zip_entry->mtime_ns);
+ if (zip_entry->flg & CTIME_IS_SET)
+ archive_entry_set_ctime(entry, zip_entry->ctime,
+ zip_entry->ctime_ns);
+ if (zip_entry->flg & ATIME_IS_SET)
+ archive_entry_set_atime(entry, zip_entry->atime,
+ zip_entry->atime_ns);
+ if (zip_entry->ssIndex != -1) {
+ zip->entry_bytes_remaining =
+ zip->si.ss.unpackSizes[zip_entry->ssIndex];
+ archive_entry_set_size(entry, zip->entry_bytes_remaining);
+ } else {
+ zip->entry_bytes_remaining = 0;
+ archive_entry_set_size(entry, 0);
+ }
+
+ /* If there's no body, force read_data() to return EOF immediately. */
+ if (zip->entry_bytes_remaining < 1)
+ zip->end_of_entry = 1;
+
+ if ((zip_entry->mode & AE_IFMT) == AE_IFLNK) {
+ unsigned char *symname = NULL;
+ size_t symsize = 0;
+ int r;
+
+ /*
+ * Symbolic-name is recorded as its contents. We have to
+ * read the contents at this time.
+ */
+ while (zip->entry_bytes_remaining > 0) {
+ const void *buff;
+ size_t size;
+ int64_t offset;
+
+ r = archive_read_format_7zip_read_data(a, &buff,
+ &size, &offset);
+ if (r < ARCHIVE_WARN)
+ return (r);
+ symname = realloc(symname, symsize + size + 1);
+ if (symname == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Symname");
+ return (ARCHIVE_FATAL);
+ }
+ memcpy(symname+symsize, buff, size);
+ symsize += size;
+ }
+ if (symsize == 0) {
+ /* If there is no synname, handle it as a regular
+ * file. */
+ zip_entry->mode &= ~AE_IFMT;
+ zip_entry->mode |= AE_IFREG;
+ archive_entry_set_mode(entry, zip_entry->mode);
+ } else {
+ symname[symsize] = '\0';
+ archive_entry_copy_symlink(entry,
+ (const char *)symname);
+ free(symname);
+ }
+ archive_entry_set_size(entry, 0);
+ }
+
+ /* Set up a more descriptive format name. */
+ sprintf(zip->format_name, "7-Zip");
+ a->archive.archive_format_name = zip->format_name;
+
+ return (ret);
+}
+
+static int
+archive_read_format_7zip_read_data(struct archive_read *a,
+ const void **buff, size_t *size, int64_t *offset)
+{
+ struct _7zip *zip;
+ ssize_t bytes;
+ int ret = ARCHIVE_OK;
+
+ zip = (struct _7zip *)(a->format->data);
+
+ if (zip->pack_stream_bytes_unconsumed)
+ read_consume(a);
+
+ /*
+ * If we hit end-of-entry last time, clean up and return
+ * ARCHIVE_EOF this time.
+ */
+ if (zip->end_of_entry) {
+ *offset = zip->entry_offset;
+ *size = 0;
+ *buff = NULL;
+ return (ARCHIVE_EOF);
+ }
+
+ bytes = read_stream(a, buff, zip->entry_bytes_remaining, 0);
+ if (bytes < 0)
+ return ((int)bytes);
+ if (bytes == 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated 7-Zip file body");
+ return (ARCHIVE_FATAL);
+ }
+ zip->entry_bytes_remaining -= bytes;
+ if (zip->entry_bytes_remaining == 0)
+ zip->end_of_entry = 1;
+
+ /* Update checksum */
+ if ((zip->entry->flg & CRC32_IS_SET) && bytes)
+ zip->entry_crc32 = crc32(zip->entry_crc32, *buff, bytes);
+
+ /* If we hit the end, swallow any end-of-data marker. */
+ if (zip->end_of_entry) {
+ /* Check computed CRC against file contents. */
+ if ((zip->entry->flg & CRC32_IS_SET) &&
+ zip->si.ss.digests[zip->entry->ssIndex] !=
+ zip->entry_crc32) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "7-Zip bad CRC: 0x%lx should be 0x%lx",
+ (unsigned long)zip->entry_crc32,
+ (unsigned long)zip->si.ss.digests[
+ zip->entry->ssIndex]);
+ ret = ARCHIVE_WARN;
+ }
+ }
+
+ *size = bytes;
+ *offset = zip->entry_offset;
+ zip->entry_offset += bytes;
+
+ return (ret);
+}
+
+static int
+archive_read_format_7zip_read_data_skip(struct archive_read *a)
+{
+ struct _7zip *zip;
+ int64_t bytes_skipped;
+
+ zip = (struct _7zip *)(a->format->data);
+
+ if (zip->pack_stream_bytes_unconsumed)
+ read_consume(a);
+
+ /* If we've already read to end of data, we're done. */
+ if (zip->end_of_entry)
+ return (ARCHIVE_OK);
+
+ /*
+ * If the length is at the beginning, we can skip the
+ * compressed data much more quickly.
+ */
+ bytes_skipped = skip_stream(a, zip->entry_bytes_remaining);
+ if (bytes_skipped < 0)
+ return (ARCHIVE_FATAL);
+ zip->entry_bytes_remaining = 0;
+
+ /* This entry is finished and done. */
+ zip->end_of_entry = 1;
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_read_format_7zip_cleanup(struct archive_read *a)
+{
+ struct _7zip *zip;
+
+ zip = (struct _7zip *)(a->format->data);
+ free_StreamsInfo(&(zip->si));
+ free(zip->entries);
+ free(zip->entry_names);
+ free_decompression(a, zip);
+ free(zip->uncompressed_buffer);
+ free(zip->sub_stream_buff[0]);
+ free(zip->sub_stream_buff[1]);
+ free(zip->sub_stream_buff[2]);
+ free(zip->tmp_stream_buff);
+ free(zip);
+ (a->format->data) = NULL;
+ return (ARCHIVE_OK);
+}
+
+static void
+read_consume(struct archive_read *a)
+{
+ struct _7zip *zip = (struct _7zip *)a->format->data;
+
+ if (zip->pack_stream_bytes_unconsumed) {
+ __archive_read_consume(a, zip->pack_stream_bytes_unconsumed);
+ zip->stream_offset += zip->pack_stream_bytes_unconsumed;
+ zip->pack_stream_bytes_unconsumed = 0;
+ }
+}
+
+#ifdef HAVE_LZMA_H
+
+/*
+ * Set an error code and choose an error message for liblzma.
+ */
+static void
+set_error(struct archive_read *a, int ret)
+{
+
+ switch (ret) {
+ case LZMA_STREAM_END: /* Found end of stream. */
+ case LZMA_OK: /* Decompressor made some progress. */
+ break;
+ case LZMA_MEM_ERROR:
+ archive_set_error(&a->archive, ENOMEM,
+ "Lzma library error: Cannot allocate memory");
+ break;
+ case LZMA_MEMLIMIT_ERROR:
+ archive_set_error(&a->archive, ENOMEM,
+ "Lzma library error: Out of memory");
+ break;
+ case LZMA_FORMAT_ERROR:
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Lzma library error: format not recognized");
+ break;
+ case LZMA_OPTIONS_ERROR:
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Lzma library error: Invalid options");
+ break;
+ case LZMA_DATA_ERROR:
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Lzma library error: Corrupted input data");
+ break;
+ case LZMA_BUF_ERROR:
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Lzma library error: No progress is possible");
+ break;
+ default:
+ /* Return an error. */
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Lzma decompression failed: Unknown error");
+ break;
+ }
+}
+
+#endif
+
+static unsigned long
+decode_codec_id(const unsigned char *codecId, size_t id_size)
+{
+ unsigned i;
+ unsigned long id = 0;
+
+ for (i = 0; i < id_size; i++) {
+ id <<= 8;
+ id += codecId[i];
+ }
+ return (id);
+}
+
+static void *
+ppmd_alloc(void *p, size_t size)
+{
+ (void)p;
+ return malloc(size);
+}
+static void
+ppmd_free(void *p, void *address)
+{
+ (void)p;
+ free(address);
+}
+static Byte
+ppmd_read(void *p)
+{
+ struct archive_read *a = ((IByteIn*)p)->a;
+ struct _7zip *zip = (struct _7zip *)(a->format->data);
+ Byte b;
+
+ if (zip->ppstream.avail_in == 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated RAR file data");
+ zip->ppstream.overconsumed = 1;
+ return (0);
+ }
+ b = *zip->ppstream.next_in++;
+ zip->ppstream.avail_in--;
+ zip->ppstream.total_in++;
+ return (b);
+}
+
+static ISzAlloc g_szalloc = { ppmd_alloc, ppmd_free };
+
+static int
+init_decompression(struct archive_read *a, struct _7zip *zip,
+ const struct _7z_coder *coder1, const struct _7z_coder *coder2)
+{
+ int r;
+
+ zip->codec = coder1->codec;
+ zip->codec2 = -1;
+
+ switch (zip->codec) {
+ case _7Z_COPY:
+ case _7Z_BZ2:
+ case _7Z_DEFLATE:
+ case _7Z_PPMD:
+ if (coder2 != NULL) {
+ if (coder2->codec != _7Z_X86 &&
+ coder2->codec != _7Z_X86_BCJ2) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Unsupported filter %lx for %lx",
+ coder2->codec, coder1->codec);
+ return (ARCHIVE_FAILED);
+ }
+ zip->codec2 = coder2->codec;
+ zip->bcj_state = 0;
+ if (coder2->codec == _7Z_X86)
+ x86_Init(zip);
+ }
+ break;
+ default:
+ break;
+ }
+
+ switch (zip->codec) {
+ case _7Z_COPY:
+ break;
+
+ case _7Z_LZMA: case _7Z_LZMA2:
+#ifdef HAVE_LZMA_H
+#if LZMA_VERSION_MAJOR >= 5
+/* Effectively disable the limiter. */
+#define LZMA_MEMLIMIT UINT64_MAX
+#else
+/* NOTE: This needs to check memory size which running system has. */
+#define LZMA_MEMLIMIT (1U << 30)
+#endif
+ {
+ lzma_options_delta delta_opt;
+ lzma_filter filters[LZMA_FILTERS_MAX];
+#if LZMA_VERSION < 50000030
+ lzma_filter *ff;
+#endif
+ int fi = 0;
+
+ if (zip->lzstream_valid) {
+ lzma_end(&(zip->lzstream));
+ zip->lzstream_valid = 0;
+ }
+
+ /*
+ * NOTE: liblzma incompletely handle the BCJ+LZMA compressed
+ * data made by 7-Zip because 7-Zip does not add End-Of-
+ * Payload Marker(EOPM) at the end of LZMA compressed data,
+ * and so liblzma cannot know the end of the compressed data
+ * without EOPM. So consequently liblzma will not return last
+ * three or four bytes of uncompressed data because
+ * LZMA_FILTER_X86 filter does not handle input data if its
+ * data size is less than five bytes. If liblzma detect EOPM
+ * or know the uncompressed data size, liblzma will flush out
+ * the remaining that three or four bytes of uncompressed
+ * data. That is why we have to use our converting program
+ * for BCJ+LZMA. If we were able to tell the uncompressed
+ * size to liblzma when using lzma_raw_decoder() liblzma
+ * could correctly deal with BCJ+LZMA. But unfortunately
+ * there is no way to do that.
+ * Discussion about this can be found at XZ Utils forum.
+ */
+ if (coder2 != NULL) {
+ zip->codec2 = coder2->codec;
+
+ filters[fi].options = NULL;
+ switch (zip->codec2) {
+ case _7Z_X86:
+ if (zip->codec == _7Z_LZMA2) {
+ filters[fi].id = LZMA_FILTER_X86;
+ fi++;
+ } else
+ /* Use our filter. */
+ x86_Init(zip);
+ break;
+ case _7Z_X86_BCJ2:
+ /* Use our filter. */
+ zip->bcj_state = 0;
+ break;
+ case _7Z_DELTA:
+ filters[fi].id = LZMA_FILTER_DELTA;
+ memset(&delta_opt, 0, sizeof(delta_opt));
+ delta_opt.type = LZMA_DELTA_TYPE_BYTE;
+ delta_opt.dist = 1;
+ filters[fi].options = &delta_opt;
+ fi++;
+ break;
+ /* Following filters have not been tested yet. */
+ case _7Z_POWERPC:
+ filters[fi].id = LZMA_FILTER_POWERPC;
+ fi++;
+ break;
+ case _7Z_IA64:
+ filters[fi].id = LZMA_FILTER_IA64;
+ fi++;
+ break;
+ case _7Z_ARM:
+ filters[fi].id = LZMA_FILTER_ARM;
+ fi++;
+ break;
+ case _7Z_ARMTHUMB:
+ filters[fi].id = LZMA_FILTER_ARMTHUMB;
+ fi++;
+ break;
+ case _7Z_SPARC:
+ filters[fi].id = LZMA_FILTER_SPARC;
+ fi++;
+ break;
+ default:
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Unexpected codec ID: %lX", zip->codec2);
+ return (ARCHIVE_FAILED);
+ }
+ }
+
+ if (zip->codec == _7Z_LZMA2)
+ filters[fi].id = LZMA_FILTER_LZMA2;
+ else
+ filters[fi].id = LZMA_FILTER_LZMA1;
+ filters[fi].options = NULL;
+#if LZMA_VERSION < 50000030
+ ff = &filters[fi];
+#endif
+ r = lzma_properties_decode(&filters[fi], NULL,
+ coder1->properties, coder1->propertiesSize);
+ if (r != LZMA_OK) {
+ set_error(a, r);
+ return (ARCHIVE_FAILED);
+ }
+ fi++;
+
+ filters[fi].id = LZMA_VLI_UNKNOWN;
+ filters[fi].options = NULL;
+ r = lzma_raw_decoder(&(zip->lzstream), filters);
+#if LZMA_VERSION < 50000030
+ free(ff->options);
+#endif
+ if (r != LZMA_OK) {
+ set_error(a, r);
+ return (ARCHIVE_FAILED);
+ }
+ zip->lzstream_valid = 1;
+ zip->lzstream.total_in = 0;
+ zip->lzstream.total_out = 0;
+ break;
+ }
+#else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "LZMA codec is unsupported");
+ return (ARCHIVE_FAILED);
+#endif
+ case _7Z_BZ2:
+#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
+ if (zip->bzstream_valid) {
+ BZ2_bzDecompressEnd(&(zip->bzstream));
+ zip->bzstream_valid = 0;
+ }
+ r = BZ2_bzDecompressInit(&(zip->bzstream), 0, 0);
+ if (r == BZ_MEM_ERROR)
+ r = BZ2_bzDecompressInit(&(zip->bzstream), 0, 1);
+ if (r != BZ_OK) {
+ int err = ARCHIVE_ERRNO_MISC;
+ const char *detail = NULL;
+ switch (r) {
+ case BZ_PARAM_ERROR:
+ detail = "invalid setup parameter";
+ break;
+ case BZ_MEM_ERROR:
+ err = ENOMEM;
+ detail = "out of memory";
+ break;
+ case BZ_CONFIG_ERROR:
+ detail = "mis-compiled library";
+ break;
+ }
+ archive_set_error(&a->archive, err,
+ "Internal error initializing decompressor: %s",
+ detail == NULL ? "??" : detail);
+ zip->bzstream_valid = 0;
+ return (ARCHIVE_FAILED);
+ }
+ zip->bzstream_valid = 1;
+ zip->bzstream.total_in_lo32 = 0;
+ zip->bzstream.total_in_hi32 = 0;
+ zip->bzstream.total_out_lo32 = 0;
+ zip->bzstream.total_out_hi32 = 0;
+ break;
+#else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "BZ2 codec is unsupported");
+ return (ARCHIVE_FAILED);
+#endif
+ case _7Z_DEFLATE:
+#ifdef HAVE_ZLIB_H
+ if (zip->stream_valid)
+ r = inflateReset(&(zip->stream));
+ else
+ r = inflateInit2(&(zip->stream),
+ -15 /* Don't check for zlib header */);
+ if (r != Z_OK) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Couldn't initialize zlib stream.");
+ return (ARCHIVE_FAILED);
+ }
+ zip->stream_valid = 1;
+ zip->stream.total_in = 0;
+ zip->stream.total_out = 0;
+ break;
+#else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "DEFLATE codec is unsupported");
+ return (ARCHIVE_FAILED);
+#endif
+ case _7Z_PPMD:
+ {
+ unsigned order;
+ uint32_t msize;
+
+ if (zip->ppmd7_valid) {
+ __archive_ppmd7_functions.Ppmd7_Free(
+ &zip->ppmd7_context, &g_szalloc);
+ zip->ppmd7_valid = 0;
+ }
+
+ if (coder1->propertiesSize < 5) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Malformed PPMd parameter");
+ return (ARCHIVE_FAILED);
+ }
+ order = coder1->properties[0];
+ msize = archive_le32dec(&(coder1->properties[1]));
+ if (order < PPMD7_MIN_ORDER || order > PPMD7_MAX_ORDER ||
+ msize < PPMD7_MIN_MEM_SIZE || msize > PPMD7_MAX_MEM_SIZE) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Malformed PPMd parameter");
+ return (ARCHIVE_FAILED);
+ }
+ __archive_ppmd7_functions.Ppmd7_Construct(&zip->ppmd7_context);
+ r = __archive_ppmd7_functions.Ppmd7_Alloc(
+ &zip->ppmd7_context, msize, &g_szalloc);
+ if (r == 0) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Coludn't allocate memory for PPMd");
+ return (ARCHIVE_FATAL);
+ }
+ __archive_ppmd7_functions.Ppmd7_Init(
+ &zip->ppmd7_context, order);
+ __archive_ppmd7_functions.Ppmd7z_RangeDec_CreateVTable(
+ &zip->range_dec);
+ zip->ppmd7_valid = 1;
+ zip->ppmd7_stat = 0;
+ zip->ppstream.overconsumed = 0;
+ zip->ppstream.total_in = 0;
+ zip->ppstream.total_out = 0;
+ break;
+ }
+ case _7Z_X86:
+ case _7Z_X86_BCJ2:
+ case _7Z_POWERPC:
+ case _7Z_IA64:
+ case _7Z_ARM:
+ case _7Z_ARMTHUMB:
+ case _7Z_SPARC:
+ case _7Z_DELTA:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Unexpected codec ID: %lX", zip->codec);
+ return (ARCHIVE_FAILED);
+ default:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Unknown codec ID: %lX", zip->codec);
+ return (ARCHIVE_FAILED);
+ }
+
+ return (ARCHIVE_OK);
+}
+
+static int
+decompress(struct archive_read *a, struct _7zip *zip,
+ void *buff, size_t *outbytes, const void *b, size_t *used)
+{
+ const uint8_t *t_next_in;
+ uint8_t *t_next_out;
+ size_t o_avail_in, o_avail_out;
+ size_t t_avail_in, t_avail_out;
+ uint8_t *bcj2_next_out;
+ size_t bcj2_avail_out;
+ int r, ret = ARCHIVE_OK;
+
+ t_avail_in = o_avail_in = *used;
+ t_avail_out = o_avail_out = *outbytes;
+ t_next_in = b;
+ t_next_out = buff;
+
+ if (zip->codec != _7Z_LZMA2 && zip->codec2 == _7Z_X86) {
+ int i;
+
+ /* Do not copy out the BCJ remaining bytes when the output
+ * buffer size is less than five bytes. */
+ if (o_avail_in != 0 && t_avail_out < 5 && zip->odd_bcj_size) {
+ *used = 0;
+ *outbytes = 0;
+ return (ret);
+ }
+ for (i = 0; zip->odd_bcj_size > 0 && t_avail_out; i++) {
+ *t_next_out++ = zip->odd_bcj[i];
+ t_avail_out--;
+ zip->odd_bcj_size--;
+ }
+ if (o_avail_in == 0 || t_avail_out == 0) {
+ *used = o_avail_in - t_avail_in;
+ *outbytes = o_avail_out - t_avail_out;
+ if (o_avail_in == 0)
+ ret = ARCHIVE_EOF;
+ return (ret);
+ }
+ }
+
+ bcj2_next_out = t_next_out;
+ bcj2_avail_out = t_avail_out;
+ if (zip->codec2 == _7Z_X86_BCJ2) {
+ /*
+ * Decord a remaining decompressed main stream for BCJ2.
+ */
+ if (zip->tmp_stream_bytes_remaining) {
+ ssize_t bytes;
+ size_t remaining = zip->tmp_stream_bytes_remaining;
+ bytes = Bcj2_Decode(zip, t_next_out, t_avail_out);
+ if (bytes < 0) {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "BCJ2 conversion Failed");
+ return (ARCHIVE_FAILED);
+ }
+ zip->main_stream_bytes_remaining -=
+ remaining - zip->tmp_stream_bytes_remaining;
+ t_avail_out -= bytes;
+ if (o_avail_in == 0 || t_avail_out == 0) {
+ *used = 0;
+ *outbytes = o_avail_out - t_avail_out;
+ if (o_avail_in == 0 &&
+ zip->tmp_stream_bytes_remaining)
+ ret = ARCHIVE_EOF;
+ return (ret);
+ }
+ t_next_out += bytes;
+ bcj2_next_out = t_next_out;
+ bcj2_avail_out = t_avail_out;
+ }
+ t_next_out = zip->tmp_stream_buff;
+ t_avail_out = zip->tmp_stream_buff_size;
+ }
+
+ switch (zip->codec) {
+ case _7Z_COPY:
+ {
+ size_t bytes =
+ (t_avail_in > t_avail_out)?t_avail_out:t_avail_in;
+
+ memcpy(t_next_out, t_next_in, bytes);
+ t_avail_in -= bytes;
+ t_avail_out -= bytes;
+ if (o_avail_in == 0)
+ ret = ARCHIVE_EOF;
+ break;
+ }
+#ifdef HAVE_LZMA_H
+ case _7Z_LZMA: case _7Z_LZMA2:
+ zip->lzstream.next_in = t_next_in;
+ zip->lzstream.avail_in = t_avail_in;
+ zip->lzstream.next_out = t_next_out;
+ zip->lzstream.avail_out = t_avail_out;
+
+ r = lzma_code(&(zip->lzstream), LZMA_RUN);
+ switch (r) {
+ case LZMA_STREAM_END: /* Found end of stream. */
+ lzma_end(&(zip->lzstream));
+ zip->lzstream_valid = 0;
+ ret = ARCHIVE_EOF;
+ break;
+ case LZMA_OK: /* Decompressor made some progress. */
+ break;
+ default:
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "Decompression failed(%d)",
+ r);
+ return (ARCHIVE_FAILED);
+ }
+ t_avail_in = zip->lzstream.avail_in;
+ t_avail_out = zip->lzstream.avail_out;
+ break;
+#endif
+#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
+ case _7Z_BZ2:
+ zip->bzstream.next_in = (char *)(uintptr_t)t_next_in;
+ zip->bzstream.avail_in = t_avail_in;
+ zip->bzstream.next_out = (char *)(uintptr_t)t_next_out;
+ zip->bzstream.avail_out = t_avail_out;
+ r = BZ2_bzDecompress(&(zip->bzstream));
+ switch (r) {
+ case BZ_STREAM_END: /* Found end of stream. */
+ switch (BZ2_bzDecompressEnd(&(zip->bzstream))) {
+ case BZ_OK:
+ break;
+ default:
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "Failed to clean up decompressor");
+ return (ARCHIVE_FAILED);
+ }
+ zip->bzstream_valid = 0;
+ ret = ARCHIVE_EOF;
+ break;
+ case BZ_OK: /* Decompressor made some progress. */
+ break;
+ default:
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "bzip decompression failed");
+ return (ARCHIVE_FAILED);
+ }
+ t_avail_in = zip->bzstream.avail_in;
+ t_avail_out = zip->bzstream.avail_out;
+ break;
+#endif
+#ifdef HAVE_ZLIB_H
+ case _7Z_DEFLATE:
+ zip->stream.next_in = (Bytef *)(uintptr_t)t_next_in;
+ zip->stream.avail_in = t_avail_in;
+ zip->stream.next_out = t_next_out;
+ zip->stream.avail_out = t_avail_out;
+ r = inflate(&(zip->stream), 0);
+ switch (r) {
+ case Z_STREAM_END: /* Found end of stream. */
+ ret = ARCHIVE_EOF;
+ break;
+ case Z_OK: /* Decompressor made some progress.*/
+ break;
+ default:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "File decompression failed (%d)", r);
+ return (ARCHIVE_FAILED);
+ }
+ t_avail_in = zip->stream.avail_in;
+ t_avail_out = zip->stream.avail_out;
+ break;
+#endif
+ case _7Z_PPMD:
+ {
+ uint64_t flush_bytes;
+
+ if (!zip->ppmd7_valid || zip->ppmd7_stat < 0 ||
+ t_avail_out <= 0) {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "Decompression internal error");
+ return (ARCHIVE_FAILED);
+ }
+ zip->ppstream.next_in = t_next_in;
+ zip->ppstream.avail_in = t_avail_in;
+ zip->ppstream.next_out = t_next_out;
+ zip->ppstream.avail_out = t_avail_out;
+ if (zip->ppmd7_stat == 0) {
+ zip->bytein.a = a;
+ zip->bytein.Read = &ppmd_read;
+ zip->range_dec.Stream = &zip->bytein;
+ r = __archive_ppmd7_functions.Ppmd7z_RangeDec_Init(
+ &(zip->range_dec));
+ if (r == 0) {
+ zip->ppmd7_stat = -1;
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Failed to initialize PPMd range decorder");
+ return (ARCHIVE_FAILED);
+ }
+ if (zip->ppstream.overconsumed) {
+ zip->ppmd7_stat = -1;
+ return (ARCHIVE_FAILED);
+ }
+ zip->ppmd7_stat = 1;
+ }
+
+ if (t_avail_in == 0)
+ /* XXX Flush out remaining decoded data XXX */
+ flush_bytes = zip->folder_outbytes_remaining;
+ else
+ flush_bytes = 0;
+
+ do {
+ int sym;
+
+ sym = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
+ &(zip->ppmd7_context), &(zip->range_dec.p));
+ if (sym < 0) {
+ zip->ppmd7_stat = -1;
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Failed to decode PPMd");
+ return (ARCHIVE_FAILED);
+ }
+ if (zip->ppstream.overconsumed) {
+ zip->ppmd7_stat = -1;
+ return (ARCHIVE_FAILED);
+ }
+ *zip->ppstream.next_out++ = (unsigned char)sym;
+ zip->ppstream.avail_out--;
+ zip->ppstream.total_out++;
+ if (flush_bytes)
+ flush_bytes--;
+ } while (zip->ppstream.avail_out &&
+ (zip->ppstream.avail_in || flush_bytes));
+
+ t_avail_in = zip->ppstream.avail_in;
+ t_avail_out = zip->ppstream.avail_out;
+ break;
+ }
+ default:
+ archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
+ "Decompression internal error");
+ return (ARCHIVE_FAILED);
+ }
+ if (ret != ARCHIVE_OK && ret != ARCHIVE_EOF)
+ return (ret);
+
+ *used = o_avail_in - t_avail_in;
+ *outbytes = o_avail_out - t_avail_out;
+
+ /*
+ * Decord BCJ.
+ */
+ if (zip->codec != _7Z_LZMA2 && zip->codec2 == _7Z_X86) {
+ size_t l = x86_Convert(zip, buff, *outbytes);
+ zip->odd_bcj_size = *outbytes - l;
+ if (zip->odd_bcj_size > 0 && zip->odd_bcj_size <= 4 &&
+ o_avail_in && ret != ARCHIVE_EOF) {
+ memcpy(zip->odd_bcj, ((unsigned char *)buff) + l,
+ zip->odd_bcj_size);
+ *outbytes = l;
+ } else
+ zip->odd_bcj_size = 0;
+ }
+
+ /*
+ * Decord BCJ2 with a decompressed main stream.
+ */
+ if (zip->codec2 == _7Z_X86_BCJ2) {
+ ssize_t bytes;
+
+ zip->tmp_stream_bytes_avail =
+ zip->tmp_stream_buff_size - t_avail_out;
+ if (zip->tmp_stream_bytes_avail >
+ zip->main_stream_bytes_remaining)
+ zip->tmp_stream_bytes_avail =
+ zip->main_stream_bytes_remaining;
+ zip->tmp_stream_bytes_remaining = zip->tmp_stream_bytes_avail;
+ bytes = Bcj2_Decode(zip, bcj2_next_out, bcj2_avail_out);
+ if (bytes < 0) {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC, "BCJ2 conversion Failed");
+ return (ARCHIVE_FAILED);
+ }
+ zip->main_stream_bytes_remaining -=
+ zip->tmp_stream_bytes_avail
+ - zip->tmp_stream_bytes_remaining;
+ bcj2_avail_out -= bytes;
+ *outbytes = o_avail_out - bcj2_avail_out;
+ }
+
+ return (ret);
+}
+
+static int
+free_decompression(struct archive_read *a, struct _7zip *zip)
+{
+ int r = ARCHIVE_OK;
+
+#ifdef HAVE_LZMA_H
+ if (zip->lzstream_valid)
+ lzma_end(&(zip->lzstream));
+#endif
+#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
+ if (zip->bzstream_valid) {
+ if (BZ2_bzDecompressEnd(&(zip->bzstream)) != BZ_OK) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Failed to clean up bzip2 decompressor");
+ r = ARCHIVE_FATAL;
+ }
+ zip->bzstream_valid = 0;
+ }
+#endif
+#ifdef HAVE_ZLIB_H
+ if (zip->stream_valid) {
+ if (inflateEnd(&(zip->stream)) != Z_OK) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Failed to clean up zlib decompressor");
+ r = ARCHIVE_FATAL;
+ }
+ zip->stream_valid = 0;
+ }
+#endif
+ if (zip->ppmd7_valid) {
+ __archive_ppmd7_functions.Ppmd7_Free(
+ &zip->ppmd7_context, &g_szalloc);
+ zip->ppmd7_valid = 0;
+ }
+ return (r);
+}
+
+static int
+parse_7zip_uint64(struct archive_read *a, uint64_t *val)
+{
+ const unsigned char *p;
+ unsigned char avail, mask;
+ int i;
+
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ avail = *p;
+ mask = 0x80;
+ *val = 0;
+ for (i = 0; i < 8; i++) {
+ if (avail & mask) {
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ *val |= ((uint64_t)*p) << (8 * i);
+ mask >>= 1;
+ continue;
+ }
+ *val += (avail & (mask -1)) << (8 * i);
+ break;
+ }
+ return (0);
+}
+
+static int
+read_Bools(struct archive_read *a, unsigned char *data, size_t num)
+{
+ const unsigned char *p;
+ unsigned i, mask = 0, avail = 0;
+
+ for (i = 0; i < num; i++) {
+ if (mask == 0) {
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ avail = *p;
+ mask = 0x80;
+ }
+ data[i] = (avail & mask)?1:0;
+ mask >>= 1;
+ }
+ return (0);
+}
+
+static void
+free_Digest(struct _7z_digests *d)
+{
+ free(d->defineds);
+ free(d->digests);
+}
+
+static int
+read_Digests(struct archive_read *a, struct _7z_digests *d, size_t num)
+{
+ const unsigned char *p;
+ unsigned i;
+
+ memset(d, 0, sizeof(*d));
+
+
+ d->defineds = malloc(num);
+ if (d->defineds == NULL)
+ return (-1);
+ /*
+ * Read Bools.
+ */
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ if (*p == 0) {
+ if (read_Bools(a, d->defineds, num) < 0)
+ return (-1);
+ } else
+ /* All are defined */
+ memset(d->defineds, 1, num);
+
+ d->digests = calloc(num, sizeof(*d->digests));
+ if (d->digests == NULL)
+ return (-1);
+ for (i = 0; i < num; i++) {
+ if (d->defineds[i]) {
+ if ((p = header_bytes(a, 4)) == NULL)
+ return (-1);
+ d->digests[i] = archive_le32dec(p);
+ }
+ }
+
+ return (0);
+}
+
+static void
+free_PackInfo(struct _7z_pack_info *pi)
+{
+ free(pi->sizes);
+ free(pi->positions);
+ free_Digest(&(pi->digest));
+}
+
+static int
+read_PackInfo(struct archive_read *a, struct _7z_pack_info *pi)
+{
+ const unsigned char *p;
+ unsigned i;
+
+ memset(pi, 0, sizeof(*pi));
+
+ /*
+ * Read PackPos.
+ */
+ if (parse_7zip_uint64(a, &(pi->pos)) < 0)
+ return (-1);
+
+ /*
+ * Read NumPackStreams.
+ */
+ if (parse_7zip_uint64(a, &(pi->numPackStreams)) < 0)
+ return (-1);
+ if (pi->numPackStreams == 0)
+ return (-1);
+ if (1000000 < pi->numPackStreams)
+ return (-1);
+
+ /*
+ * Read PackSizes[num]
+ */
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ if (*p == kEnd)
+ /* PackSizes[num] are not present. */
+ return (0);
+ if (*p != kSize)
+ return (-1);
+ pi->sizes = calloc(pi->numPackStreams, sizeof(uint64_t));
+ pi->positions = calloc(pi->numPackStreams, sizeof(uint64_t));
+ if (pi->sizes == NULL || pi->positions == NULL)
+ return (-1);
+
+ for (i = 0; i < pi->numPackStreams; i++) {
+ if (parse_7zip_uint64(a, &(pi->sizes[i])) < 0)
+ return (-1);
+ }
+
+ /*
+ * Read PackStreamDigests[num]
+ */
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ if (*p == kEnd) {
+ /* PackStreamDigests[num] are not present. */
+ pi->digest.defineds =
+ calloc(pi->numPackStreams, sizeof(*pi->digest.defineds));
+ pi->digest.digests =
+ calloc(pi->numPackStreams, sizeof(*pi->digest.digests));
+ if (pi->digest.defineds == NULL || pi->digest.digests == NULL)
+ return (-1);
+ return (0);
+ }
+
+ if (*p != kSize)
+ return (-1);
+
+ if (read_Digests(a, &(pi->digest), pi->numPackStreams) < 0)
+ return (-1);
+
+ /*
+ * Must be marked by kEnd.
+ */
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ if (*p != kEnd)
+ return (-1);
+ return (0);
+}
+
+static void
+free_Folder(struct _7z_folder *f)
+{
+ unsigned i;
+
+ if (f->coders) {
+ for (i = 0; i< f->numCoders; i++) {
+ free(f->coders[i].properties);
+ }
+ free(f->coders);
+ }
+ free(f->bindPairs);
+ free(f->packedStreams);
+ free(f->unPackSize);
+}
+
+static int
+read_Folder(struct archive_read *a, struct _7z_folder *f)
+{
+ struct _7zip *zip = (struct _7zip *)a->format->data;
+ const unsigned char *p;
+ uint64_t numInStreamsTotal = 0;
+ uint64_t numOutStreamsTotal = 0;
+ unsigned i;
+
+ memset(f, 0, sizeof(*f));
+
+ /*
+ * Read NumCoders.
+ */
+ if (parse_7zip_uint64(a, &(f->numCoders)) < 0)
+ return (-1);
+ if (f->numCoders > 4)
+ /* Too many coders. */
+ return (-1);
+
+ f->coders = calloc(f->numCoders, sizeof(*f->coders));
+ if (f->coders == NULL)
+ return (-1);
+ for (i = 0; i< f->numCoders; i++) {
+ size_t codec_size;
+ int simple, attr;
+
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ /*
+ * 0:3 CodecIdSize
+ * 4: 0 - IsSimple
+ * 1 - Is not Simple
+ * 5: 0 - No Attributes
+ * 1 - There are Attributes;
+ * 7: Must be zero.
+ */
+ codec_size = *p & 0xf;
+ simple = (*p & 0x10)?0:1;
+ attr = *p & 0x20;
+ if (*p & 0x80)
+ return (-1);/* Not supported. */
+
+ /*
+ * Read Decompression Method IDs.
+ */
+ if ((p = header_bytes(a, codec_size)) == NULL)
+ return (-1);
+
+ f->coders[i].codec = decode_codec_id(p, codec_size);
+
+ if (simple) {
+ f->coders[i].numInStreams = 1;
+ f->coders[i].numOutStreams = 1;
+ } else {
+ if (parse_7zip_uint64(
+ a, &(f->coders[i].numInStreams)) < 0)
+ return (-1);
+ if (1000000 < f->coders[i].numInStreams)
+ return (-1);
+ if (parse_7zip_uint64(
+ a, &(f->coders[i].numOutStreams)) < 0)
+ return (-1);
+ if (1000000 < f->coders[i].numOutStreams)
+ return (-1);
+ }
+
+ if (attr) {
+ if (parse_7zip_uint64(
+ a, &(f->coders[i].propertiesSize)) < 0)
+ return (-1);
+ if ((p = header_bytes(
+ a, f->coders[i].propertiesSize)) == NULL)
+ return (-1);
+ f->coders[i].properties =
+ malloc(f->coders[i].propertiesSize);
+ if (f->coders[i].properties == NULL)
+ return (-1);
+ memcpy(f->coders[i].properties, p,
+ f->coders[i].propertiesSize);
+ }
+
+ numInStreamsTotal += f->coders[i].numInStreams;
+ numOutStreamsTotal += f->coders[i].numOutStreams;
+ }
+
+ if (numOutStreamsTotal == 0 ||
+ numInStreamsTotal < numOutStreamsTotal-1)
+ return (-1);
+
+ f->numBindPairs = numOutStreamsTotal - 1;
+ if (zip->header_bytes_remaining < f->numBindPairs)
+ return (-1);
+ f->bindPairs = calloc(f->numBindPairs, sizeof(*f->bindPairs));
+ if (f->bindPairs == NULL)
+ return (-1);
+ for (i = 0; i < f->numBindPairs; i++) {
+ if (parse_7zip_uint64(a, &(f->bindPairs[i].inIndex)) < 0)
+ return (-1);
+ if (1000000 < f->bindPairs[i].inIndex)
+ return (-1);
+ if (parse_7zip_uint64(a, &(f->bindPairs[i].outIndex)) < 0)
+ return (-1);
+ if (1000000 < f->bindPairs[i].outIndex)
+ return (-1);
+ }
+
+ f->numPackedStreams = numInStreamsTotal - f->numBindPairs;
+ f->packedStreams =
+ calloc(f->numPackedStreams, sizeof(*f->packedStreams));
+ if (f->packedStreams == NULL)
+ return (-1);
+ if (f->numPackedStreams == 1) {
+ for (i = 0; i < numInStreamsTotal; i++) {
+ unsigned j;
+ for (j = 0; j < f->numBindPairs; j++) {
+ if (f->bindPairs[j].inIndex == i)
+ break;
+ }
+ if (j == f->numBindPairs)
+ break;
+ }
+ if (i == numInStreamsTotal)
+ return (-1);
+ f->packedStreams[0] = i;
+ } else {
+ for (i = 0; i < f->numPackedStreams; i++) {
+ if (parse_7zip_uint64(a, &(f->packedStreams[i])) < 0)
+ return (-1);
+ if (1000000 < f->packedStreams[i])
+ return (-1);
+ }
+ }
+ f->numInStreams = numInStreamsTotal;
+ f->numOutStreams = numOutStreamsTotal;
+
+ return (0);
+}
+
+static void
+free_CodersInfo(struct _7z_coders_info *ci)
+{
+ unsigned i;
+
+ if (ci->folders) {
+ for (i = 0; i < ci->numFolders; i++)
+ free_Folder(&(ci->folders[i]));
+ free(ci->folders);
+ }
+}
+
+static int
+read_CodersInfo(struct archive_read *a, struct _7z_coders_info *ci)
+{
+ const unsigned char *p;
+ struct _7z_digests digest;
+ unsigned i;
+
+ memset(ci, 0, sizeof(*ci));
+ memset(&digest, 0, sizeof(digest));
+
+ if ((p = header_bytes(a, 1)) == NULL)
+ goto failed;
+ if (*p != kFolder)
+ goto failed;
+
+ /*
+ * Read NumFolders.
+ */
+ if (parse_7zip_uint64(a, &(ci->numFolders)) < 0)
+ goto failed;
+ if (1000000 < ci->numFolders)
+ return (-1);
+
+ /*
+ * Read External.
+ */
+ if ((p = header_bytes(a, 1)) == NULL)
+ goto failed;
+ switch (*p) {
+ case 0:
+ ci->folders = calloc(ci->numFolders, sizeof(*ci->folders));
+ if (ci->folders == NULL)
+ return (-1);
+ for (i = 0; i < ci->numFolders; i++) {
+ if (read_Folder(a, &(ci->folders[i])) < 0)
+ goto failed;
+ }
+ break;
+ case 1:
+ if (parse_7zip_uint64(a, &(ci->dataStreamIndex)) < 0)
+ return (-1);
+ if (1000000 < ci->dataStreamIndex)
+ return (-1);
+ break;
+ }
+
+ if ((p = header_bytes(a, 1)) == NULL)
+ goto failed;
+ if (*p != kCodersUnPackSize)
+ goto failed;
+
+ for (i = 0; i < ci->numFolders; i++) {
+ struct _7z_folder *folder = &(ci->folders[i]);
+ unsigned j;
+
+ folder->unPackSize =
+ calloc(folder->numOutStreams, sizeof(*folder->unPackSize));
+ if (folder->unPackSize == NULL)
+ goto failed;
+ for (j = 0; j < folder->numOutStreams; j++) {
+ if (parse_7zip_uint64(a, &(folder->unPackSize[j])) < 0)
+ goto failed;
+ }
+ }
+
+ /*
+ * Read CRCs.
+ */
+ if ((p = header_bytes(a, 1)) == NULL)
+ goto failed;
+ if (*p == kEnd)
+ return (0);
+ if (*p != kCRC)
+ goto failed;
+ if (read_Digests(a, &digest, ci->numFolders) < 0)
+ goto failed;
+ for (i = 0; i < ci->numFolders; i++) {
+ ci->folders[i].digest_defined = digest.defineds[i];
+ ci->folders[i].digest = digest.digests[i];
+ }
+
+ /*
+ * Must be kEnd.
+ */
+ if ((p = header_bytes(a, 1)) == NULL)
+ goto failed;
+ if (*p != kEnd)
+ goto failed;
+ free_Digest(&digest);
+ return (0);
+failed:
+ free_Digest(&digest);
+ return (-1);
+}
+
+static uint64_t
+folder_uncompressed_size(struct _7z_folder *f)
+{
+ int n = f->numOutStreams;
+ unsigned pairs = f->numBindPairs;
+
+ while (--n >= 0) {
+ unsigned i;
+ for (i = 0; i < pairs; i++) {
+ if (f->bindPairs[i].outIndex == n)
+ break;
+ }
+ if (i >= pairs)
+ return (f->unPackSize[n]);
+ }
+ return (0);
+}
+
+static void
+free_SubStreamsInfo(struct _7z_substream_info *ss)
+{
+ free(ss->unpackSizes);
+ free(ss->digestsDefined);
+ free(ss->digests);
+}
+
+static int
+read_SubStreamsInfo(struct archive_read *a, struct _7z_substream_info *ss,
+ struct _7z_folder *f, size_t numFolders)
+{
+ const unsigned char *p;
+ uint64_t *usizes;
+ size_t unpack_streams;
+ int type;
+ unsigned i;
+ uint32_t numDigests;
+
+ memset(ss, 0, sizeof(*ss));
+
+ for (i = 0; i < numFolders; i++)
+ f[i].numUnpackStreams = 1;
+
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ type = *p;
+
+ if (type == kNumUnPackStream) {
+ unpack_streams = 0;
+ for (i = 0; i < numFolders; i++) {
+ if (parse_7zip_uint64(a, &(f[i].numUnpackStreams)) < 0)
+ return (-1);
+ if (1000000 < f[i].numUnpackStreams)
+ return (-1);
+ unpack_streams += f[i].numUnpackStreams;
+ }
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ type = *p;
+ } else
+ unpack_streams = numFolders;
+
+ ss->unpack_streams = unpack_streams;
+ if (unpack_streams) {
+ ss->unpackSizes = calloc(unpack_streams,
+ sizeof(*ss->unpackSizes));
+ ss->digestsDefined = calloc(unpack_streams,
+ sizeof(*ss->digestsDefined));
+ ss->digests = calloc(unpack_streams,
+ sizeof(*ss->digests));
+ if (ss->unpackSizes == NULL || ss->digestsDefined == NULL ||
+ ss->digests == NULL)
+ return (-1);
+ }
+
+ usizes = ss->unpackSizes;
+ for (i = 0; i < numFolders; i++) {
+ unsigned pack;
+ uint64_t sum;
+
+ if (f[i].numUnpackStreams == 0)
+ continue;
+
+ sum = 0;
+ if (type == kSize) {
+ for (pack = 1; pack < f[i].numUnpackStreams; pack++) {
+ if (parse_7zip_uint64(a, usizes) < 0)
+ return (-1);
+ sum += *usizes++;
+ }
+ }
+ *usizes++ = folder_uncompressed_size(&f[i]) - sum;
+ }
+
+ if (type == kSize) {
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ type = *p;
+ }
+
+ for (i = 0; i < unpack_streams; i++) {
+ ss->digestsDefined[i] = 0;
+ ss->digests[i] = 0;
+ }
+
+ numDigests = 0;
+ for (i = 0; i < numFolders; i++) {
+ if (f[i].numUnpackStreams != 1 || !f[i].digest_defined)
+ numDigests += f[i].numUnpackStreams;
+ }
+
+ if (type == kCRC) {
+ struct _7z_digests tmpDigests;
+ unsigned char *digestsDefined = ss->digestsDefined;
+ uint32_t * digests = ss->digests;
+ int di = 0;
+
+ memset(&tmpDigests, 0, sizeof(tmpDigests));
+ if (read_Digests(a, &(tmpDigests), numDigests) < 0) {
+ free_Digest(&tmpDigests);
+ return (-1);
+ }
+ for (i = 0; i < numFolders; i++) {
+ if (f[i].numUnpackStreams == 1 && f[i].digest_defined) {
+ *digestsDefined++ = 1;
+ *digests++ = f[i].digest;
+ } else {
+ unsigned j;
+
+ for (j = 0; j < f[i].numUnpackStreams;
+ j++, di++) {
+ *digestsDefined++ =
+ tmpDigests.defineds[di];
+ *digests++ =
+ tmpDigests.digests[di];
+ }
+ }
+ }
+ free_Digest(&tmpDigests);
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ type = *p;
+ }
+
+ /*
+ * Must be kEnd.
+ */
+ if (type != kEnd)
+ return (-1);
+ return (0);
+}
+
+static void
+free_StreamsInfo(struct _7z_stream_info *si)
+{
+ free_PackInfo(&(si->pi));
+ free_CodersInfo(&(si->ci));
+ free_SubStreamsInfo(&(si->ss));
+}
+
+static int
+read_StreamsInfo(struct archive_read *a, struct _7z_stream_info *si)
+{
+ struct _7zip *zip = (struct _7zip *)a->format->data;
+ const unsigned char *p;
+ unsigned i;
+
+ memset(si, 0, sizeof(*si));
+
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ if (*p == kPackInfo) {
+ uint64_t packPos;
+
+ if (read_PackInfo(a, &(si->pi)) < 0)
+ return (-1);
+
+ if (si->pi.positions == NULL || si->pi.sizes == NULL)
+ return (-1);
+ /*
+ * Calculate packed stream positions.
+ */
+ packPos = si->pi.pos;
+ for (i = 0; i < si->pi.numPackStreams; i++) {
+ si->pi.positions[i] = packPos;
+ packPos += si->pi.sizes[i];
+ if (packPos > zip->header_offset)
+ return (-1);
+ }
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ }
+ if (*p == kUnPackInfo) {
+ uint32_t packIndex;
+ struct _7z_folder *f;
+
+ if (read_CodersInfo(a, &(si->ci)) < 0)
+ return (-1);
+
+ /*
+ * Calculate packed stream indexes.
+ */
+ packIndex = 0;
+ f = si->ci.folders;
+ for (i = 0; i < si->ci.numFolders; i++) {
+ f[i].packIndex = packIndex;
+ packIndex += f[i].numPackedStreams;
+ if (packIndex > si->pi.numPackStreams)
+ return (-1);
+ }
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ }
+
+ if (*p == kSubStreamsInfo) {
+ if (read_SubStreamsInfo(a, &(si->ss),
+ si->ci.folders, si->ci.numFolders) < 0)
+ return (-1);
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ }
+
+ /*
+ * Must be kEnd.
+ */
+ if (*p != kEnd)
+ return (-1);
+ return (0);
+}
+
+static void
+free_Header(struct _7z_header_info *h)
+{
+ free(h->emptyStreamBools);
+ free(h->emptyFileBools);
+ free(h->antiBools);
+ free(h->attrBools);
+}
+
+static int
+read_Header(struct archive_read *a, struct _7z_header_info *h,
+ int check_header_id)
+{
+ struct _7zip *zip = (struct _7zip *)a->format->data;
+ const unsigned char *p;
+ struct _7z_folder *folders;
+ struct _7z_stream_info *si = &(zip->si);
+ struct _7zip_entry *entries;
+ uint32_t folderIndex, indexInFolder;
+ unsigned i;
+ int eindex, empty_streams, sindex;
+
+ if (check_header_id) {
+ /*
+ * Read Header.
+ */
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ if (*p != kHeader)
+ return (-1);
+ }
+
+ /*
+ * Read ArchiveProperties.
+ */
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ if (*p == kArchiveProperties) {
+ for (;;) {
+ uint64_t size;
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ if (*p == 0)
+ break;
+ if (parse_7zip_uint64(a, &size) < 0)
+ return (-1);
+ }
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ }
+
+ /*
+ * Read MainStreamsInfo.
+ */
+ if (*p == kMainStreamsInfo) {
+ if (read_StreamsInfo(a, &(zip->si)) < 0)
+ return (-1);
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ }
+ if (*p == kEnd)
+ return (0);
+
+ /*
+ * Read FilesInfo.
+ */
+ if (*p != kFilesInfo)
+ return (-1);
+
+ if (parse_7zip_uint64(a, &(zip->numFiles)) < 0)
+ return (-1);
+ if (1000000 < zip->numFiles)
+ return (-1);
+
+ zip->entries = calloc(zip->numFiles, sizeof(*zip->entries));
+ if (zip->entries == NULL)
+ return (-1);
+ entries = zip->entries;
+
+ empty_streams = 0;
+ for (;;) {
+ int type;
+ uint64_t size;
+ size_t ll;
+
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ type = *p;
+ if (type == kEnd)
+ break;
+
+ if (parse_7zip_uint64(a, &size) < 0)
+ return (-1);
+ if (zip->header_bytes_remaining < size)
+ return (-1);
+ ll = (size_t)size;
+
+ switch (type) {
+ case kEmptyStream:
+ h->emptyStreamBools = calloc(zip->numFiles,
+ sizeof(*h->emptyStreamBools));
+ if (h->emptyStreamBools == NULL)
+ return (-1);
+ if (read_Bools(
+ a, h->emptyStreamBools, zip->numFiles) < 0)
+ return (-1);
+ empty_streams = 0;
+ for (i = 0; i < zip->numFiles; i++) {
+ if (h->emptyStreamBools[i])
+ empty_streams++;
+ }
+ break;
+ case kEmptyFile:
+ h->emptyFileBools = calloc(empty_streams,
+ sizeof(*h->emptyFileBools));
+ if (h->emptyFileBools == NULL)
+ return (-1);
+ if (read_Bools(a, h->emptyFileBools, empty_streams) < 0)
+ return (-1);
+ break;
+ case kAnti:
+ h->antiBools = calloc(empty_streams,
+ sizeof(*h->antiBools));
+ if (h->antiBools == NULL)
+ return (-1);
+ if (read_Bools(a, h->antiBools, empty_streams) < 0)
+ return (-1);
+ break;
+ case kCTime:
+ case kATime:
+ case kMTime:
+ if (read_Times(a, h, type) < 0)
+ return (-1);
+ break;
+ case kName:
+ {
+ unsigned char *np;
+ size_t nl, nb;
+
+ /* Skip one byte. */
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ ll--;
+
+ if ((ll & 1) || ll < zip->numFiles * 4)
+ return (-1);
+
+ zip->entry_names = malloc(ll);
+ if (zip->entry_names == NULL)
+ return (-1);
+ np = zip->entry_names;
+ nb = ll;
+ /*
+ * Copy whole file names.
+ * NOTE: This loop prevents from expanding
+ * the uncompressed buffer in order not to
+ * use extra memory resource.
+ */
+ while (nb) {
+ size_t b;
+ if (nb > UBUFF_SIZE)
+ b = UBUFF_SIZE;
+ else
+ b = nb;
+ if ((p = header_bytes(a, b)) == NULL)
+ return (-1);
+ memcpy(np, p, b);
+ np += b;
+ nb -= b;
+ }
+ np = zip->entry_names;
+ nl = ll;
+
+ for (i = 0; i < zip->numFiles; i++) {
+ entries[i].utf16name = np;
+#if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG)
+ entries[i].wname = (wchar_t *)np;
+#endif
+
+ /* Find a terminator. */
+ while (nl >= 2 && (np[0] || np[1])) {
+ np += 2;
+ nl -= 2;
+ }
+ if (nl < 2)
+ return (-1);/* Terminator not found */
+ entries[i].name_len = np - entries[i].utf16name;
+ np += 2;
+ nl -= 2;
+ }
+ break;
+ }
+ case kAttributes:
+ {
+ int allAreDefined;
+
+ if ((p = header_bytes(a, 2)) == NULL)
+ return (-1);
+ allAreDefined = *p;
+ h->attrBools = calloc(zip->numFiles,
+ sizeof(*h->attrBools));
+ if (h->attrBools == NULL)
+ return (-1);
+ if (allAreDefined)
+ memset(h->attrBools, 1, zip->numFiles);
+ else {
+ if (read_Bools(a, h->attrBools,
+ zip->numFiles) < 0)
+ return (-1);
+ }
+ for (i = 0; i < zip->numFiles; i++) {
+ if (h->attrBools[i]) {
+ if ((p = header_bytes(a, 4)) == NULL)
+ return (-1);
+ entries[i].attr = archive_le32dec(p);
+ }
+ }
+ break;
+ }
+ default:
+ if (header_bytes(a, ll) == NULL)
+ return (-1);
+ break;
+ }
+ }
+
+ /*
+ * Set up entry's attributes.
+ */
+ folders = si->ci.folders;
+ eindex = sindex = 0;
+ folderIndex = indexInFolder = 0;
+ for (i = 0; i < zip->numFiles; i++) {
+ if (h->emptyStreamBools == NULL || h->emptyStreamBools[i] == 0)
+ entries[i].flg |= HAS_STREAM;
+ /* The high 16 bits of attributes is a posix file mode. */
+ entries[i].mode = entries[i].attr >> 16;
+ if (entries[i].flg & HAS_STREAM) {
+ if ((size_t)sindex >= si->ss.unpack_streams)
+ return (-1);
+ if (entries[i].mode == 0)
+ entries[i].mode = AE_IFREG | 0777;
+ if (si->ss.digestsDefined[sindex])
+ entries[i].flg |= CRC32_IS_SET;
+ entries[i].ssIndex = sindex;
+ sindex++;
+ } else {
+ int dir;
+ if (h->emptyFileBools == NULL)
+ dir = 1;
+ else {
+ if (h->emptyFileBools[eindex])
+ dir = 0;
+ else
+ dir = 1;
+ eindex++;
+ }
+ if (entries[i].mode == 0) {
+ if (dir)
+ entries[i].mode = AE_IFDIR | 0777;
+ else
+ entries[i].mode = AE_IFREG | 0777;
+ } else if (dir &&
+ (entries[i].mode & AE_IFMT) != AE_IFDIR) {
+ entries[i].mode &= ~AE_IFMT;
+ entries[i].mode |= AE_IFDIR;
+ }
+ if ((entries[i].mode & AE_IFMT) == AE_IFDIR &&
+ entries[i].name_len >= 2 &&
+ (entries[i].utf16name[entries[i].name_len-2] != '/' ||
+ entries[i].utf16name[entries[i].name_len-1] != 0)) {
+ entries[i].utf16name[entries[i].name_len] = '/';
+ entries[i].utf16name[entries[i].name_len+1] = 0;
+ entries[i].name_len += 2;
+ }
+ entries[i].ssIndex = -1;
+ }
+ if (entries[i].attr & 0x01)
+ entries[i].mode &= ~0222;/* Read only. */
+
+ if ((entries[i].flg & HAS_STREAM) == 0 && indexInFolder == 0) {
+ /*
+ * The entry is an empty file or a directory file,
+ * those both have no contents.
+ */
+ entries[i].folderIndex = -1;
+ continue;
+ }
+ if (indexInFolder == 0) {
+ for (;;) {
+ if (folderIndex >= si->ci.numFolders)
+ return (-1);
+ if (folders[folderIndex].numUnpackStreams)
+ break;
+ folderIndex++;
+ }
+ }
+ entries[i].folderIndex = folderIndex;
+ if ((entries[i].flg & HAS_STREAM) == 0)
+ continue;
+ indexInFolder++;
+ if (indexInFolder >= folders[folderIndex].numUnpackStreams) {
+ folderIndex++;
+ indexInFolder = 0;
+ }
+ }
+
+ return (0);
+}
+
+#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
+static void
+fileTimeToUtc(uint64_t fileTime, time_t *time, long *ns)
+{
+
+ if (fileTime >= EPOC_TIME) {
+ fileTime -= EPOC_TIME;
+ /* milli seconds base */
+ *time = (time_t)(fileTime / 10000000);
+ /* nano seconds base */
+ *ns = (long)(fileTime % 10000000) * 100;
+ } else {
+ *time = 0;
+ *ns = 0;
+ }
+}
+
+static int
+read_Times(struct archive_read *a, struct _7z_header_info *h, int type)
+{
+ struct _7zip *zip = (struct _7zip *)a->format->data;
+ const unsigned char *p;
+ struct _7zip_entry *entries = zip->entries;
+ unsigned char *timeBools;
+ int allAreDefined;
+ unsigned i;
+
+ timeBools = calloc(zip->numFiles, sizeof(*timeBools));
+ if (timeBools == NULL)
+ return (-1);
+
+ /* Read allAreDefined. */
+ if ((p = header_bytes(a, 1)) == NULL)
+ goto failed;
+ allAreDefined = *p;
+ if (allAreDefined)
+ memset(timeBools, 1, zip->numFiles);
+ else {
+ if (read_Bools(a, timeBools, zip->numFiles) < 0)
+ goto failed;
+ }
+
+ /* Read external. */
+ if ((p = header_bytes(a, 1)) == NULL)
+ goto failed;
+ if (*p) {
+ if (parse_7zip_uint64(a, &(h->dataIndex)) < 0)
+ goto failed;
+ if (1000000 < h->dataIndex)
+ return (-1);
+ }
+
+ for (i = 0; i < zip->numFiles; i++) {
+ if (!timeBools[i])
+ continue;
+ if ((p = header_bytes(a, 8)) == NULL)
+ goto failed;
+ switch (type) {
+ case kCTime:
+ fileTimeToUtc(archive_le64dec(p),
+ &(entries[i].ctime),
+ &(entries[i].ctime_ns));
+ entries[i].flg |= CTIME_IS_SET;
+ break;
+ case kATime:
+ fileTimeToUtc(archive_le64dec(p),
+ &(entries[i].atime),
+ &(entries[i].atime_ns));
+ entries[i].flg |= ATIME_IS_SET;
+ break;
+ case kMTime:
+ fileTimeToUtc(archive_le64dec(p),
+ &(entries[i].mtime),
+ &(entries[i].mtime_ns));
+ entries[i].flg |= MTIME_IS_SET;
+ break;
+ }
+ }
+
+ free(timeBools);
+ return (0);
+failed:
+ free(timeBools);
+ return (-1);
+}
+
+static int
+decode_encoded_header_info(struct archive_read *a, struct _7z_stream_info *si)
+{
+ struct _7zip *zip = (struct _7zip *)a->format->data;
+
+ errno = 0;
+ if (read_StreamsInfo(a, si) < 0) {
+ if (errno == ENOMEM)
+ archive_set_error(&a->archive, -1,
+ "Couldn't allocate memory");
+ else
+ archive_set_error(&a->archive, -1,
+ "Malformed 7-Zip archive");
+ return (ARCHIVE_FATAL);
+ }
+
+ if (si->pi.numPackStreams == 0 || si->ci.numFolders == 0) {
+ archive_set_error(&a->archive, -1, "Malformed 7-Zip archive");
+ return (ARCHIVE_FATAL);
+ }
+
+ if (zip->header_offset < si->pi.pos + si->pi.sizes[0] ||
+ (int64_t)(si->pi.pos + si->pi.sizes[0]) < 0 ||
+ si->pi.sizes[0] == 0 || (int64_t)si->pi.pos < 0) {
+ archive_set_error(&a->archive, -1, "Malformed Header offset");
+ return (ARCHIVE_FATAL);
+ }
+
+ return (ARCHIVE_OK);
+}
+
+static const unsigned char *
+header_bytes(struct archive_read *a, size_t rbytes)
+{
+ struct _7zip *zip = (struct _7zip *)a->format->data;
+ const unsigned char *p;
+
+ if (zip->header_bytes_remaining < rbytes)
+ return (NULL);
+ if (zip->pack_stream_bytes_unconsumed)
+ read_consume(a);
+
+ if (zip->header_is_encoded == 0) {
+ p = __archive_read_ahead(a, rbytes, NULL);
+ if (p == NULL)
+ return (NULL);
+ zip->header_bytes_remaining -= rbytes;
+ zip->pack_stream_bytes_unconsumed = rbytes;
+ } else {
+ const void *buff;
+ ssize_t bytes;
+
+ bytes = read_stream(a, &buff, rbytes, rbytes);
+ if (bytes <= 0)
+ return (NULL);
+ zip->header_bytes_remaining -= bytes;
+ p = buff;
+ }
+
+ /* Update checksum */
+ zip->header_crc32 = crc32(zip->header_crc32, p, rbytes);
+ return (p);
+}
+
+static int
+slurp_central_directory(struct archive_read *a, struct _7zip *zip,
+ struct _7z_header_info *header)
+{
+ const unsigned char *p;
+ uint64_t next_header_offset;
+ uint64_t next_header_size;
+ uint32_t next_header_crc;
+ ssize_t bytes_avail;
+ int check_header_crc, r;
+
+ if ((p = __archive_read_ahead(a, 32, &bytes_avail)) == NULL)
+ return (ARCHIVE_FATAL);
+
+ if ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0) {
+ /* This is an executable ? Must be self-extracting... */
+ r = skip_sfx(a, bytes_avail);
+ if (r < ARCHIVE_WARN)
+ return (r);
+ if ((p = __archive_read_ahead(a, 32, &bytes_avail)) == NULL)
+ return (ARCHIVE_FATAL);
+ }
+ zip->seek_base += 32;
+
+ if (memcmp(p, _7ZIP_SIGNATURE, 6) != 0) {
+ archive_set_error(&a->archive, -1, "Not 7-Zip archive file");
+ return (ARCHIVE_FATAL);
+ }
+
+ /* CRC check. */
+ if (crc32(0, (unsigned char *)p + 12, 20) != archive_le32dec(p + 8)) {
+ archive_set_error(&a->archive, -1, "Header CRC error");
+ return (ARCHIVE_FATAL);
+ }
+
+ next_header_offset = archive_le64dec(p + 12);
+ next_header_size = archive_le64dec(p + 20);
+ next_header_crc = archive_le32dec(p + 28);
+
+ if (next_header_size == 0)
+ /* There is no entry in an archive file. */
+ return (ARCHIVE_EOF);
+
+ if (((int64_t)next_header_offset) < 0) {
+ archive_set_error(&a->archive, -1, "Malformed 7-Zip archive");
+ return (ARCHIVE_FATAL);
+ }
+ __archive_read_consume(a, 32);
+ if (next_header_offset != 0) {
+ if (bytes_avail >= next_header_offset)
+ __archive_read_consume(a, next_header_offset);
+ else if (__archive_read_seek(a,
+ next_header_offset + zip->seek_base, SEEK_SET) < 0)
+ return (ARCHIVE_FATAL);
+ }
+ zip->stream_offset = next_header_offset;
+ zip->header_offset = next_header_offset;
+ zip->header_bytes_remaining = next_header_size;
+ zip->header_crc32 = 0;
+ zip->header_is_encoded = 0;
+ zip->header_is_being_read = 1;
+ check_header_crc = 1;
+
+ if ((p = header_bytes(a, 1)) == NULL) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated 7-Zip file body");
+ return (ARCHIVE_FATAL);
+ }
+ /* Parse ArchiveProperties. */
+ switch (p[0]) {
+ case kEncodedHeader:
+ /*
+ * The archive has an encoded header and we have to decode it
+ * in order to parse the header correctly.
+ */
+ r = decode_encoded_header_info(a, &(zip->si));
+
+ /* Check the EncodedHeader CRC.*/
+ if (r == 0 && zip->header_crc32 != next_header_crc) {
+ archive_set_error(&a->archive, -1,
+ "Damaged 7-Zip archive");
+ r = -1;
+ }
+ if (r == 0) {
+ if (zip->si.ci.folders[0].digest_defined)
+ next_header_crc = zip->si.ci.folders[0].digest;
+ else
+ check_header_crc = 0;
+ if (zip->pack_stream_bytes_unconsumed)
+ read_consume(a);
+ r = setup_decode_folder(a, zip->si.ci.folders, 1);
+ if (r == 0) {
+ zip->header_bytes_remaining =
+ zip->folder_outbytes_remaining;
+ r = seek_pack(a);
+ }
+ }
+ /* Clean up StreamsInfo. */
+ free_StreamsInfo(&(zip->si));
+ memset(&(zip->si), 0, sizeof(zip->si));
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ zip->header_is_encoded = 1;
+ zip->header_crc32 = 0;
+ /* FALL THROUGH */
+ case kHeader:
+ /*
+ * Parse the header.
+ */
+ errno = 0;
+ r = read_Header(a, header, zip->header_is_encoded);
+ if (r < 0) {
+ if (errno == ENOMEM)
+ archive_set_error(&a->archive, -1,
+ "Couldn't allocate memory");
+ else
+ archive_set_error(&a->archive, -1,
+ "Damaged 7-Zip archive");
+ return (ARCHIVE_FATAL);
+ }
+
+ /*
+ * Must be kEnd.
+ */
+ if ((p = header_bytes(a, 1)) == NULL ||*p != kEnd) {
+ archive_set_error(&a->archive, -1,
+ "Malformed 7-Zip archive");
+ return (ARCHIVE_FATAL);
+ }
+
+ /* Check the Header CRC.*/
+ if (check_header_crc && zip->header_crc32 != next_header_crc) {
+ archive_set_error(&a->archive, -1,
+ "Malformed 7-Zip archive");
+ return (ARCHIVE_FATAL);
+ }
+ break;
+ default:
+ archive_set_error(&a->archive, -1,
+ "Unexpected Property ID = %X", p[0]);
+ return (ARCHIVE_FATAL);
+ }
+
+ /* Clean up variables be used for decoding the archive header */
+ zip->pack_stream_remaining = 0;
+ zip->pack_stream_index = 0;
+ zip->folder_outbytes_remaining = 0;
+ zip->uncompressed_buffer_bytes_remaining = 0;
+ zip->pack_stream_bytes_unconsumed = 0;
+ zip->header_is_being_read = 0;
+
+ return (ARCHIVE_OK);
+}
+
+static ssize_t
+get_uncompressed_data(struct archive_read *a, const void **buff, size_t size,
+ size_t minimum)
+{
+ struct _7zip *zip = (struct _7zip *)a->format->data;
+ ssize_t bytes_avail;
+
+ if (zip->codec == _7Z_COPY && zip->codec2 == -1) {
+ /* Copy mode. */
+
+ /*
+ * Note: '1' here is a performance optimization.
+ * Recall that the decompression layer returns a count of
+ * available bytes; asking for more than that forces the
+ * decompressor to combine reads by copying data.
+ */
+ *buff = __archive_read_ahead(a, 1, &bytes_avail);
+ if (bytes_avail <= 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated 7-Zip file data");
+ return (ARCHIVE_FATAL);
+ }
+ if ((size_t)bytes_avail >
+ zip->uncompressed_buffer_bytes_remaining)
+ bytes_avail = (ssize_t)
+ zip->uncompressed_buffer_bytes_remaining;
+ if ((size_t)bytes_avail > size)
+ bytes_avail = (ssize_t)size;
+
+ zip->pack_stream_bytes_unconsumed = bytes_avail;
+ } else if (zip->uncompressed_buffer_pointer == NULL) {
+ /* Decompression has failed. */
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC, "Damaged 7-Zip archive");
+ return (ARCHIVE_FATAL);
+ } else {
+ /* Packed mode. */
+ if (minimum > zip->uncompressed_buffer_bytes_remaining) {
+ /*
+ * If remaining uncompressed data size is less than
+ * the minimum size, fill the buffer up to the
+ * minimum size.
+ */
+ if (extract_pack_stream(a, minimum) < 0)
+ return (ARCHIVE_FATAL);
+ }
+ if (size > zip->uncompressed_buffer_bytes_remaining)
+ bytes_avail = (ssize_t)
+ zip->uncompressed_buffer_bytes_remaining;
+ else
+ bytes_avail = (ssize_t)size;
+ *buff = zip->uncompressed_buffer_pointer;
+ zip->uncompressed_buffer_pointer += bytes_avail;
+ }
+ zip->uncompressed_buffer_bytes_remaining -= bytes_avail;
+ return (bytes_avail);
+}
+
+static ssize_t
+extract_pack_stream(struct archive_read *a, size_t minimum)
+{
+ struct _7zip *zip = (struct _7zip *)a->format->data;
+ ssize_t bytes_avail;
+ int r;
+
+ if (zip->codec == _7Z_COPY && zip->codec2 == -1) {
+ if (minimum == 0)
+ minimum = 1;
+ if (__archive_read_ahead(a, minimum, &bytes_avail) == NULL
+ || bytes_avail <= 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated 7-Zip file body");
+ return (ARCHIVE_FATAL);
+ }
+ if (bytes_avail > zip->pack_stream_inbytes_remaining)
+ bytes_avail = zip->pack_stream_inbytes_remaining;
+ zip->pack_stream_inbytes_remaining -= bytes_avail;
+ if (bytes_avail > zip->folder_outbytes_remaining)
+ bytes_avail = zip->folder_outbytes_remaining;
+ zip->folder_outbytes_remaining -= bytes_avail;
+ zip->uncompressed_buffer_bytes_remaining = bytes_avail;
+ return (ARCHIVE_OK);
+ }
+
+ /* If the buffer hasn't been allocated, allocate it now. */
+ if (zip->uncompressed_buffer == NULL) {
+ zip->uncompressed_buffer_size = UBUFF_SIZE;
+ if (zip->uncompressed_buffer_size < minimum) {
+ zip->uncompressed_buffer_size = minimum + 1023;
+ zip->uncompressed_buffer_size &= ~0x3ff;
+ }
+ zip->uncompressed_buffer =
+ malloc(zip->uncompressed_buffer_size);
+ if (zip->uncompressed_buffer == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory for 7-Zip decompression");
+ return (ARCHIVE_FATAL);
+ }
+ zip->uncompressed_buffer_bytes_remaining = 0;
+ } else if (zip->uncompressed_buffer_size < minimum ||
+ zip->uncompressed_buffer_bytes_remaining < minimum) {
+ /*
+ * Make sure the uncompressed buffer can have bytes
+ * at least `minimum' bytes.
+ * NOTE: This case happen when reading the header.
+ */
+ size_t used;
+ if (zip->uncompressed_buffer_pointer != 0)
+ used = zip->uncompressed_buffer_pointer -
+ zip->uncompressed_buffer;
+ else
+ used = 0;
+ if (zip->uncompressed_buffer_size < minimum) {
+ /*
+ * Expand the uncompressed buffer up to
+ * the minimum size.
+ */
+ zip->uncompressed_buffer_size = minimum + 1023;
+ zip->uncompressed_buffer_size &= ~0x3ff;
+ zip->uncompressed_buffer =
+ realloc(zip->uncompressed_buffer,
+ zip->uncompressed_buffer_size);
+ if (zip->uncompressed_buffer == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory for 7-Zip decompression");
+ return (ARCHIVE_FATAL);
+ }
+ }
+ /*
+ * Move unconsumed bytes to the head.
+ */
+ if (used) {
+ memmove(zip->uncompressed_buffer,
+ zip->uncompressed_buffer + used,
+ zip->uncompressed_buffer_bytes_remaining);
+ }
+ } else
+ zip->uncompressed_buffer_bytes_remaining = 0;
+ zip->uncompressed_buffer_pointer = NULL;
+ for (;;) {
+ size_t bytes_in, bytes_out;
+ const void *buff_in;
+ unsigned char *buff_out;
+ int eof;
+
+ /*
+ * Note: '1' here is a performance optimization.
+ * Recall that the decompression layer returns a count of
+ * available bytes; asking for more than that forces the
+ * decompressor to combine reads by copying data.
+ */
+ buff_in = __archive_read_ahead(a, 1, &bytes_avail);
+ if (bytes_avail <= 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated 7-Zip file body");
+ return (ARCHIVE_FATAL);
+ }
+
+ buff_out = zip->uncompressed_buffer
+ + zip->uncompressed_buffer_bytes_remaining;
+ bytes_out = zip->uncompressed_buffer_size
+ - zip->uncompressed_buffer_bytes_remaining;
+ bytes_in = bytes_avail;
+ if (bytes_in > zip->pack_stream_inbytes_remaining)
+ bytes_in = zip->pack_stream_inbytes_remaining;
+ /* Drive decompression. */
+ r = decompress(a, zip, buff_out, &bytes_out,
+ buff_in, &bytes_in);
+ switch (r) {
+ case ARCHIVE_OK:
+ eof = 0;
+ break;
+ case ARCHIVE_EOF:
+ eof = 1;
+ break;
+ default:
+ return (ARCHIVE_FATAL);
+ }
+ zip->pack_stream_inbytes_remaining -= bytes_in;
+ if (bytes_out > zip->folder_outbytes_remaining)
+ bytes_out = zip->folder_outbytes_remaining;
+ zip->folder_outbytes_remaining -= bytes_out;
+ zip->uncompressed_buffer_bytes_remaining += bytes_out;
+ zip->pack_stream_bytes_unconsumed = bytes_in;
+
+ /*
+ * Continue decompression until uncompressed_buffer is full.
+ */
+ if (zip->uncompressed_buffer_bytes_remaining ==
+ zip->uncompressed_buffer_size)
+ break;
+ if (zip->codec2 == _7Z_X86 && zip->odd_bcj_size &&
+ zip->uncompressed_buffer_bytes_remaining + 5 >
+ zip->uncompressed_buffer_size)
+ break;
+ if (zip->pack_stream_inbytes_remaining == 0 &&
+ zip->folder_outbytes_remaining == 0)
+ break;
+ if (eof || (bytes_in == 0 && bytes_out == 0)) {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC, "Damaged 7-Zip archive");
+ return (ARCHIVE_FATAL);
+ }
+ read_consume(a);
+ }
+ if (zip->uncompressed_buffer_bytes_remaining < minimum) {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC, "Damaged 7-Zip archive");
+ return (ARCHIVE_FATAL);
+ }
+ zip->uncompressed_buffer_pointer = zip->uncompressed_buffer;
+ return (ARCHIVE_OK);
+}
+
+static int
+seek_pack(struct archive_read *a)
+{
+ struct _7zip *zip = (struct _7zip *)a->format->data;
+ uint64_t pack_offset;
+
+ if (zip->pack_stream_remaining <= 0) {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC, "Damaged 7-Zip archive");
+ return (ARCHIVE_FATAL);
+ }
+ zip->pack_stream_inbytes_remaining =
+ zip->si.pi.sizes[zip->pack_stream_index];
+ pack_offset = zip->si.pi.positions[zip->pack_stream_index];
+ if (zip->stream_offset != pack_offset) {
+ if (0 > __archive_read_seek(a, pack_offset + zip->seek_base,
+ SEEK_SET))
+ return (ARCHIVE_FATAL);
+ zip->stream_offset = pack_offset;
+ }
+ zip->pack_stream_index++;
+ zip->pack_stream_remaining--;
+ return (ARCHIVE_OK);
+}
+
+static ssize_t
+read_stream(struct archive_read *a, const void **buff, size_t size,
+ size_t minimum)
+{
+ struct _7zip *zip = (struct _7zip *)a->format->data;
+ uint64_t skip_bytes = 0;
+ int r;
+
+ if (zip->uncompressed_buffer_bytes_remaining == 0) {
+ if (zip->pack_stream_inbytes_remaining > 0) {
+ r = extract_pack_stream(a, 0);
+ if (r < 0)
+ return (r);
+ return (get_uncompressed_data(a, buff, size, minimum));
+ } else if (zip->folder_outbytes_remaining > 0) {
+ /* Extract a remaining pack stream. */
+ r = extract_pack_stream(a, 0);
+ if (r < 0)
+ return (r);
+ return (get_uncompressed_data(a, buff, size, minimum));
+ }
+ } else
+ return (get_uncompressed_data(a, buff, size, minimum));
+
+ /*
+ * Current pack stream has been consumed.
+ */
+ if (zip->pack_stream_remaining == 0) {
+ if (zip->header_is_being_read) {
+ /* Invalid sequence. This might happen when
+ * reading a malformed archive. */
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC, "Malformed 7-Zip archive");
+ return (ARCHIVE_FATAL);
+ }
+
+ /*
+ * All current folder's pack streams have been
+ * consumed. Switch to next folder.
+ */
+ if (zip->folder_index == 0 &&
+ (zip->si.ci.folders[zip->entry->folderIndex].skipped_bytes
+ || zip->folder_index != zip->entry->folderIndex)) {
+ zip->folder_index = zip->entry->folderIndex;
+ skip_bytes =
+ zip->si.ci.folders[zip->folder_index].skipped_bytes;
+ }
+
+ if (zip->folder_index >= zip->si.ci.numFolders) {
+ /*
+ * We have consumed all folders and its pack streams.
+ */
+ *buff = NULL;
+ return (0);
+ }
+ r = setup_decode_folder(a,
+ &(zip->si.ci.folders[zip->folder_index]), 0);
+ if (r != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ zip->folder_index++;
+ }
+
+ /*
+ * Switch to next pack stream.
+ */
+ r = seek_pack(a);
+ if (r < 0)
+ return (r);
+
+ /* Extract a new pack stream. */
+ r = extract_pack_stream(a, 0);
+ if (r < 0)
+ return (r);
+
+ /*
+ * Skip the bytes we alrady has skipped in skip_stream().
+ */
+ while (skip_bytes) {
+ ssize_t skipped;
+
+ if (zip->uncompressed_buffer_bytes_remaining == 0) {
+ if (zip->pack_stream_inbytes_remaining > 0) {
+ r = extract_pack_stream(a, 0);
+ if (r < 0)
+ return (r);
+ } else if (zip->folder_outbytes_remaining > 0) {
+ /* Extract a remaining pack stream. */
+ r = extract_pack_stream(a, 0);
+ if (r < 0)
+ return (r);
+ } else {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated 7-Zip file body");
+ return (ARCHIVE_FATAL);
+ }
+ }
+ skipped = get_uncompressed_data(a, buff, skip_bytes, 0);
+ if (skipped < 0)
+ return (skipped);
+ skip_bytes -= skipped;
+ if (zip->pack_stream_bytes_unconsumed)
+ read_consume(a);
+ }
+
+ return (get_uncompressed_data(a, buff, size, minimum));
+}
+
+static int
+setup_decode_folder(struct archive_read *a, struct _7z_folder *folder,
+ int header)
+{
+ struct _7zip *zip = (struct _7zip *)a->format->data;
+ const struct _7z_coder *coder1, *coder2;
+ const char *cname = (header)?"archive header":"file content";
+ unsigned i;
+ int r, found_bcj2 = 0;
+
+ /*
+ * Release the memory which the previous folder used for BCJ2.
+ */
+ for (i = 0; i < 3; i++) {
+ if (zip->sub_stream_buff[i] != NULL)
+ free(zip->sub_stream_buff[i]);
+ zip->sub_stream_buff[i] = NULL;
+ }
+
+ /*
+ * Initialize a stream reader.
+ */
+ zip->pack_stream_remaining = (unsigned)folder->numPackedStreams;
+ zip->pack_stream_index = (unsigned)folder->packIndex;
+ zip->folder_outbytes_remaining = folder_uncompressed_size(folder);
+ zip->uncompressed_buffer_bytes_remaining = 0;
+
+ /*
+ * Check coder types.
+ */
+ for (i = 0; i < folder->numCoders; i++) {
+ if (folder->coders[i].codec == _7Z_CRYPTO) {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "The %s is encrypted, "
+ "but currently not supported", cname);
+ return (ARCHIVE_FATAL);
+ }
+ if (folder->coders[i].codec == _7Z_X86_BCJ2)
+ found_bcj2++;
+ }
+ if ((folder->numCoders > 2 && !found_bcj2) || found_bcj2 > 1) {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "The %s is encoded with many filters, "
+ "but currently not supported", cname);
+ return (ARCHIVE_FATAL);
+ }
+ coder1 = &(folder->coders[0]);
+ if (folder->numCoders == 2)
+ coder2 = &(folder->coders[1]);
+ else
+ coder2 = NULL;
+
+ if (found_bcj2) {
+ /*
+ * Preparation to decode BCJ2.
+ * Decoding BCJ2 requires four sources. Those are at least,
+ * as far as I know, two types of the storage form.
+ */
+ const struct _7z_coder *fc = folder->coders;
+ static const struct _7z_coder coder_copy = {0, 1, 1, 0, NULL};
+ const struct _7z_coder *scoder[3] =
+ {&coder_copy, &coder_copy, &coder_copy};
+ const void *buff;
+ ssize_t bytes;
+ unsigned char *b[3] = {NULL, NULL, NULL};
+ uint64_t sunpack[3] ={-1, -1, -1};
+ size_t s[3] = {0, 0, 0};
+ int idx[3] = {0, 1, 2};
+
+ if (folder->numCoders == 4 && fc[3].codec == _7Z_X86_BCJ2 &&
+ folder->numInStreams == 7 && folder->numOutStreams == 4 &&
+ zip->pack_stream_remaining == 4) {
+ /* Source type 1 made by 7zr or 7z with -m options. */
+ if (folder->bindPairs[0].inIndex == 5) {
+ /* The form made by 7zr */
+ idx[0] = 1; idx[1] = 2; idx[2] = 0;
+ scoder[1] = &(fc[1]);
+ scoder[2] = &(fc[0]);
+ sunpack[1] = folder->unPackSize[1];
+ sunpack[2] = folder->unPackSize[0];
+ coder1 = &(fc[2]);
+ } else {
+ /*
+ * NOTE: Some patterns do not work.
+ * work:
+ * 7z a -m0=BCJ2 -m1=COPY -m2=COPY
+ * -m3=(any)
+ * 7z a -m0=BCJ2 -m1=COPY -m2=(any)
+ * -m3=COPY
+ * 7z a -m0=BCJ2 -m1=(any) -m2=COPY
+ * -m3=COPY
+ * not work:
+ * other patterns.
+ *
+ * We have to handle this like `pipe' or
+ * our libarchive7s filter frame work,
+ * decoding the BCJ2 main stream sequentially,
+ * m3 -> m2 -> m1 -> BCJ2.
+ *
+ */
+ if (fc[0].codec == _7Z_COPY &&
+ fc[1].codec == _7Z_COPY)
+ coder1 = &(folder->coders[2]);
+ else if (fc[0].codec == _7Z_COPY &&
+ fc[2].codec == _7Z_COPY)
+ coder1 = &(folder->coders[1]);
+ else if (fc[1].codec == _7Z_COPY &&
+ fc[2].codec == _7Z_COPY)
+ coder1 = &(folder->coders[0]);
+ else {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "Unsupported form of "
+ "BCJ2 streams");
+ return (ARCHIVE_FATAL);
+ }
+ }
+ coder2 = &(fc[3]);
+ zip->main_stream_bytes_remaining =
+ folder->unPackSize[2];
+ } else if (coder2 != NULL && coder2->codec == _7Z_X86_BCJ2 &&
+ zip->pack_stream_remaining == 4 &&
+ folder->numInStreams == 5 && folder->numOutStreams == 2) {
+ /* Source type 0 made by 7z */
+ zip->main_stream_bytes_remaining =
+ folder->unPackSize[0];
+ } else {
+ /* We got an unexpected form. */
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "Unsupported form of BCJ2 streams");
+ return (ARCHIVE_FATAL);
+ }
+
+ /* Skip the main stream at this time. */
+ if ((r = seek_pack(a)) < 0)
+ return (r);
+ zip->pack_stream_bytes_unconsumed =
+ zip->pack_stream_inbytes_remaining;
+ read_consume(a);
+
+ /* Read following three sub streams. */
+ for (i = 0; i < 3; i++) {
+ const struct _7z_coder *coder = scoder[i];
+
+ if ((r = seek_pack(a)) < 0)
+ return (r);
+
+ if (sunpack[i] == -1)
+ zip->folder_outbytes_remaining =
+ zip->pack_stream_inbytes_remaining;
+ else
+ zip->folder_outbytes_remaining = sunpack[i];
+
+ r = init_decompression(a, zip, coder, NULL);
+ if (r != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /* Allocate memory for the decorded data of a sub
+ * stream. */
+ b[i] = malloc(zip->folder_outbytes_remaining);
+ if (b[i] == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory for 7-Zip decompression");
+ return (ARCHIVE_FATAL);
+ }
+
+ /* Extract a sub stream. */
+ while (zip->pack_stream_inbytes_remaining > 0) {
+ r = extract_pack_stream(a, 0);
+ if (r < 0)
+ return (r);
+ bytes = get_uncompressed_data(a, &buff,
+ zip->uncompressed_buffer_bytes_remaining,
+ 0);
+ if (bytes < 0)
+ return ((int)bytes);
+ memcpy(b[i]+s[i], buff, bytes);
+ s[i] += bytes;
+ if (zip->pack_stream_bytes_unconsumed)
+ read_consume(a);
+ }
+ }
+
+ /* Set the sub streams to the right place. */
+ for (i = 0; i < 3; i++) {
+ zip->sub_stream_buff[i] = b[idx[i]];
+ zip->sub_stream_size[i] = s[idx[i]];
+ zip->sub_stream_bytes_remaining[i] = s[idx[i]];
+ }
+
+ /* Allocate memory used for decoded main stream bytes. */
+ if (zip->tmp_stream_buff == NULL) {
+ zip->tmp_stream_buff_size = 32 * 1024;
+ zip->tmp_stream_buff =
+ malloc(zip->tmp_stream_buff_size);
+ if (zip->tmp_stream_buff == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory for 7-Zip decompression");
+ return (ARCHIVE_FATAL);
+ }
+ }
+ zip->tmp_stream_bytes_avail = 0;
+ zip->tmp_stream_bytes_remaining = 0;
+ zip->odd_bcj_size = 0;
+ zip->bcj2_outPos = 0;
+
+ /*
+ * Reset a stream reader in order to read the main stream
+ * of BCJ2.
+ */
+ zip->pack_stream_remaining = 1;
+ zip->pack_stream_index = (unsigned)folder->packIndex;
+ zip->folder_outbytes_remaining =
+ folder_uncompressed_size(folder);
+ zip->uncompressed_buffer_bytes_remaining = 0;
+ }
+
+ /*
+ * Initialize the decompressor for the new folder's pack streams.
+ */
+ r = init_decompression(a, zip, coder1, coder2);
+ if (r != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ return (ARCHIVE_OK);
+}
+
+static int64_t
+skip_stream(struct archive_read *a, size_t skip_bytes)
+{
+ struct _7zip *zip = (struct _7zip *)a->format->data;
+ const void *p;
+ int64_t skipped_bytes;
+ size_t bytes = skip_bytes;
+
+ if (zip->folder_index == 0) {
+ /*
+ * Optimization for a list mode.
+ * Avoid unncecessary decoding operations.
+ */
+ zip->si.ci.folders[zip->entry->folderIndex].skipped_bytes
+ += skip_bytes;
+ return (skip_bytes);
+ }
+
+ while (bytes) {
+ skipped_bytes = read_stream(a, &p, bytes, 0);
+ if (skipped_bytes < 0)
+ return (skipped_bytes);
+ if (skipped_bytes == 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated 7-Zip file body");
+ return (ARCHIVE_FATAL);
+ }
+ bytes -= skipped_bytes;
+ if (zip->pack_stream_bytes_unconsumed)
+ read_consume(a);
+ }
+ return (skip_bytes);
+}
+
+/*
+ * Brought from LZMA SDK.
+ *
+ * Bra86.c -- Converter for x86 code (BCJ)
+ * 2008-10-04 : Igor Pavlov : Public domain
+ *
+ */
+
+#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)
+
+static void
+x86_Init(struct _7zip *zip)
+{
+ zip->bcj_state = 0;
+ zip->bcj_prevPosT = (size_t)0 - 1;
+ zip->bcj_prevMask = 0;
+ zip->bcj_ip = 5;
+}
+
+static size_t
+x86_Convert(struct _7zip *zip, uint8_t *data, size_t size)
+{
+ static const uint8_t kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};
+ static const uint8_t kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};
+ size_t bufferPos, prevPosT;
+ uint32_t ip, prevMask;
+
+ if (size < 5)
+ return 0;
+
+ bufferPos = 0;
+ prevPosT = zip->bcj_prevPosT;
+ prevMask = zip->bcj_prevMask;
+ ip = zip->bcj_ip;
+
+ for (;;) {
+ uint8_t *p = data + bufferPos;
+ uint8_t *limit = data + size - 4;
+
+ for (; p < limit; p++)
+ if ((*p & 0xFE) == 0xE8)
+ break;
+ bufferPos = (size_t)(p - data);
+ if (p >= limit)
+ break;
+ prevPosT = bufferPos - prevPosT;
+ if (prevPosT > 3)
+ prevMask = 0;
+ else {
+ prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7;
+ if (prevMask != 0) {
+ unsigned char b =
+ p[4 - kMaskToBitNumber[prevMask]];
+ if (!kMaskToAllowedStatus[prevMask] ||
+ Test86MSByte(b)) {
+ prevPosT = bufferPos;
+ prevMask = ((prevMask << 1) & 0x7) | 1;
+ bufferPos++;
+ continue;
+ }
+ }
+ }
+ prevPosT = bufferPos;
+
+ if (Test86MSByte(p[4])) {
+ uint32_t src = ((uint32_t)p[4] << 24) |
+ ((uint32_t)p[3] << 16) | ((uint32_t)p[2] << 8) |
+ ((uint32_t)p[1]);
+ uint32_t dest;
+ for (;;) {
+ uint8_t b;
+ int index;
+
+ dest = src - (ip + (uint32_t)bufferPos);
+ if (prevMask == 0)
+ break;
+ index = kMaskToBitNumber[prevMask] * 8;
+ b = (uint8_t)(dest >> (24 - index));
+ if (!Test86MSByte(b))
+ break;
+ src = dest ^ ((1 << (32 - index)) - 1);
+ }
+ p[4] = (uint8_t)(~(((dest >> 24) & 1) - 1));
+ p[3] = (uint8_t)(dest >> 16);
+ p[2] = (uint8_t)(dest >> 8);
+ p[1] = (uint8_t)dest;
+ bufferPos += 5;
+ } else {
+ prevMask = ((prevMask << 1) & 0x7) | 1;
+ bufferPos++;
+ }
+ }
+ zip->bcj_prevPosT = prevPosT;
+ zip->bcj_prevMask = prevMask;
+ zip->bcj_ip += bufferPos;
+ return (bufferPos);
+}
+
+/*
+ * Brought from LZMA SDK.
+ *
+ * Bcj2.c -- Converter for x86 code (BCJ2)
+ * 2008-10-04 : Igor Pavlov : Public domain
+ *
+ */
+
+#define SZ_ERROR_DATA ARCHIVE_FAILED
+
+#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80)
+#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1))
+
+#define kNumTopBits 24
+#define kTopValue ((uint32_t)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+
+#define RC_READ_BYTE (*buffer++)
+#define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; }
+#define RC_INIT2 zip->bcj2_code = 0; zip->bcj2_range = 0xFFFFFFFF; \
+ { int i; for (i = 0; i < 5; i++) { RC_TEST; zip->bcj2_code = (zip->bcj2_code << 8) | RC_READ_BYTE; }}
+
+#define NORMALIZE if (zip->bcj2_range < kTopValue) { RC_TEST; zip->bcj2_range <<= 8; zip->bcj2_code = (zip->bcj2_code << 8) | RC_READ_BYTE; }
+
+#define IF_BIT_0(p) ttt = *(p); bound = (zip->bcj2_range >> kNumBitModelTotalBits) * ttt; if (zip->bcj2_code < bound)
+#define UPDATE_0(p) zip->bcj2_range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); NORMALIZE;
+#define UPDATE_1(p) zip->bcj2_range -= bound; zip->bcj2_code -= bound; *(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); NORMALIZE;
+
+static ssize_t
+Bcj2_Decode(struct _7zip *zip, uint8_t *outBuf, size_t outSize)
+{
+ size_t inPos = 0, outPos = 0;
+ const uint8_t *buf0, *buf1, *buf2, *buf3;
+ size_t size0, size1, size2, size3;
+ const uint8_t *buffer, *bufferLim;
+ unsigned int i, j;
+
+ size0 = zip->tmp_stream_bytes_remaining;
+ buf0 = zip->tmp_stream_buff + zip->tmp_stream_bytes_avail - size0;
+ size1 = zip->sub_stream_bytes_remaining[0];
+ buf1 = zip->sub_stream_buff[0] + zip->sub_stream_size[0] - size1;
+ size2 = zip->sub_stream_bytes_remaining[1];
+ buf2 = zip->sub_stream_buff[1] + zip->sub_stream_size[1] - size2;
+ size3 = zip->sub_stream_bytes_remaining[2];
+ buf3 = zip->sub_stream_buff[2] + zip->sub_stream_size[2] - size3;
+
+ buffer = buf3;
+ bufferLim = buffer + size3;
+
+ if (zip->bcj_state == 0) {
+ /*
+ * Initialize.
+ */
+ zip->bcj2_prevByte = 0;
+ for (i = 0;
+ i < sizeof(zip->bcj2_p) / sizeof(zip->bcj2_p[0]); i++)
+ zip->bcj2_p[i] = kBitModelTotal >> 1;
+ RC_INIT2;
+ zip->bcj_state = 1;
+ }
+
+ /*
+ * Gather the odd bytes of a previous call.
+ */
+ for (i = 0; zip->odd_bcj_size > 0 && outPos < outSize; i++) {
+ outBuf[outPos++] = zip->odd_bcj[i];
+ zip->odd_bcj_size--;
+ }
+
+ if (outSize == 0) {
+ zip->bcj2_outPos += outPos;
+ return (outPos);
+ }
+
+ for (;;) {
+ uint8_t b;
+ CProb *prob;
+ uint32_t bound;
+ uint32_t ttt;
+
+ size_t limit = size0 - inPos;
+ if (outSize - outPos < limit)
+ limit = outSize - outPos;
+
+ if (zip->bcj_state == 1) {
+ while (limit != 0) {
+ uint8_t b = buf0[inPos];
+ outBuf[outPos++] = b;
+ if (IsJ(zip->bcj2_prevByte, b)) {
+ zip->bcj_state = 2;
+ break;
+ }
+ inPos++;
+ zip->bcj2_prevByte = b;
+ limit--;
+ }
+ }
+
+ if (limit == 0 || outPos == outSize)
+ break;
+ zip->bcj_state = 1;
+
+ b = buf0[inPos++];
+
+ if (b == 0xE8)
+ prob = zip->bcj2_p + zip->bcj2_prevByte;
+ else if (b == 0xE9)
+ prob = zip->bcj2_p + 256;
+ else
+ prob = zip->bcj2_p + 257;
+
+ IF_BIT_0(prob) {
+ UPDATE_0(prob)
+ zip->bcj2_prevByte = b;
+ } else {
+ uint32_t dest;
+ const uint8_t *v;
+ uint8_t out[4];
+
+ UPDATE_1(prob)
+ if (b == 0xE8) {
+ v = buf1;
+ if (size1 < 4)
+ return SZ_ERROR_DATA;
+ buf1 += 4;
+ size1 -= 4;
+ } else {
+ v = buf2;
+ if (size2 < 4)
+ return SZ_ERROR_DATA;
+ buf2 += 4;
+ size2 -= 4;
+ }
+ dest = (((uint32_t)v[0] << 24) |
+ ((uint32_t)v[1] << 16) |
+ ((uint32_t)v[2] << 8) |
+ ((uint32_t)v[3])) -
+ ((uint32_t)zip->bcj2_outPos + outPos + 4);
+ out[0] = (uint8_t)dest;
+ out[1] = (uint8_t)(dest >> 8);
+ out[2] = (uint8_t)(dest >> 16);
+ out[3] = zip->bcj2_prevByte = (uint8_t)(dest >> 24);
+
+ for (i = 0; i < 4 && outPos < outSize; i++)
+ outBuf[outPos++] = out[i];
+ if (i < 4) {
+ /*
+ * Save odd bytes which we could not add into
+ * the output buffer because of out of space.
+ */
+ zip->odd_bcj_size = 4 -i;
+ for (; i < 4; i++) {
+ j = i - 4 + zip->odd_bcj_size;
+ zip->odd_bcj[j] = out[i];
+ }
+ break;
+ }
+ }
+ }
+ zip->tmp_stream_bytes_remaining -= inPos;
+ zip->sub_stream_bytes_remaining[0] = size1;
+ zip->sub_stream_bytes_remaining[1] = size2;
+ zip->sub_stream_bytes_remaining[2] = bufferLim - buffer;
+ zip->bcj2_outPos += outPos;
+
+ return ((ssize_t)outPos);
+}
+
diff --git a/libarchive/archive_read_support_format_all.c b/libarchive/archive_read_support_format_all.c
index 573750811d2c..53fe6fa391a2 100644
--- a/libarchive/archive_read_support_format_all.c
+++ b/libarchive/archive_read_support_format_all.c
@@ -27,17 +27,53 @@
__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_all.c 174991 2007-12-30 04:58:22Z kientzle $");
#include "archive.h"
+#include "archive_private.h"
int
archive_read_support_format_all(struct archive *a)
{
+ archive_check_magic(a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_all");
+
+ /* TODO: It would be nice to compute the ordering
+ * here automatically so that people who enable just
+ * a few formats can still get the benefits. That
+ * may just require the format registration to include
+ * a "maximum read-ahead" value (anything that uses seek
+ * would be essentially infinite read-ahead). The core
+ * bid management can then sort the bidders before calling
+ * them.
+ *
+ * If you implement the above, please return the list below
+ * to alphabetic order.
+ */
+
+ /*
+ * These bidders are all pretty cheap; they just examine a
+ * small initial part of the archive. If one of these bids
+ * high, we can maybe avoid running any of the more expensive
+ * bidders below.
+ */
archive_read_support_format_ar(a);
archive_read_support_format_cpio(a);
archive_read_support_format_empty(a);
- archive_read_support_format_iso9660(a);
+ archive_read_support_format_lha(a);
archive_read_support_format_mtree(a);
archive_read_support_format_tar(a);
archive_read_support_format_xar(a);
+
+ /*
+ * Install expensive bidders last. By doing them last, we
+ * increase the chance that a high bid from someone else will
+ * make it unnecessary for these to do anything at all.
+ */
+ /* These three have potentially large look-ahead. */
+ archive_read_support_format_7zip(a);
+ archive_read_support_format_cab(a);
+ archive_read_support_format_rar(a);
+ archive_read_support_format_iso9660(a);
+ /* Seek is really bad, since it forces the read-ahead
+ * logic to discard buffered data. */
archive_read_support_format_zip(a);
/* Note: We always return ARCHIVE_OK here, even if some of the
diff --git a/libarchive/archive_read_support_format_ar.c b/libarchive/archive_read_support_format_ar.c
index 7c1ca3a0c876..9feb547dbbea 100644
--- a/libarchive/archive_read_support_format_ar.c
+++ b/libarchive/archive_read_support_format_ar.c
@@ -50,11 +50,17 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_ar.c 201101
#include "archive_read_private.h"
struct ar {
- off_t entry_bytes_remaining;
- off_t entry_offset;
- off_t entry_padding;
+ int64_t entry_bytes_remaining;
+ /* unconsumed is purely to track data we've gotten from readahead,
+ * but haven't yet marked as consumed. Must be paired with
+ * entry_bytes_remaining usage/modification.
+ */
+ size_t entry_bytes_unconsumed;
+ int64_t entry_offset;
+ int64_t entry_padding;
char *strtab;
size_t strtab_size;
+ char read_global_header;
};
/*
@@ -75,10 +81,10 @@ struct ar {
#define AR_fmag_offset 58
#define AR_fmag_size 2
-static int archive_read_format_ar_bid(struct archive_read *a);
+static int archive_read_format_ar_bid(struct archive_read *a, int);
static int archive_read_format_ar_cleanup(struct archive_read *a);
static int archive_read_format_ar_read_data(struct archive_read *a,
- const void **buff, size_t *size, off_t *offset);
+ const void **buff, size_t *size, int64_t *offset);
static int archive_read_format_ar_skip(struct archive_read *a);
static int archive_read_format_ar_read_header(struct archive_read *a,
struct archive_entry *e);
@@ -95,6 +101,9 @@ archive_read_support_format_ar(struct archive *_a)
struct ar *ar;
int r;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_ar");
+
ar = (struct ar *)malloc(sizeof(*ar));
if (ar == NULL) {
archive_set_error(&a->archive, ENOMEM,
@@ -135,14 +144,11 @@ archive_read_format_ar_cleanup(struct archive_read *a)
}
static int
-archive_read_format_ar_bid(struct archive_read *a)
+archive_read_format_ar_bid(struct archive_read *a, int best_bid)
{
const void *h;
- if (a->archive.archive_format != 0 &&
- (a->archive.archive_format & ARCHIVE_FORMAT_BASE_MASK) !=
- ARCHIVE_FORMAT_AR)
- return(0);
+ (void)best_bid; /* UNUSED */
/*
* Verify the 8-byte file signature.
@@ -150,45 +156,23 @@ archive_read_format_ar_bid(struct archive_read *a)
*/
if ((h = __archive_read_ahead(a, 8, NULL)) == NULL)
return (-1);
- if (strncmp((const char*)h, "!<arch>\n", 8) == 0) {
+ if (memcmp(h, "!<arch>\n", 8) == 0) {
return (64);
}
return (-1);
}
static int
-archive_read_format_ar_read_header(struct archive_read *a,
- struct archive_entry *entry)
+_ar_read_header(struct archive_read *a, struct archive_entry *entry,
+ struct ar *ar, const char *h, size_t *unconsumed)
{
char filename[AR_name_size + 1];
- struct ar *ar;
uint64_t number; /* Used to hold parsed numbers before validation. */
- ssize_t bytes_read;
size_t bsd_name_length, entry_size;
char *p, *st;
const void *b;
- const char *h;
int r;
- ar = (struct ar*)(a->format->data);
-
- if (a->archive.file_position == 0) {
- /*
- * We are now at the beginning of the archive,
- * so we need first consume the ar global header.
- */
- __archive_read_consume(a, 8);
- /* Set a default format code for now. */
- a->archive.archive_format = ARCHIVE_FORMAT_AR;
- }
-
- /* Read the header for the next file entry. */
- if ((b = __archive_read_ahead(a, 60, &bytes_read)) == NULL)
- /* Broken header. */
- return (ARCHIVE_EOF);
- __archive_read_consume(a, 60);
- h = (const char *)b;
-
/* Verify the magic signature on the file header. */
if (strncmp(h + AR_fmag_offset, "`\n", 2) != 0) {
archive_set_error(&a->archive, EINVAL,
@@ -292,6 +276,12 @@ archive_read_format_ar_read_header(struct archive_read *a,
}
ar->strtab = st;
ar->strtab_size = entry_size;
+
+ if (*unconsumed) {
+ __archive_read_consume(a, *unconsumed);
+ *unconsumed = 0;
+ }
+
if ((b = __archive_read_ahead(a, entry_size, NULL)) == NULL)
return (ARCHIVE_FATAL);
memcpy(st, b, entry_size);
@@ -347,7 +337,7 @@ archive_read_format_ar_read_header(struct archive_read *a,
* overflowing a size_t and against the filename size
* being larger than the entire entry. */
if (number > (uint64_t)(bsd_name_length + 1)
- || (off_t)bsd_name_length > ar->entry_bytes_remaining) {
+ || (int64_t)bsd_name_length > ar->entry_bytes_remaining) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Bad input file size");
return (ARCHIVE_FATAL);
@@ -356,14 +346,17 @@ archive_read_format_ar_read_header(struct archive_read *a,
/* Adjust file size reported to client. */
archive_entry_set_size(entry, ar->entry_bytes_remaining);
+ if (*unconsumed) {
+ __archive_read_consume(a, *unconsumed);
+ *unconsumed = 0;
+ }
+
/* Read the long name into memory. */
if ((b = __archive_read_ahead(a, bsd_name_length, NULL)) == NULL) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Truncated input file");
return (ARCHIVE_FATAL);
}
- __archive_read_consume(a, bsd_name_length);
-
/* Store it in the entry. */
p = (char *)malloc(bsd_name_length + 1);
if (p == NULL) {
@@ -373,6 +366,9 @@ archive_read_format_ar_read_header(struct archive_read *a,
}
strncpy(p, b, bsd_name_length);
p[bsd_name_length] = '\0';
+
+ __archive_read_consume(a, bsd_name_length);
+
archive_entry_copy_pathname(entry, p);
free(p);
return (ARCHIVE_OK);
@@ -409,6 +405,42 @@ archive_read_format_ar_read_header(struct archive_read *a,
}
static int
+archive_read_format_ar_read_header(struct archive_read *a,
+ struct archive_entry *entry)
+{
+ struct ar *ar = (struct ar*)(a->format->data);
+ size_t unconsumed;
+ const void *header_data;
+ int ret;
+
+ if (!ar->read_global_header) {
+ /*
+ * We are now at the beginning of the archive,
+ * so we need first consume the ar global header.
+ */
+ __archive_read_consume(a, 8);
+ ar->read_global_header = 1;
+ /* Set a default format code for now. */
+ a->archive.archive_format = ARCHIVE_FORMAT_AR;
+ }
+
+ /* Read the header for the next file entry. */
+ if ((header_data = __archive_read_ahead(a, 60, NULL)) == NULL)
+ /* Broken header. */
+ return (ARCHIVE_EOF);
+
+ unconsumed = 60;
+
+ ret = _ar_read_header(a, entry, ar, (const char *)header_data, &unconsumed);
+
+ if (unconsumed)
+ __archive_read_consume(a, unconsumed);
+
+ return ret;
+}
+
+
+static int
ar_parse_common_header(struct ar *ar, struct archive_entry *entry,
const char *h)
{
@@ -434,13 +466,18 @@ ar_parse_common_header(struct ar *ar, struct archive_entry *entry,
static int
archive_read_format_ar_read_data(struct archive_read *a,
- const void **buff, size_t *size, off_t *offset)
+ const void **buff, size_t *size, int64_t *offset)
{
ssize_t bytes_read;
struct ar *ar;
ar = (struct ar *)(a->format->data);
+ if (ar->entry_bytes_unconsumed) {
+ __archive_read_consume(a, ar->entry_bytes_unconsumed);
+ ar->entry_bytes_unconsumed = 0;
+ }
+
if (ar->entry_bytes_remaining > 0) {
*buff = __archive_read_ahead(a, 1, &bytes_read);
if (bytes_read == 0) {
@@ -453,20 +490,22 @@ archive_read_format_ar_read_data(struct archive_read *a,
if (bytes_read > ar->entry_bytes_remaining)
bytes_read = (ssize_t)ar->entry_bytes_remaining;
*size = bytes_read;
+ ar->entry_bytes_unconsumed = bytes_read;
*offset = ar->entry_offset;
ar->entry_offset += bytes_read;
ar->entry_bytes_remaining -= bytes_read;
- __archive_read_consume(a, (size_t)bytes_read);
return (ARCHIVE_OK);
} else {
- while (ar->entry_padding > 0) {
- *buff = __archive_read_ahead(a, 1, &bytes_read);
- if (bytes_read <= 0)
- return (ARCHIVE_FATAL);
- if (bytes_read > ar->entry_padding)
- bytes_read = (ssize_t)ar->entry_padding;
- __archive_read_consume(a, (size_t)bytes_read);
- ar->entry_padding -= bytes_read;
+ int64_t skipped = __archive_read_consume(a, ar->entry_padding);
+ if (skipped >= 0) {
+ ar->entry_padding -= skipped;
+ }
+ if (ar->entry_padding) {
+ if (skipped >= 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Truncated ar archive- failed consuming padding");
+ }
+ return (ARCHIVE_FATAL);
}
*buff = NULL;
*size = 0;
@@ -478,17 +517,19 @@ archive_read_format_ar_read_data(struct archive_read *a,
static int
archive_read_format_ar_skip(struct archive_read *a)
{
- off_t bytes_skipped;
+ int64_t bytes_skipped;
struct ar* ar;
ar = (struct ar *)(a->format->data);
- bytes_skipped = __archive_read_skip(a,
- ar->entry_bytes_remaining + ar->entry_padding);
+ bytes_skipped = __archive_read_consume(a,
+ ar->entry_bytes_remaining + ar->entry_padding
+ + ar->entry_bytes_unconsumed);
if (bytes_skipped < 0)
return (ARCHIVE_FATAL);
ar->entry_bytes_remaining = 0;
+ ar->entry_bytes_unconsumed = 0;
ar->entry_padding = 0;
return (ARCHIVE_OK);
diff --git a/libarchive/archive_read_support_format_by_code.c b/libarchive/archive_read_support_format_by_code.c
new file mode 100644
index 000000000000..084563f4310e
--- /dev/null
+++ b/libarchive/archive_read_support_format_by_code.c
@@ -0,0 +1,74 @@
+/*-
+ * Copyright (c) 2003-2011 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+__FBSDID("$FreeBSD$");
+
+#include "archive.h"
+#include "archive_private.h"
+
+int
+archive_read_support_format_by_code(struct archive *a, int format_code)
+{
+ archive_check_magic(a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_by_code");
+
+ switch (format_code & ARCHIVE_FORMAT_BASE_MASK) {
+ case ARCHIVE_FORMAT_7ZIP:
+ return archive_read_support_format_7zip(a);
+ break;
+ case ARCHIVE_FORMAT_AR:
+ return archive_read_support_format_ar(a);
+ break;
+ case ARCHIVE_FORMAT_CAB:
+ return archive_read_support_format_cab(a);
+ break;
+ case ARCHIVE_FORMAT_CPIO:
+ return archive_read_support_format_cpio(a);
+ break;
+ case ARCHIVE_FORMAT_ISO9660:
+ return archive_read_support_format_iso9660(a);
+ break;
+ case ARCHIVE_FORMAT_LHA:
+ return archive_read_support_format_lha(a);
+ break;
+ case ARCHIVE_FORMAT_MTREE:
+ return archive_read_support_format_mtree(a);
+ break;
+ case ARCHIVE_FORMAT_RAR:
+ return archive_read_support_format_rar(a);
+ break;
+ case ARCHIVE_FORMAT_TAR:
+ return archive_read_support_format_tar(a);
+ break;
+ case ARCHIVE_FORMAT_XAR:
+ return archive_read_support_format_xar(a);
+ break;
+ case ARCHIVE_FORMAT_ZIP:
+ return archive_read_support_format_zip(a);
+ break;
+ }
+ return (ARCHIVE_FATAL);
+}
diff --git a/libarchive/archive_read_support_format_cab.c b/libarchive/archive_read_support_format_cab.c
new file mode 100644
index 000000000000..1b81ee92ce4d
--- /dev/null
+++ b/libarchive/archive_read_support_format_cab.c
@@ -0,0 +1,3315 @@
+/*-
+ * Copyright (c) 2010-2011 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_ZLIB_H
+#include <zlib.h>
+#endif
+
+#include "archive.h"
+#include "archive_entry.h"
+#include "archive_entry_locale.h"
+#include "archive_private.h"
+#include "archive_read_private.h"
+#include "archive_endian.h"
+
+
+struct lzx_dec {
+ /* Decoding status. */
+ int state;
+
+ /*
+ * Window to see last decoded data, from 32KBi to 2MBi.
+ */
+ int w_size;
+ int w_mask;
+ /* Window buffer, which is a loop buffer. */
+ unsigned char *w_buff;
+ /* The insert position to the window. */
+ int w_pos;
+ /* The position where we can copy decoded code from the window. */
+ int copy_pos;
+ /* The length how many bytes we can copy decoded code from
+ * the window. */
+ int copy_len;
+ /* Translation reversal for x86 proccessor CALL byte sequence(E8).
+ * This is used for LZX only. */
+ uint32_t translation_size;
+ char translation;
+ char block_type;
+#define VERBATIM_BLOCK 1
+#define ALIGNED_OFFSET_BLOCK 2
+#define UNCOMPRESSED_BLOCK 3
+ size_t block_size;
+ size_t block_bytes_avail;
+ /* Repeated offset. */
+ int r0, r1, r2;
+ unsigned char rbytes[4];
+ int rbytes_avail;
+ int length_header;
+ int position_slot;
+ int offset_bits;
+
+ struct lzx_pos_tbl {
+ int base;
+ int footer_bits;
+ } *pos_tbl;
+ /*
+ * Bit stream reader.
+ */
+ struct lzx_br {
+#define CACHE_TYPE uint64_t
+#define CACHE_BITS (8 * sizeof(CACHE_TYPE))
+ /* Cache buffer. */
+ CACHE_TYPE cache_buffer;
+ /* Indicates how many bits avail in cache_buffer. */
+ int cache_avail;
+ unsigned char odd;
+ char have_odd;
+ } br;
+
+ /*
+ * Huffman coding.
+ */
+ struct huffman {
+ int len_size;
+ int freq[17];
+ unsigned char *bitlen;
+
+ /*
+ * Use a index table. It's faster than searching a huffman
+ * coding tree, which is a binary tree. But a use of a large
+ * index table causes L1 cache read miss many times.
+ */
+#define HTBL_BITS 10
+ int max_bits;
+ int shift_bits;
+ int tbl_bits;
+ int tree_used;
+ int tree_avail;
+ /* Direct access table. */
+ uint16_t *tbl;
+ /* Binary tree table for extra bits over the direct access. */
+ struct htree_t {
+ uint16_t left;
+ uint16_t right;
+ } *tree;
+ } at, lt, mt, pt;
+
+ int loop;
+ int error;
+};
+
+static const int slots[] = {
+ 30, 32, 34, 36, 38, 42, 50, 66, 98, 162, 290
+};
+#define SLOT_BASE 15
+#define SLOT_MAX 21/*->25*/
+
+struct lzx_stream {
+ const unsigned char *next_in;
+ int64_t avail_in;
+ int64_t total_in;
+ unsigned char *next_out;
+ int64_t avail_out;
+ int64_t total_out;
+ struct lzx_dec *ds;
+};
+
+/*
+ * Cabinet file definitions.
+ */
+/* CFHEADER offset */
+#define CFHEADER_signature 0
+#define CFHEADER_cbCabinet 8
+#define CFHEADER_coffFiles 16
+#define CFHEADER_versionMinor 24
+#define CFHEADER_versionMajor 25
+#define CFHEADER_cFolders 26
+#define CFHEADER_cFiles 28
+#define CFHEADER_flags 30
+#define CFHEADER_setID 32
+#define CFHEADER_iCabinet 34
+#define CFHEADER_cbCFHeader 36
+#define CFHEADER_cbCFFolder 38
+#define CFHEADER_cbCFData 39
+
+/* CFFOLDER offset */
+#define CFFOLDER_coffCabStart 0
+#define CFFOLDER_cCFData 4
+#define CFFOLDER_typeCompress 6
+#define CFFOLDER_abReserve 8
+
+/* CFFILE offset */
+#define CFFILE_cbFile 0
+#define CFFILE_uoffFolderStart 4
+#define CFFILE_iFolder 8
+#define CFFILE_date_time 10
+#define CFFILE_attribs 14
+
+/* CFDATA offset */
+#define CFDATA_csum 0
+#define CFDATA_cbData 4
+#define CFDATA_cbUncomp 6
+
+static const char *compression_name[] = {
+ "NONE",
+ "MSZIP",
+ "Quantum",
+ "LZX",
+};
+
+struct cfdata {
+ /* Sum value of this CFDATA. */
+ uint32_t sum;
+ uint16_t compressed_size;
+ uint16_t compressed_bytes_remaining;
+ uint16_t uncompressed_size;
+ uint16_t uncompressed_bytes_remaining;
+ /* To know how many bytes we have decompressed. */
+ uint16_t uncompressed_avail;
+ /* Offset from the beginning of compressed data of this CFDATA */
+ uint16_t read_offset;
+ int64_t unconsumed;
+ /* To keep memory image of this CFDATA to compute the sum. */
+ size_t memimage_size;
+ unsigned char *memimage;
+ /* Result of calculation of sum. */
+ uint32_t sum_calculated;
+ unsigned char sum_extra[4];
+ int sum_extra_avail;
+ const void *sum_ptr;
+};
+
+struct cffolder {
+ uint32_t cfdata_offset_in_cab;
+ uint16_t cfdata_count;
+ uint16_t comptype;
+#define COMPTYPE_NONE 0x0000
+#define COMPTYPE_MSZIP 0x0001
+#define COMPTYPE_QUANTUM 0x0002
+#define COMPTYPE_LZX 0x0003
+ uint16_t compdata;
+ const char *compname;
+ /* At the time reading CFDATA */
+ struct cfdata cfdata;
+ int cfdata_index;
+ /* Flags to mark progress of decompression. */
+ char decompress_init;
+};
+
+struct cffile {
+ uint32_t uncompressed_size;
+ uint32_t offset;
+ time_t mtime;
+ uint16_t folder;
+#define iFoldCONTINUED_FROM_PREV 0xFFFD
+#define iFoldCONTINUED_TO_NEXT 0xFFFE
+#define iFoldCONTINUED_PREV_AND_NEXT 0xFFFF
+ unsigned char attr;
+#define ATTR_RDONLY 0x01
+#define ATTR_NAME_IS_UTF 0x80
+ struct archive_string pathname;
+};
+
+struct cfheader {
+ /* Total bytes of all file size in a Cabinet. */
+ uint32_t total_bytes;
+ uint32_t files_offset;
+ uint16_t folder_count;
+ uint16_t file_count;
+ uint16_t flags;
+#define PREV_CABINET 0x0001
+#define NEXT_CABINET 0x0002
+#define RESERVE_PRESENT 0x0004
+ uint16_t setid;
+ uint16_t cabinet;
+ /* Version number. */
+ unsigned char major;
+ unsigned char minor;
+ unsigned char cffolder;
+ unsigned char cfdata;
+ /* All folders in a cabinet. */
+ struct cffolder *folder_array;
+ /* All files in a cabinet. */
+ struct cffile *file_array;
+ int file_index;
+};
+
+struct cab {
+ /* entry_bytes_remaining is the number of bytes we expect. */
+ int64_t entry_offset;
+ int64_t entry_bytes_remaining;
+ int64_t entry_unconsumed;
+ int64_t entry_compressed_bytes_read;
+ int64_t entry_uncompressed_bytes_read;
+ struct cffolder *entry_cffolder;
+ struct cffile *entry_cffile;
+ struct cfdata *entry_cfdata;
+
+ /* Offset from beginning of a cabinet file. */
+ int64_t cab_offset;
+ struct cfheader cfheader;
+ struct archive_wstring ws;
+
+ /* Flag to mark progress that an archive was read their first header.*/
+ char found_header;
+ char end_of_archive;
+ char end_of_entry;
+ char end_of_entry_cleanup;
+
+ unsigned char *uncompressed_buffer;
+ size_t uncompressed_buffer_size;
+
+ int init_default_conversion;
+ struct archive_string_conv *sconv;
+ struct archive_string_conv *sconv_default;
+ struct archive_string_conv *sconv_utf8;
+ char format_name[64];
+
+#ifdef HAVE_ZLIB_H
+ z_stream stream;
+ char stream_valid;
+#endif
+ struct lzx_stream xstrm;
+};
+
+static int archive_read_format_cab_bid(struct archive_read *, int);
+static int archive_read_format_cab_options(struct archive_read *,
+ const char *, const char *);
+static int archive_read_format_cab_read_header(struct archive_read *,
+ struct archive_entry *);
+static int archive_read_format_cab_read_data(struct archive_read *,
+ const void **, size_t *, int64_t *);
+static int archive_read_format_cab_read_data_skip(struct archive_read *);
+static int archive_read_format_cab_cleanup(struct archive_read *);
+
+static int cab_skip_sfx(struct archive_read *);
+static time_t cab_dos_time(const unsigned char *);
+static int cab_read_data(struct archive_read *, const void **,
+ size_t *, int64_t *);
+static int cab_read_header(struct archive_read *);
+static uint32_t cab_checksum_cfdata_4(const void *, size_t bytes, uint32_t);
+static uint32_t cab_checksum_cfdata(const void *, size_t bytes, uint32_t);
+static void cab_checksum_update(struct archive_read *, size_t);
+static int cab_checksum_finish(struct archive_read *);
+static int cab_next_cfdata(struct archive_read *);
+static const void *cab_read_ahead_cfdata(struct archive_read *, ssize_t *);
+static const void *cab_read_ahead_cfdata_none(struct archive_read *, ssize_t *);
+static const void *cab_read_ahead_cfdata_deflate(struct archive_read *,
+ ssize_t *);
+static const void *cab_read_ahead_cfdata_lzx(struct archive_read *,
+ ssize_t *);
+static int64_t cab_consume_cfdata(struct archive_read *, int64_t);
+static int64_t cab_minimum_consume_cfdata(struct archive_read *, int64_t);
+static int lzx_decode_init(struct lzx_stream *, int);
+static int lzx_read_blocks(struct lzx_stream *, int);
+static int lzx_decode_blocks(struct lzx_stream *, int);
+static void lzx_decode_free(struct lzx_stream *);
+static void lzx_translation(struct lzx_stream *, void *, size_t, uint32_t);
+static void lzx_cleanup_bitstream(struct lzx_stream *);
+static int lzx_decode(struct lzx_stream *, int);
+static int lzx_read_pre_tree(struct lzx_stream *);
+static int lzx_read_bitlen(struct lzx_stream *, struct huffman *, int);
+static int lzx_huffman_init(struct huffman *, size_t, int);
+static void lzx_huffman_free(struct huffman *);
+static int lzx_make_huffman_table(struct huffman *);
+static int inline lzx_decode_huffman(struct huffman *, unsigned);
+static int lzx_decode_huffman_tree(struct huffman *, unsigned, int);
+
+
+int
+archive_read_support_format_cab(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct cab *cab;
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_cab");
+
+ cab = (struct cab *)calloc(1, sizeof(*cab));
+ if (cab == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate CAB data");
+ return (ARCHIVE_FATAL);
+ }
+ archive_string_init(&cab->ws);
+ archive_wstring_ensure(&cab->ws, 256);
+
+ r = __archive_read_register_format(a,
+ cab,
+ "cab",
+ archive_read_format_cab_bid,
+ archive_read_format_cab_options,
+ archive_read_format_cab_read_header,
+ archive_read_format_cab_read_data,
+ archive_read_format_cab_read_data_skip,
+ archive_read_format_cab_cleanup);
+
+ if (r != ARCHIVE_OK)
+ free(cab);
+ return (ARCHIVE_OK);
+}
+
+static int
+find_cab_magic(const char *p)
+{
+ switch (p[4]) {
+ case 0:
+ /*
+ * Note: Self-Extraction program has 'MSCF' string in their
+ * program. If we were finding 'MSCF' string only, we got
+ * wrong place for Cabinet header, thus, we have to check
+ * following four bytes which are reserved and must be set
+ * to zero.
+ */
+ if (memcmp(p, "MSCF\0\0\0\0", 8) == 0)
+ return 0;
+ return 5;
+ case 'F': return 1;
+ case 'C': return 2;
+ case 'S': return 3;
+ case 'M': return 4;
+ default: return 5;
+ }
+}
+
+static int
+archive_read_format_cab_bid(struct archive_read *a, int best_bid)
+{
+ const char *p;
+ ssize_t bytes_avail, offset, window;
+
+ /* If there's already a better bid than we can ever
+ make, don't bother testing. */
+ if (best_bid > 64)
+ return (-1);
+
+ if ((p = __archive_read_ahead(a, 8, NULL)) == NULL)
+ return (-1);
+
+ if (memcmp(p, "MSCF\0\0\0\0", 8) == 0)
+ return (64);
+
+ /*
+ * Attempt to handle self-extracting archives
+ * by noting a PE header and searching forward
+ * up to 128k for a 'MSCF' marker.
+ */
+ if (p[0] == 'M' && p[1] == 'Z') {
+ offset = 0;
+ window = 4096;
+ while (offset < (1024 * 128)) {
+ const char *h = __archive_read_ahead(a, offset + window,
+ &bytes_avail);
+ if (h == NULL) {
+ /* Remaining bytes are less than window. */
+ window >>= 1;
+ if (window < 128)
+ return (0);
+ continue;
+ }
+ p = h + offset;
+ while (p + 8 < h + bytes_avail) {
+ int next;
+ if ((next = find_cab_magic(p)) == 0)
+ return (64);
+ p += next;
+ }
+ offset = p - h;
+ }
+ }
+ return (0);
+}
+
+static int
+archive_read_format_cab_options(struct archive_read *a,
+ const char *key, const char *val)
+{
+ struct cab *cab;
+ int ret = ARCHIVE_FAILED;
+
+ cab = (struct cab *)(a->format->data);
+ if (strcmp(key, "hdrcharset") == 0) {
+ if (val == NULL || val[0] == 0)
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "cab: hdrcharset option needs a character-set name");
+ else {
+ cab->sconv = archive_string_conversion_from_charset(
+ &a->archive, val, 0);
+ if (cab->sconv != NULL)
+ ret = ARCHIVE_OK;
+ else
+ ret = ARCHIVE_FATAL;
+ }
+ } else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "cab: unknown keyword ``%s''", key);
+
+ return (ret);
+}
+
+static int
+cab_skip_sfx(struct archive_read *a)
+{
+ const char *p, *q;
+ size_t skip;
+ ssize_t bytes, window;
+
+ window = 4096;
+ for (;;) {
+ const char *h = __archive_read_ahead(a, window, &bytes);
+ if (h == NULL) {
+ /* Remaining size are less than window. */
+ window >>= 1;
+ if (window < 128) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Couldn't find out CAB header");
+ return (ARCHIVE_FATAL);
+ }
+ continue;
+ }
+ p = h;
+ q = p + bytes;
+
+ /*
+ * Scan ahead until we find something that looks
+ * like the cab header.
+ */
+ while (p + 8 < q) {
+ int next;
+ if ((next = find_cab_magic(p)) == 0) {
+ skip = p - h;
+ __archive_read_consume(a, skip);
+ return (ARCHIVE_OK);
+ }
+ p += next;
+ }
+ skip = p - h;
+ __archive_read_consume(a, skip);
+ }
+}
+
+static int
+truncated_error(struct archive_read *a)
+{
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated CAB header");
+ return (ARCHIVE_FATAL);
+}
+
+static int
+cab_strnlen(const unsigned char *p, size_t maxlen)
+{
+ size_t i;
+
+ for (i = 0; i <= maxlen; i++) {
+ if (p[i] == 0)
+ break;
+ }
+ if (i > maxlen)
+ return (-1);/* invalid */
+ return (i);
+}
+
+/* Read bytes as much as remaining. */
+static const void *
+cab_read_ahead_remaining(struct archive_read *a, size_t min, ssize_t *avail)
+{
+ const void *p;
+
+ while (min > 0) {
+ p = __archive_read_ahead(a, min, avail);
+ if (p != NULL)
+ return (p);
+ min--;
+ }
+ return (NULL);
+}
+
+/* Convert a path separator '\' -> '/' */
+static int
+cab_convert_path_separator_1(struct archive_string *fn, unsigned char attr)
+{
+ size_t i;
+ int mb;
+
+ /* Easy check if we have '\' in multi-byte string. */
+ mb = 0;
+ for (i = 0; i < archive_strlen(fn); i++) {
+ if (fn->s[i] == '\\') {
+ if (mb) {
+ /* This may be second byte of multi-byte
+ * character. */
+ break;
+ }
+ fn->s[i] = '/';
+ mb = 0;
+ } else if ((fn->s[i] & 0x80) && !(attr & ATTR_NAME_IS_UTF))
+ mb = 1;
+ else
+ mb = 0;
+ }
+ if (i == archive_strlen(fn))
+ return (0);
+ return (-1);
+}
+
+/*
+ * Replace a character '\' with '/' in wide character.
+ */
+static void
+cab_convert_path_separator_2(struct cab *cab, struct archive_entry *entry)
+{
+ const wchar_t *wp;
+ size_t i;
+
+ /* If a conversion to wide character failed, force the replacement. */
+ if ((wp = archive_entry_pathname_w(entry)) != NULL) {
+ archive_wstrcpy(&(cab->ws), wp);
+ for (i = 0; i < archive_strlen(&(cab->ws)); i++) {
+ if (cab->ws.s[i] == L'\\')
+ cab->ws.s[i] = L'/';
+ }
+ archive_entry_copy_pathname_w(entry, cab->ws.s);
+ }
+}
+
+/*
+ * Read CFHEADER, CFFOLDER and CFFILE.
+ */
+static int
+cab_read_header(struct archive_read *a)
+{
+ const unsigned char *p;
+ struct cab *cab;
+ struct cfheader *hd;
+ size_t bytes, used;
+ int64_t skip;
+ int err, i, len;
+ int cur_folder, prev_folder;
+ uint32_t offset32;
+
+ a->archive.archive_format = ARCHIVE_FORMAT_CAB;
+ if (a->archive.archive_format_name == NULL)
+ a->archive.archive_format_name = "CAB";
+
+ if ((p = __archive_read_ahead(a, 42, NULL)) == NULL)
+ return (truncated_error(a));
+
+ cab = (struct cab *)(a->format->data);
+ if (cab->found_header == 0 &&
+ p[0] == 'M' && p[1] == 'Z') {
+ /* This is an executable? Must be self-extracting... */
+ err = cab_skip_sfx(a);
+ if (err < ARCHIVE_WARN)
+ return (err);
+
+ if ((p = __archive_read_ahead(a, sizeof(*p), NULL)) == NULL)
+ return (truncated_error(a));
+ }
+
+ cab->cab_offset = 0;
+ /*
+ * Read CFHEADER.
+ */
+ hd = &cab->cfheader;
+ if (p[CFHEADER_signature+0] != 'M' || p[CFHEADER_signature+1] != 'S' ||
+ p[CFHEADER_signature+2] != 'C' || p[CFHEADER_signature+3] != 'F') {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Couldn't find out CAB header");
+ return (ARCHIVE_FATAL);
+ }
+ hd->total_bytes = archive_le32dec(p + CFHEADER_cbCabinet);
+ hd->files_offset = archive_le32dec(p + CFHEADER_coffFiles);
+ hd->minor = p[CFHEADER_versionMinor];
+ hd->major = p[CFHEADER_versionMajor];
+ hd->folder_count = archive_le16dec(p + CFHEADER_cFolders);
+ if (hd->folder_count == 0)
+ goto invalid;
+ hd->file_count = archive_le16dec(p + CFHEADER_cFiles);
+ if (hd->file_count == 0)
+ goto invalid;
+ hd->flags = archive_le16dec(p + CFHEADER_flags);
+ hd->setid = archive_le16dec(p + CFHEADER_setID);
+ hd->cabinet = archive_le16dec(p + CFHEADER_iCabinet);
+ used = CFHEADER_iCabinet + 2;
+ if (hd->flags & RESERVE_PRESENT) {
+ uint16_t cfheader;
+ cfheader = archive_le16dec(p + CFHEADER_cbCFHeader);
+ if (cfheader > 60000U)
+ goto invalid;
+ hd->cffolder = p[CFHEADER_cbCFFolder];
+ hd->cfdata = p[CFHEADER_cbCFData];
+ used += 4;/* cbCFHeader, cbCFFolder and cbCFData */
+ used += cfheader;/* abReserve */
+ } else
+ hd->cffolder = 0;/* Avoid compiling warning. */
+ if (hd->flags & PREV_CABINET) {
+ /* How many bytes are used for szCabinetPrev. */
+ if ((p = __archive_read_ahead(a, used+256, NULL)) == NULL)
+ return (truncated_error(a));
+ if ((len = cab_strnlen(p + used, 255)) <= 0)
+ goto invalid;
+ used += len + 1;
+ /* How many bytes are used for szDiskPrev. */
+ if ((p = __archive_read_ahead(a, used+256, NULL)) == NULL)
+ return (truncated_error(a));
+ if ((len = cab_strnlen(p + used, 255)) <= 0)
+ goto invalid;
+ used += len + 1;
+ }
+ if (hd->flags & NEXT_CABINET) {
+ /* How many bytes are used for szCabinetNext. */
+ if ((p = __archive_read_ahead(a, used+256, NULL)) == NULL)
+ return (truncated_error(a));
+ if ((len = cab_strnlen(p + used, 255)) <= 0)
+ goto invalid;
+ used += len + 1;
+ /* How many bytes are used for szDiskNext. */
+ if ((p = __archive_read_ahead(a, used+256, NULL)) == NULL)
+ return (truncated_error(a));
+ if ((len = cab_strnlen(p + used, 255)) <= 0)
+ goto invalid;
+ used += len + 1;
+ }
+ __archive_read_consume(a, used);
+ cab->cab_offset += used;
+ used = 0;
+
+ /*
+ * Read CFFOLDER.
+ */
+ hd->folder_array = (struct cffolder *)calloc(
+ hd->folder_count, sizeof(struct cffolder));
+ if (hd->folder_array == NULL)
+ goto nomem;
+
+ bytes = 8;
+ if (hd->flags & RESERVE_PRESENT)
+ bytes += hd->cffolder;
+ bytes *= hd->folder_count;
+ if ((p = __archive_read_ahead(a, bytes, NULL)) == NULL)
+ return (truncated_error(a));
+ offset32 = 0;
+ for (i = 0; i < hd->folder_count; i++) {
+ struct cffolder *folder = &(hd->folder_array[i]);
+ folder->cfdata_offset_in_cab =
+ archive_le32dec(p + CFFOLDER_coffCabStart);
+ folder->cfdata_count = archive_le16dec(p+CFFOLDER_cCFData);
+ folder->comptype =
+ archive_le16dec(p+CFFOLDER_typeCompress) & 0x0F;
+ folder->compdata =
+ archive_le16dec(p+CFFOLDER_typeCompress) >> 8;
+ /* Get a compression name. */
+ if (folder->comptype <
+ sizeof(compression_name) / sizeof(compression_name[0]))
+ folder->compname = compression_name[folder->comptype];
+ else
+ folder->compname = "UNKNOWN";
+ p += 8;
+ used += 8;
+ if (hd->flags & RESERVE_PRESENT) {
+ p += hd->cffolder;/* abReserve */
+ used += hd->cffolder;
+ }
+ /*
+ * Sanity check if each data is acceptable.
+ */
+ if (offset32 >= folder->cfdata_offset_in_cab)
+ goto invalid;
+ offset32 = folder->cfdata_offset_in_cab;
+
+ /* Set a request to initialize zlib for the CFDATA of
+ * this folder. */
+ folder->decompress_init = 0;
+ }
+ __archive_read_consume(a, used);
+ cab->cab_offset += used;
+
+ /*
+ * Read CFFILE.
+ */
+ /* Seek read pointer to the offset of CFFILE if needed. */
+ skip = (int64_t)hd->files_offset - cab->cab_offset;
+ if (skip < 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Invalid offset of CFFILE %jd < %jd",
+ (intmax_t)hd->files_offset, (intmax_t)cab->cab_offset);
+ return (ARCHIVE_FATAL);
+ }
+ if (skip) {
+ __archive_read_consume(a, skip);
+ cab->cab_offset += skip;
+ }
+ /* Allocate memory for CFDATA */
+ hd->file_array = (struct cffile *)calloc(
+ hd->file_count, sizeof(struct cffile));
+ if (hd->file_array == NULL)
+ goto nomem;
+
+ prev_folder = -1;
+ for (i = 0; i < hd->file_count; i++) {
+ struct cffile *file = &(hd->file_array[i]);
+ ssize_t avail;
+
+ if ((p = __archive_read_ahead(a, 16, NULL)) == NULL)
+ return (truncated_error(a));
+ file->uncompressed_size = archive_le32dec(p + CFFILE_cbFile);
+ file->offset = archive_le32dec(p + CFFILE_uoffFolderStart);
+ file->folder = archive_le16dec(p + CFFILE_iFolder);
+ file->mtime = cab_dos_time(p + CFFILE_date_time);
+ file->attr = archive_le16dec(p + CFFILE_attribs);
+ __archive_read_consume(a, 16);
+
+ cab->cab_offset += 16;
+ if ((p = cab_read_ahead_remaining(a, 256, &avail)) == NULL)
+ return (truncated_error(a));
+ if ((len = cab_strnlen(p, avail-1)) <= 0)
+ goto invalid;
+
+ /* Copy a pathname. */
+ archive_string_init(&(file->pathname));
+ archive_strncpy(&(file->pathname), p, len);
+ __archive_read_consume(a, len + 1);
+ cab->cab_offset += len + 1;
+
+ /*
+ * Sanity check if each data is acceptable.
+ */
+ if (file->uncompressed_size > 0x7FFF8000)
+ goto invalid;/* Too large */
+ if ((int64_t)file->offset + (int64_t)file->uncompressed_size
+ > ARCHIVE_LITERAL_LL(0x7FFF8000))
+ goto invalid;/* Too large */
+ switch (file->folder) {
+ case iFoldCONTINUED_TO_NEXT:
+ /* This must be last file in a folder. */
+ if (i != hd->file_count -1)
+ goto invalid;
+ cur_folder = hd->folder_count -1;
+ break;
+ case iFoldCONTINUED_PREV_AND_NEXT:
+ /* This must be only one file in a folder. */
+ if (hd->file_count != 1)
+ goto invalid;
+ /* FALL THROUGH */
+ case iFoldCONTINUED_FROM_PREV:
+ /* This must be first file in a folder. */
+ if (i != 0)
+ goto invalid;
+ prev_folder = cur_folder = 0;
+ offset32 = file->offset;
+ break;
+ default:
+ if (file->folder >= hd->folder_count)
+ goto invalid;
+ cur_folder = file->folder;
+ break;
+ }
+ /* Dot not back track. */
+ if (cur_folder < prev_folder)
+ goto invalid;
+ if (cur_folder != prev_folder)
+ offset32 = 0;
+ prev_folder = cur_folder;
+
+ /* Make sure there are not any blanks from last file
+ * contents. */
+ if (offset32 != file->offset)
+ goto invalid;
+ offset32 += file->uncompressed_size;
+
+ /* CFDATA is available for file contents. */
+ if (file->uncompressed_size > 0 &&
+ hd->folder_array[cur_folder].cfdata_count == 0)
+ goto invalid;
+ }
+
+ if (hd->cabinet != 0 || hd->flags & (PREV_CABINET | NEXT_CABINET)) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Multivolume cabinet file is unsupported");
+ return (ARCHIVE_WARN);
+ }
+ return (ARCHIVE_OK);
+invalid:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid CAB header");
+ return (ARCHIVE_FATAL);
+nomem:
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for CAB data");
+ return (ARCHIVE_FATAL);
+}
+
+static int
+archive_read_format_cab_read_header(struct archive_read *a,
+ struct archive_entry *entry)
+{
+ struct cab *cab;
+ struct cfheader *hd;
+ struct cffolder *prev_folder;
+ struct cffile *file;
+ struct archive_string_conv *sconv;
+ int err = ARCHIVE_OK, r;
+
+ cab = (struct cab *)(a->format->data);
+ if (cab->found_header == 0) {
+ err = cab_read_header(a);
+ if (err < ARCHIVE_WARN)
+ return (err);
+ /* We've found the header. */
+ cab->found_header = 1;
+ }
+ hd = &cab->cfheader;
+
+ if (hd->file_index >= hd->file_count) {
+ cab->end_of_archive = 1;
+ return (ARCHIVE_EOF);
+ }
+ file = &hd->file_array[hd->file_index++];
+
+ cab->end_of_entry = 0;
+ cab->end_of_entry_cleanup = 0;
+ cab->entry_compressed_bytes_read = 0;
+ cab->entry_uncompressed_bytes_read = 0;
+ cab->entry_unconsumed = 0;
+ cab->entry_cffile = file;
+
+ /*
+ * Choose a proper folder.
+ */
+ prev_folder = cab->entry_cffolder;
+ switch (file->folder) {
+ case iFoldCONTINUED_FROM_PREV:
+ case iFoldCONTINUED_PREV_AND_NEXT:
+ cab->entry_cffolder = &hd->folder_array[0];
+ break;
+ case iFoldCONTINUED_TO_NEXT:
+ cab->entry_cffolder = &hd->folder_array[hd->folder_count-1];
+ break;
+ default:
+ cab->entry_cffolder = &hd->folder_array[file->folder];
+ break;
+ }
+ /* If a cffolder of this file is changed, reset a cfdata to read
+ * file contents from next cfdata. */
+ if (prev_folder != cab->entry_cffolder)
+ cab->entry_cfdata = NULL;
+
+ /* If a pathname is UTF-8, prepare a string conversion object
+ * for UTF-8 and use it. */
+ if (file->attr & ATTR_NAME_IS_UTF) {
+ if (cab->sconv_utf8 == NULL) {
+ cab->sconv_utf8 =
+ archive_string_conversion_from_charset(
+ &(a->archive), "UTF-8", 1);
+ if (cab->sconv_utf8 == NULL)
+ return (ARCHIVE_FATAL);
+ }
+ sconv = cab->sconv_utf8;
+ } else if (cab->sconv != NULL) {
+ /* Choose the conversion specified by the option. */
+ sconv = cab->sconv;
+ } else {
+ /* Choose the default conversion. */
+ if (!cab->init_default_conversion) {
+ cab->sconv_default =
+ archive_string_default_conversion_for_read(
+ &(a->archive));
+ cab->init_default_conversion = 1;
+ }
+ sconv = cab->sconv_default;
+ }
+
+ /*
+ * Set a default value and common data
+ */
+ r = cab_convert_path_separator_1(&(file->pathname), file->attr);
+ if (archive_entry_copy_pathname_l(entry, file->pathname.s,
+ archive_strlen(&(file->pathname)), sconv) != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Pathname cannot be converted "
+ "from %s to current locale.",
+ archive_string_conversion_charset_name(sconv));
+ err = ARCHIVE_WARN;
+ }
+ if (r < 0) {
+ /* Convert a path separator '\' -> '/' */
+ cab_convert_path_separator_2(cab, entry);
+ }
+
+ archive_entry_set_size(entry, file->uncompressed_size);
+ if (file->attr & ATTR_RDONLY)
+ archive_entry_set_mode(entry, AE_IFREG | 0555);
+ else
+ archive_entry_set_mode(entry, AE_IFREG | 0777);
+ archive_entry_set_mtime(entry, file->mtime, 0);
+
+ cab->entry_bytes_remaining = file->uncompressed_size;
+ cab->entry_offset = 0;
+ /* We don't need compress data. */
+ if (file->uncompressed_size == 0)
+ cab->end_of_entry_cleanup = cab->end_of_entry = 1;
+
+ /* Set up a more descriptive format name. */
+ sprintf(cab->format_name, "CAB %d.%d (%s)",
+ hd->major, hd->minor, cab->entry_cffolder->compname);
+ a->archive.archive_format_name = cab->format_name;
+
+ return (err);
+}
+
+static int
+archive_read_format_cab_read_data(struct archive_read *a,
+ const void **buff, size_t *size, int64_t *offset)
+{
+ struct cab *cab = (struct cab *)(a->format->data);
+ int r;
+
+ switch (cab->entry_cffile->folder) {
+ case iFoldCONTINUED_FROM_PREV:
+ case iFoldCONTINUED_TO_NEXT:
+ case iFoldCONTINUED_PREV_AND_NEXT:
+ *buff = NULL;
+ *size = 0;
+ *offset = 0;
+ archive_clear_error(&a->archive);
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Cannot restore this file split in multivolume.");
+ return (ARCHIVE_FAILED);
+ default:
+ break;
+ }
+ if (cab->entry_unconsumed) {
+ /* Consume as much as the compressor actually used. */
+ r = cab_consume_cfdata(a, cab->entry_unconsumed);
+ cab->entry_unconsumed = 0;
+ if (r < 0)
+ return (r);
+ }
+ if (cab->end_of_archive || cab->end_of_entry) {
+ if (!cab->end_of_entry_cleanup) {
+ /* End-of-entry cleanup done. */
+ cab->end_of_entry_cleanup = 1;
+ }
+ *offset = cab->entry_offset;
+ *size = 0;
+ *buff = NULL;
+ return (ARCHIVE_EOF);
+ }
+
+ return (cab_read_data(a, buff, size, offset));
+}
+
+static uint32_t
+cab_checksum_cfdata_4(const void *p, size_t bytes, uint32_t seed)
+{
+ const unsigned char *b;
+ int u32num;
+ uint32_t sum;
+
+ u32num = bytes / 4;
+ sum = seed;
+ b = p;
+ while (--u32num >= 0) {
+ sum ^= archive_le32dec(b);
+ b += 4;
+ }
+ return (sum);
+}
+
+static uint32_t
+cab_checksum_cfdata(const void *p, size_t bytes, uint32_t seed)
+{
+ const unsigned char *b;
+ uint32_t sum;
+ uint32_t t;
+
+ sum = cab_checksum_cfdata_4(p, bytes, seed);
+ b = p;
+ b += bytes & ~3;
+ t = 0;
+ switch (bytes & 3) {
+ case 3:
+ t |= ((uint32_t)(*b++)) << 16;
+ /* FALL THROUGH */
+ case 2:
+ t |= ((uint32_t)(*b++)) << 8;
+ /* FALL THROUGH */
+ case 1:
+ t |= *b;
+ /* FALL THROUGH */
+ default:
+ break;
+ }
+ sum ^= t;
+
+ return (sum);
+}
+
+static void
+cab_checksum_update(struct archive_read *a, size_t bytes)
+{
+ struct cab *cab = (struct cab *)(a->format->data);
+ struct cfdata *cfdata = cab->entry_cfdata;
+ const unsigned char *p;
+ size_t sumbytes;
+
+ if (cfdata->sum == 0 || cfdata->sum_ptr == NULL)
+ return;
+ /*
+ * Calculate the sum of this CFDATA.
+ * Make sure CFDATA must be calculated in four bytes.
+ */
+ p = cfdata->sum_ptr;
+ sumbytes = bytes;
+ if (cfdata->sum_extra_avail) {
+ while (cfdata->sum_extra_avail < 4 && sumbytes > 0) {
+ cfdata->sum_extra[
+ cfdata->sum_extra_avail++] = *p++;
+ sumbytes--;
+ }
+ if (cfdata->sum_extra_avail == 4) {
+ cfdata->sum_calculated = cab_checksum_cfdata_4(
+ cfdata->sum_extra, 4, cfdata->sum_calculated);
+ cfdata->sum_extra_avail = 0;
+ }
+ }
+ if (sumbytes) {
+ int odd = sumbytes & 3;
+ if (sumbytes - odd > 0)
+ cfdata->sum_calculated = cab_checksum_cfdata_4(
+ p, sumbytes - odd, cfdata->sum_calculated);
+ if (odd)
+ memcpy(cfdata->sum_extra, p + sumbytes - odd, odd);
+ cfdata->sum_extra_avail = odd;
+ }
+ cfdata->sum_ptr = NULL;
+}
+
+static int
+cab_checksum_finish(struct archive_read *a)
+{
+ struct cab *cab = (struct cab *)(a->format->data);
+ struct cfdata *cfdata = cab->entry_cfdata;
+ int l;
+
+ /* Do not need to compute a sum. */
+ if (cfdata->sum == 0)
+ return (ARCHIVE_OK);
+
+ /*
+ * Calculate the sum of remaining CFDATA.
+ */
+ if (cfdata->sum_extra_avail) {
+ cfdata->sum_calculated =
+ cab_checksum_cfdata(cfdata->sum_extra,
+ cfdata->sum_extra_avail, cfdata->sum_calculated);
+ cfdata->sum_extra_avail = 0;
+ }
+
+ l = 4;
+ if (cab->cfheader.flags & RESERVE_PRESENT)
+ l += cab->cfheader.cfdata;
+ cfdata->sum_calculated = cab_checksum_cfdata(
+ cfdata->memimage + CFDATA_cbData, l, cfdata->sum_calculated);
+ if (cfdata->sum_calculated != cfdata->sum) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Checksum error CFDATA[%d] %x:%x in %d bytes",
+ cab->entry_cffolder->cfdata_index -1,
+ cfdata->sum, cfdata->sum_calculated,
+ cfdata->compressed_size);
+ return (ARCHIVE_FAILED);
+ }
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Read CFDATA if needed.
+ */
+static int
+cab_next_cfdata(struct archive_read *a)
+{
+ struct cab *cab = (struct cab *)(a->format->data);
+ struct cfdata *cfdata = cab->entry_cfdata;
+
+ /* There are remaining bytes in current CFDATA, use it first. */
+ if (cfdata != NULL && cfdata->uncompressed_bytes_remaining > 0)
+ return (ARCHIVE_OK);
+
+ if (cfdata == NULL) {
+ int64_t skip;
+
+ cab->entry_cffolder->cfdata_index = 0;
+
+ /* Seek read pointer to the offset of CFDATA if needed. */
+ skip = cab->entry_cffolder->cfdata_offset_in_cab
+ - cab->cab_offset;
+ if (skip < 0) {
+ int folder_index;
+ switch (cab->entry_cffile->folder) {
+ case iFoldCONTINUED_FROM_PREV:
+ case iFoldCONTINUED_PREV_AND_NEXT:
+ folder_index = 0;
+ break;
+ case iFoldCONTINUED_TO_NEXT:
+ folder_index = cab->cfheader.folder_count-1;
+ break;
+ default:
+ folder_index = cab->entry_cffile->folder;
+ break;
+ }
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Invalid offset of CFDATA in folder(%d) %jd < %jd",
+ folder_index,
+ (intmax_t)cab->entry_cffolder->cfdata_offset_in_cab,
+ (intmax_t)cab->cab_offset);
+ return (ARCHIVE_FATAL);
+ }
+ if (skip > 0) {
+ if (__archive_read_consume(a, skip) < 0)
+ return (ARCHIVE_FATAL);
+ cab->cab_offset =
+ cab->entry_cffolder->cfdata_offset_in_cab;
+ }
+ }
+
+ /*
+ * Read a CFDATA.
+ */
+ if (cab->entry_cffolder->cfdata_index <
+ cab->entry_cffolder->cfdata_count) {
+ const unsigned char *p;
+ int l;
+
+ cfdata = &(cab->entry_cffolder->cfdata);
+ cab->entry_cffolder->cfdata_index++;
+ cab->entry_cfdata = cfdata;
+ cfdata->sum_calculated = 0;
+ cfdata->sum_extra_avail = 0;
+ cfdata->sum_ptr = NULL;
+ l = 8;
+ if (cab->cfheader.flags & RESERVE_PRESENT)
+ l += cab->cfheader.cfdata;
+ if ((p = __archive_read_ahead(a, l, NULL)) == NULL)
+ return (truncated_error(a));
+ cfdata->sum = archive_le32dec(p + CFDATA_csum);
+ cfdata->compressed_size = archive_le16dec(p + CFDATA_cbData);
+ cfdata->compressed_bytes_remaining = cfdata->compressed_size;
+ cfdata->uncompressed_size =
+ archive_le16dec(p + CFDATA_cbUncomp);
+ cfdata->uncompressed_bytes_remaining =
+ cfdata->uncompressed_size;
+ cfdata->uncompressed_avail = 0;
+ cfdata->read_offset = 0;
+ cfdata->unconsumed = 0;
+
+ /*
+ * Sanity check if data size is acceptable.
+ */
+ if (cfdata->compressed_size == 0 ||
+ cfdata->compressed_size > (0x8000+6144))
+ goto invalid;
+ if (cfdata->uncompressed_size > 0x8000)
+ goto invalid;
+ if (cfdata->uncompressed_size == 0) {
+ switch (cab->entry_cffile->folder) {
+ case iFoldCONTINUED_PREV_AND_NEXT:
+ case iFoldCONTINUED_TO_NEXT:
+ break;
+ case iFoldCONTINUED_FROM_PREV:
+ default:
+ goto invalid;
+ }
+ }
+ /* If CFDATA is not last in a folder, an uncompressed
+ * size must be 0x8000(32KBi) */
+ if ((cab->entry_cffolder->cfdata_index <
+ cab->entry_cffolder->cfdata_count) &&
+ cfdata->uncompressed_size != 0x8000)
+ goto invalid;
+
+ /* A compressed data size and an uncompressed data size must
+ * be the same in no compression mode. */
+ if (cab->entry_cffolder->comptype == COMPTYPE_NONE &&
+ cfdata->compressed_size != cfdata->uncompressed_size)
+ goto invalid;
+
+ /*
+ * Save CFDATA image for sum check.
+ */
+ if (cfdata->memimage_size < (size_t)l) {
+ free(cfdata->memimage);
+ cfdata->memimage = malloc(l);
+ if (cfdata->memimage == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for CAB data");
+ return (ARCHIVE_FATAL);
+ }
+ cfdata->memimage_size = l;
+ }
+ memcpy(cfdata->memimage, p, l);
+
+ /* Consume bytes as much as we used. */
+ __archive_read_consume(a, l);
+ cab->cab_offset += l;
+ } else if (cab->entry_cffolder->cfdata_count > 0) {
+ /* Run out of all CFDATA in a folder. */
+ cfdata->compressed_size = 0;
+ cfdata->uncompressed_size = 0;
+ cfdata->compressed_bytes_remaining = 0;
+ cfdata->uncompressed_bytes_remaining = 0;
+ } else {
+ /* Current folder does not have any CFDATA. */
+ cfdata = &(cab->entry_cffolder->cfdata);
+ cab->entry_cfdata = cfdata;
+ memset(cfdata, 0, sizeof(*cfdata));
+ }
+ return (ARCHIVE_OK);
+invalid:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid CFDATA");
+ return (ARCHIVE_FATAL);
+}
+
+/*
+ * Read ahead CFDATA.
+ */
+static const void *
+cab_read_ahead_cfdata(struct archive_read *a, ssize_t *avail)
+{
+ struct cab *cab = (struct cab *)(a->format->data);
+ int err;
+
+ err = cab_next_cfdata(a);
+ if (err < ARCHIVE_OK) {
+ *avail = err;
+ return (NULL);
+ }
+
+ switch (cab->entry_cffolder->comptype) {
+ case COMPTYPE_NONE:
+ return (cab_read_ahead_cfdata_none(a, avail));
+ case COMPTYPE_MSZIP:
+ return (cab_read_ahead_cfdata_deflate(a, avail));
+ case COMPTYPE_LZX:
+ return (cab_read_ahead_cfdata_lzx(a, avail));
+ default: /* Unsupported compression. */
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Unsupported CAB compression : %s",
+ cab->entry_cffolder->compname);
+ *avail = ARCHIVE_FAILED;
+ return (NULL);
+ }
+}
+
+/*
+ * Read ahead CFDATA as uncompressed data.
+ */
+static const void *
+cab_read_ahead_cfdata_none(struct archive_read *a, ssize_t *avail)
+{
+ struct cab *cab = (struct cab *)(a->format->data);
+ struct cfdata *cfdata;
+ const void *d;
+ int64_t skipped_bytes;
+
+ cfdata = cab->entry_cfdata;
+
+ if (cfdata->uncompressed_avail == 0 &&
+ cfdata->read_offset > 0) {
+ /* we've already skipped some bytes before really read. */
+ skipped_bytes = cfdata->read_offset;
+ cfdata->read_offset = 0;
+ cfdata->uncompressed_bytes_remaining += skipped_bytes;
+ } else
+ skipped_bytes = 0;
+ do {
+ /*
+ * Note: '1' here is a performance optimization.
+ * Recall that the decompression layer returns a count of
+ * available bytes; asking for more than that forces the
+ * decompressor to combine reads by copying data.
+ */
+ d = __archive_read_ahead(a, 1, avail);
+ if (*avail <= 0) {
+ *avail = truncated_error(a);
+ return (NULL);
+ }
+ if (*avail > cfdata->uncompressed_bytes_remaining)
+ *avail = cfdata->uncompressed_bytes_remaining;
+ cfdata->uncompressed_avail = cfdata->uncompressed_size;
+ cfdata->unconsumed = *avail;
+ cfdata->sum_ptr = d;
+ if (skipped_bytes > 0) {
+ skipped_bytes =
+ cab_minimum_consume_cfdata(a, skipped_bytes);
+ if (skipped_bytes < 0) {
+ *avail = ARCHIVE_FATAL;
+ return (NULL);
+ }
+ continue;
+ }
+ } while (0);
+
+ return (d);
+}
+
+/*
+ * Read ahead CFDATA as deflate data.
+ */
+#ifdef HAVE_ZLIB_H
+static const void *
+cab_read_ahead_cfdata_deflate(struct archive_read *a, ssize_t *avail)
+{
+ struct cab *cab = (struct cab *)(a->format->data);
+ struct cfdata *cfdata;
+ const void *d;
+ int r, mszip;
+ uint16_t uavail;
+ char eod = 0;
+
+ cfdata = cab->entry_cfdata;
+ /* If the buffer hasn't been allocated, allocate it now. */
+ if (cab->uncompressed_buffer == NULL) {
+ cab->uncompressed_buffer_size = 0x8000;
+ cab->uncompressed_buffer
+ = (unsigned char *)malloc(cab->uncompressed_buffer_size);
+ if (cab->uncompressed_buffer == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory for CAB reader");
+ *avail = ARCHIVE_FATAL;
+ return (NULL);
+ }
+ }
+
+ uavail = cfdata->uncompressed_avail;
+ if (uavail == cfdata->uncompressed_size) {
+ d = cab->uncompressed_buffer + cfdata->read_offset;
+ *avail = uavail - cfdata->read_offset;
+ return (d);
+ }
+
+ if (!cab->entry_cffolder->decompress_init) {
+ cab->stream.next_in = NULL;
+ cab->stream.avail_in = 0;
+ cab->stream.total_in = 0;
+ cab->stream.next_out = NULL;
+ cab->stream.avail_out = 0;
+ cab->stream.total_out = 0;
+ if (cab->stream_valid)
+ r = inflateReset(&cab->stream);
+ else
+ r = inflateInit2(&cab->stream,
+ -15 /* Don't check for zlib header */);
+ if (r != Z_OK) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Can't initialize deflate decompression.");
+ *avail = ARCHIVE_FATAL;
+ return (NULL);
+ }
+ /* Stream structure has been set up. */
+ cab->stream_valid = 1;
+ /* We've initialized decompression for this stream. */
+ cab->entry_cffolder->decompress_init = 1;
+ }
+
+ if (cfdata->compressed_bytes_remaining == cfdata->compressed_size)
+ mszip = 2;
+ else
+ mszip = 0;
+ eod = 0;
+ cab->stream.total_out = uavail;
+ /*
+ * We always uncompress all data in current CFDATA.
+ */
+ while (!eod && cab->stream.total_out < cfdata->uncompressed_size) {
+ ssize_t bytes_avail;
+
+ cab->stream.next_out =
+ cab->uncompressed_buffer + cab->stream.total_out;
+ cab->stream.avail_out =
+ cfdata->uncompressed_size - cab->stream.total_out;
+
+ d = __archive_read_ahead(a, 1, &bytes_avail);
+ if (bytes_avail <= 0) {
+ *avail = truncated_error(a);
+ return (NULL);
+ }
+ if (bytes_avail > cfdata->compressed_bytes_remaining)
+ bytes_avail = cfdata->compressed_bytes_remaining;
+ /*
+ * A bug in zlib.h: stream.next_in should be marked 'const'
+ * but isn't (the library never alters data through the
+ * next_in pointer, only reads it). The result: this ugly
+ * cast to remove 'const'.
+ */
+ cab->stream.next_in = (Bytef *)(uintptr_t)d;
+ cab->stream.avail_in = bytes_avail;
+ cab->stream.total_in = 0;
+
+ /* Cut out a tow-byte MSZIP signature(0x43, 0x4b). */
+ if (mszip > 0) {
+ if (bytes_avail <= mszip) {
+ if (mszip == 2) {
+ if (cab->stream.next_in[0] != 0x43)
+ goto nomszip;
+ if (bytes_avail > 1 &&
+ cab->stream.next_in[1] != 0x4b)
+ goto nomszip;
+ } else if (cab->stream.next_in[0] != 0x4b)
+ goto nomszip;
+ cfdata->unconsumed = bytes_avail;
+ cfdata->sum_ptr = d;
+ if (cab_minimum_consume_cfdata(
+ a, cfdata->unconsumed) < 0) {
+ *avail = ARCHIVE_FATAL;
+ return (NULL);
+ }
+ mszip -= bytes_avail;
+ continue;
+ }
+ if (mszip == 1 && cab->stream.next_in[0] != 0x4b)
+ goto nomszip;
+ else if (cab->stream.next_in[0] != 0x43 ||
+ cab->stream.next_in[1] != 0x4b)
+ goto nomszip;
+ cab->stream.next_in += mszip;
+ cab->stream.avail_in -= mszip;
+ cab->stream.total_in += mszip;
+ mszip = 0;
+ }
+
+ r = inflate(&cab->stream, 0);
+ switch (r) {
+ case Z_OK:
+ break;
+ case Z_STREAM_END:
+ eod = 1;
+ break;
+ default:
+ goto zlibfailed;
+ }
+ cfdata->unconsumed = cab->stream.total_in;
+ cfdata->sum_ptr = d;
+ if (cab_minimum_consume_cfdata(a, cfdata->unconsumed) < 0) {
+ *avail = ARCHIVE_FATAL;
+ return (NULL);
+ }
+ }
+ uavail = cab->stream.total_out;
+
+ if (uavail < cfdata->uncompressed_size) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Invalid uncompressed size (%d < %d)",
+ uavail, cfdata->uncompressed_size);
+ *avail = ARCHIVE_FATAL;
+ return (NULL);
+ }
+
+ /*
+ * Note: I suspect there is a bug in makecab.exe because, in rare
+ * case, compressed bytes are still remaining regardless we have
+ * gotten all uncompressed bytes, which size is recoded in CFDATA,
+ * as much as we need, and we have to use the garbage so as to
+ * correctly compute the sum of CFDATA accordingly.
+ */
+ if (cfdata->compressed_bytes_remaining > 0) {
+ ssize_t bytes_avail;
+
+ d = __archive_read_ahead(a, cfdata->compressed_bytes_remaining,
+ &bytes_avail);
+ if (bytes_avail <= 0) {
+ *avail = truncated_error(a);
+ return (NULL);
+ }
+ cfdata->unconsumed = cfdata->compressed_bytes_remaining;
+ cfdata->sum_ptr = d;
+ if (cab_minimum_consume_cfdata(a, cfdata->unconsumed) < 0) {
+ *avail = ARCHIVE_FATAL;
+ return (NULL);
+ }
+ }
+
+ /*
+ * Set dictionary data for decompressing of next CFDATA, which
+ * in the same folder. This is why we always do decompress CFDATA
+ * even if beginning CFDATA or some of CFDATA are not used in
+ * skipping file data.
+ */
+ if (cab->entry_cffolder->cfdata_index <
+ cab->entry_cffolder->cfdata_count) {
+ r = inflateReset(&cab->stream);
+ if (r != Z_OK)
+ goto zlibfailed;
+ r = inflateSetDictionary(&cab->stream,
+ cab->uncompressed_buffer, cfdata->uncompressed_size);
+ if (r != Z_OK)
+ goto zlibfailed;
+ }
+
+ d = cab->uncompressed_buffer + cfdata->read_offset;
+ *avail = uavail - cfdata->read_offset;
+ cfdata->uncompressed_avail = uavail;
+
+ return (d);
+
+zlibfailed:
+ switch (r) {
+ case Z_MEM_ERROR:
+ archive_set_error(&a->archive, ENOMEM,
+ "Out of memory for deflate decompression");
+ break;
+ default:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Deflate decompression failed (%d)", r);
+ break;
+ }
+ *avail = ARCHIVE_FATAL;
+ return (NULL);
+nomszip:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "CFDATA incorrect(no MSZIP signature)");
+ *avail = ARCHIVE_FATAL;
+ return (NULL);
+}
+
+#else /* HAVE_ZLIB_H */
+
+static const void *
+cab_read_ahead_cfdata_deflate(struct archive_read *a, ssize_t *avail)
+{
+ *avail = ARCHIVE_FATAL;
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "libarchive compiled without deflate support (no libz)");
+ return (NULL);
+}
+
+#endif /* HAVE_ZLIB_H */
+
+static const void *
+cab_read_ahead_cfdata_lzx(struct archive_read *a, ssize_t *avail)
+{
+ struct cab *cab = (struct cab *)(a->format->data);
+ struct cfdata *cfdata;
+ const void *d;
+ int r;
+ uint16_t uavail;
+
+ cfdata = cab->entry_cfdata;
+ /* If the buffer hasn't been allocated, allocate it now. */
+ if (cab->uncompressed_buffer == NULL) {
+ cab->uncompressed_buffer_size = 0x8000;
+ cab->uncompressed_buffer
+ = (unsigned char *)malloc(cab->uncompressed_buffer_size);
+ if (cab->uncompressed_buffer == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory for CAB reader");
+ *avail = ARCHIVE_FATAL;
+ return (NULL);
+ }
+ }
+
+ uavail = cfdata->uncompressed_avail;
+ if (uavail == cfdata->uncompressed_size) {
+ d = cab->uncompressed_buffer + cfdata->read_offset;
+ *avail = uavail - cfdata->read_offset;
+ return (d);
+ }
+
+ if (!cab->entry_cffolder->decompress_init) {
+ r = lzx_decode_init(&cab->xstrm,
+ cab->entry_cffolder->compdata);
+ if (r != ARCHIVE_OK) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Can't initialize LZX decompression.");
+ *avail = ARCHIVE_FATAL;
+ return (NULL);
+ }
+ /* We've initialized decompression for this stream. */
+ cab->entry_cffolder->decompress_init = 1;
+ }
+
+ /* Clean up remaining bits of previous CFDATA. */
+ lzx_cleanup_bitstream(&cab->xstrm);
+ cab->xstrm.total_out = uavail;
+ while (cab->xstrm.total_out < cfdata->uncompressed_size) {
+ ssize_t bytes_avail;
+
+ cab->xstrm.next_out =
+ cab->uncompressed_buffer + cab->xstrm.total_out;
+ cab->xstrm.avail_out =
+ cfdata->uncompressed_size - cab->xstrm.total_out;
+
+ d = __archive_read_ahead(a, 1, &bytes_avail);
+ if (bytes_avail <= 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated CAB file data");
+ *avail = ARCHIVE_FATAL;
+ return (NULL);
+ }
+ if (bytes_avail > cfdata->compressed_bytes_remaining)
+ bytes_avail = cfdata->compressed_bytes_remaining;
+
+ cab->xstrm.next_in = d;
+ cab->xstrm.avail_in = bytes_avail;
+ cab->xstrm.total_in = 0;
+ r = lzx_decode(&cab->xstrm,
+ cfdata->compressed_bytes_remaining == bytes_avail);
+ switch (r) {
+ case ARCHIVE_OK:
+ case ARCHIVE_EOF:
+ break;
+ default:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "LZX decompression failed (%d)", r);
+ *avail = ARCHIVE_FATAL;
+ return (NULL);
+ }
+ cfdata->unconsumed = cab->xstrm.total_in;
+ cfdata->sum_ptr = d;
+ if (cab_minimum_consume_cfdata(a, cfdata->unconsumed) < 0) {
+ *avail = ARCHIVE_FATAL;
+ return (NULL);
+ }
+ }
+
+ uavail = cab->xstrm.total_out;
+ /*
+ * Make sure a read pointer advances to next CFDATA.
+ */
+ if (cfdata->compressed_bytes_remaining > 0) {
+ ssize_t bytes_avail;
+
+ d = __archive_read_ahead(a, cfdata->compressed_bytes_remaining,
+ &bytes_avail);
+ if (bytes_avail <= 0) {
+ *avail = truncated_error(a);
+ return (NULL);
+ }
+ cfdata->unconsumed = cfdata->compressed_bytes_remaining;
+ cfdata->sum_ptr = d;
+ if (cab_minimum_consume_cfdata(a, cfdata->unconsumed) < 0) {
+ *avail = ARCHIVE_FATAL;
+ return (NULL);
+ }
+ }
+
+ /*
+ * Translation reversal of x86 proccessor CALL byte sequence(E8).
+ */
+ lzx_translation(&cab->xstrm, cab->uncompressed_buffer,
+ cfdata->uncompressed_size,
+ (cab->entry_cffolder->cfdata_index-1) * 0x8000);
+
+ d = cab->uncompressed_buffer + cfdata->read_offset;
+ *avail = uavail - cfdata->read_offset;
+ cfdata->uncompressed_avail = uavail;
+
+ return (d);
+}
+
+/*
+ * Consume CFDATA.
+ * We always decompress CFDATA to consume CFDATA as much as we need
+ * in uncompressed bytes because all CFDATA in a folder are related
+ * so we do not skip any CFDATA without decompressing.
+ * Note: If the folder of a CFFILE is iFoldCONTINUED_PREV_AND_NEXT or
+ * iFoldCONTINUED_FROM_PREV, we won't decompress because a CFDATA for
+ * the CFFILE is remaining bytes of previous Multivolume CAB file.
+ */
+static int64_t
+cab_consume_cfdata(struct archive_read *a, int64_t consumed_bytes)
+{
+ struct cab *cab = (struct cab *)(a->format->data);
+ struct cfdata *cfdata;
+ int64_t cbytes, rbytes;
+ int err;
+
+ rbytes = cab_minimum_consume_cfdata(a, consumed_bytes);
+ if (rbytes < 0)
+ return (ARCHIVE_FATAL);
+
+ cfdata = cab->entry_cfdata;
+ while (rbytes > 0) {
+ ssize_t avail;
+
+ if (cfdata->compressed_size == 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid CFDATA");
+ return (ARCHIVE_FATAL);
+ }
+ cbytes = cfdata->uncompressed_bytes_remaining;
+ if (cbytes > rbytes)
+ cbytes = rbytes;
+ rbytes -= cbytes;
+
+ if (cfdata->uncompressed_avail == 0 &&
+ (cab->entry_cffolder->comptype == COMPTYPE_NONE ||
+ cab->entry_cffile->folder == iFoldCONTINUED_PREV_AND_NEXT ||
+ cab->entry_cffile->folder == iFoldCONTINUED_FROM_PREV)) {
+ /* We have not read any data yet. */
+ if (cbytes == cfdata->uncompressed_bytes_remaining) {
+ /* Skip whole current CFDATA. */
+ __archive_read_consume(a,
+ cfdata->compressed_size);
+ cab->cab_offset += cfdata->compressed_size;
+ cfdata->compressed_bytes_remaining = 0;
+ cfdata->uncompressed_bytes_remaining = 0;
+ err = cab_next_cfdata(a);
+ if (err < 0)
+ return (err);
+ cfdata = cab->entry_cfdata;
+ if (cfdata->uncompressed_size == 0) {
+ switch (cab->entry_cffile->folder) {
+ case iFoldCONTINUED_PREV_AND_NEXT:
+ case iFoldCONTINUED_TO_NEXT:
+ case iFoldCONTINUED_FROM_PREV:
+ rbytes = 0;
+ break;
+ default:
+ break;
+ }
+ }
+ continue;
+ }
+ cfdata->read_offset += cbytes;
+ cfdata->uncompressed_bytes_remaining -= cbytes;
+ break;
+ } else if (cbytes == 0) {
+ err = cab_next_cfdata(a);
+ if (err < 0)
+ return (err);
+ cfdata = cab->entry_cfdata;
+ if (cfdata->uncompressed_size == 0) {
+ switch (cab->entry_cffile->folder) {
+ case iFoldCONTINUED_PREV_AND_NEXT:
+ case iFoldCONTINUED_TO_NEXT:
+ case iFoldCONTINUED_FROM_PREV:
+ return (ARCHIVE_FATAL);
+ default:
+ break;
+ }
+ }
+ continue;
+ }
+ while (cbytes > 0) {
+ (void)cab_read_ahead_cfdata(a, &avail);
+ if (avail <= 0)
+ return (ARCHIVE_FATAL);
+ if (avail > cbytes)
+ avail = cbytes;
+ if (cab_minimum_consume_cfdata(a, avail) < 0)
+ return (ARCHIVE_FATAL);
+ cbytes -= avail;
+ }
+ }
+ return (consumed_bytes);
+}
+
+/*
+ * Consume CFDATA as much as we have already gotten and
+ * compute the sum of CFDATA.
+ */
+static int64_t
+cab_minimum_consume_cfdata(struct archive_read *a, int64_t consumed_bytes)
+{
+ struct cab *cab = (struct cab *)(a->format->data);
+ struct cfdata *cfdata;
+ int64_t cbytes, rbytes;
+ int err;
+
+ cfdata = cab->entry_cfdata;
+ rbytes = consumed_bytes;
+ if (cab->entry_cffolder->comptype == COMPTYPE_NONE) {
+ if (consumed_bytes < cfdata->unconsumed)
+ cbytes = consumed_bytes;
+ else
+ cbytes = cfdata->unconsumed;
+ rbytes -= cbytes;
+ cfdata->read_offset += cbytes;
+ cfdata->uncompressed_bytes_remaining -= cbytes;
+ cfdata->unconsumed -= cbytes;
+ } else {
+ cbytes = cfdata->uncompressed_avail - cfdata->read_offset;
+ if (cbytes > 0) {
+ if (consumed_bytes < cbytes)
+ cbytes = consumed_bytes;
+ rbytes -= cbytes;
+ cfdata->read_offset += cbytes;
+ cfdata->uncompressed_bytes_remaining -= cbytes;
+ }
+
+ if (cfdata->unconsumed) {
+ cbytes = cfdata->unconsumed;
+ cfdata->unconsumed = 0;
+ } else
+ cbytes = 0;
+ }
+ if (cbytes) {
+ /* Compute the sum. */
+ cab_checksum_update(a, cbytes);
+
+ /* Consume as much as the compressor actually used. */
+ __archive_read_consume(a, cbytes);
+ cab->cab_offset += cbytes;
+ cfdata->compressed_bytes_remaining -= cbytes;
+ if (cfdata->compressed_bytes_remaining == 0) {
+ err = cab_checksum_finish(a);
+ if (err < 0)
+ return (err);
+ }
+ }
+ return (rbytes);
+}
+
+/*
+ * Returns ARCHIVE_OK if successful, ARCHIVE_FATAL otherwise, sets
+ * cab->end_of_entry if it consumes all of the data.
+ */
+static int
+cab_read_data(struct archive_read *a, const void **buff,
+ size_t *size, int64_t *offset)
+{
+ struct cab *cab = (struct cab *)(a->format->data);
+ ssize_t bytes_avail;
+
+ if (cab->entry_bytes_remaining == 0) {
+ *buff = NULL;
+ *size = 0;
+ *offset = cab->entry_offset;
+ cab->end_of_entry = 1;
+ return (ARCHIVE_OK);
+ }
+
+ *buff = cab_read_ahead_cfdata(a, &bytes_avail);
+ if (bytes_avail <= 0) {
+ *buff = NULL;
+ *size = 0;
+ *offset = 0;
+ if (bytes_avail == 0 &&
+ cab->entry_cfdata->uncompressed_size == 0) {
+ /* All of CFDATA in a folder has been handled. */
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT, "Invalid CFDATA");
+ return (ARCHIVE_FATAL);
+ } else
+ return (bytes_avail);
+ }
+ if (bytes_avail > cab->entry_bytes_remaining)
+ bytes_avail = cab->entry_bytes_remaining;
+
+ *size = bytes_avail;
+ *offset = cab->entry_offset;
+ cab->entry_offset += bytes_avail;
+ cab->entry_bytes_remaining -= bytes_avail;
+ if (cab->entry_bytes_remaining == 0)
+ cab->end_of_entry = 1;
+ cab->entry_unconsumed = bytes_avail;
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_read_format_cab_read_data_skip(struct archive_read *a)
+{
+ struct cab *cab;
+ int64_t bytes_skipped;
+ int r;
+
+ cab = (struct cab *)(a->format->data);
+
+ if (cab->end_of_archive)
+ return (ARCHIVE_EOF);
+
+ if (cab->entry_unconsumed) {
+ /* Consume as much as the compressor actually used. */
+ r = cab_consume_cfdata(a, cab->entry_unconsumed);
+ cab->entry_unconsumed = 0;
+ if (r < 0)
+ return (r);
+ } else if (cab->entry_cfdata == NULL) {
+ r = cab_next_cfdata(a);
+ if (r < 0)
+ return (r);
+ }
+
+ /* if we've already read to end of data, we're done. */
+ if (cab->end_of_entry_cleanup)
+ return (ARCHIVE_OK);
+
+ /*
+ * If the length is at the beginning, we can skip the
+ * compressed data much more quickly.
+ */
+ bytes_skipped = cab_consume_cfdata(a, cab->entry_bytes_remaining);
+ if (bytes_skipped < 0)
+ return (ARCHIVE_FATAL);
+
+ /* This entry is finished and done. */
+ cab->end_of_entry_cleanup = cab->end_of_entry = 1;
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_read_format_cab_cleanup(struct archive_read *a)
+{
+ struct cab *cab = (struct cab *)(a->format->data);
+ struct cfheader *hd = &cab->cfheader;
+ int i;
+
+ if (hd->folder_array != NULL) {
+ for (i = 0; i < hd->folder_count; i++)
+ free(hd->folder_array[i].cfdata.memimage);
+ free(hd->folder_array);
+ }
+ if (hd->file_array != NULL) {
+ for (i = 0; i < cab->cfheader.file_count; i++)
+ archive_string_free(&(hd->file_array[i].pathname));
+ free(hd->file_array);
+ }
+#ifdef HAVE_ZLIB_H
+ if (cab->stream_valid)
+ inflateEnd(&cab->stream);
+#endif
+ lzx_decode_free(&cab->xstrm);
+ archive_wstring_free(&cab->ws);
+ free(cab->uncompressed_buffer);
+ free(cab);
+ (a->format->data) = NULL;
+ return (ARCHIVE_OK);
+}
+
+/* Convert an MSDOS-style date/time into Unix-style time. */
+static time_t
+cab_dos_time(const unsigned char *p)
+{
+ int msTime, msDate;
+ struct tm ts;
+
+ msDate = archive_le16dec(p);
+ msTime = archive_le16dec(p+2);
+
+ memset(&ts, 0, sizeof(ts));
+ ts.tm_year = ((msDate >> 9) & 0x7f) + 80; /* Years since 1900. */
+ ts.tm_mon = ((msDate >> 5) & 0x0f) - 1; /* Month number. */
+ ts.tm_mday = msDate & 0x1f; /* Day of month. */
+ ts.tm_hour = (msTime >> 11) & 0x1f;
+ ts.tm_min = (msTime >> 5) & 0x3f;
+ ts.tm_sec = (msTime << 1) & 0x3e;
+ ts.tm_isdst = -1;
+ return (mktime(&ts));
+}
+
+/*****************************************************************
+ *
+ * LZX decompression code.
+ *
+ *****************************************************************/
+
+/*
+ * Initialize LZX decoder.
+ *
+ * Returns ARCHIVE_OK if initialization was successful.
+ * Returns ARCHIVE_FAILED if w_bits has unsupported value.
+ * Returns ARCHIVE_FATAL if initialization failed; memory allocation
+ * error occurred.
+ */
+static int
+lzx_decode_init(struct lzx_stream *strm, int w_bits)
+{
+ struct lzx_dec *ds;
+ int slot, w_size, w_slot;
+ int base, footer;
+
+ if (strm->ds == NULL) {
+ strm->ds = calloc(1, sizeof(*strm->ds));
+ if (strm->ds == NULL)
+ return (ARCHIVE_FATAL);
+ }
+ ds = strm->ds;
+ ds->error = ARCHIVE_FAILED;
+
+ /* Allow bits from 15(32KBi) up to 21(2MBi) */
+ if (w_bits < SLOT_BASE || w_bits > SLOT_MAX)
+ return (ARCHIVE_FAILED);
+
+ ds->error = ARCHIVE_FATAL;
+
+ /*
+ * Alloc window
+ */
+ w_size = ds->w_size;
+ w_slot = slots[w_bits - SLOT_BASE];
+ ds->w_size = 1U << w_bits;
+ ds->w_mask = ds->w_size -1;
+ if (ds->w_buff == NULL || w_size != ds->w_size) {
+ free(ds->w_buff);
+ ds->w_buff = malloc(ds->w_size);
+ if (ds->w_buff == NULL)
+ return (ARCHIVE_FATAL);
+ free(ds->pos_tbl);
+ ds->pos_tbl = malloc(sizeof(ds->pos_tbl[0]) * w_slot);
+ if (ds->pos_tbl == NULL)
+ return (ARCHIVE_FATAL);
+ lzx_huffman_free(&(ds->mt));
+ }
+
+ base = footer = 0;
+ for (slot = 0; slot < w_slot; slot++) {
+ int n;
+ if (footer == 0)
+ base = slot;
+ else
+ base += 1 << footer;
+ if (footer < 17) {
+ footer = -2;
+ for (n = base; n; n >>= 1)
+ footer++;
+ if (footer <= 0)
+ footer = 0;
+ }
+ ds->pos_tbl[slot].base = base;
+ ds->pos_tbl[slot].footer_bits = footer;
+ }
+
+ ds->w_pos = 0;
+ ds->state = 0;
+ ds->br.cache_buffer = 0;
+ ds->br.cache_avail = 0;
+ ds->r0 = ds->r1 = ds->r2 = 1;
+
+ /* Initialize aligned offset tree. */
+ if (lzx_huffman_init(&(ds->at), 8, 8) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /* Initialize pre-tree. */
+ if (lzx_huffman_init(&(ds->pt), 20, 10) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /* Initialize Main tree. */
+ if (lzx_huffman_init(&(ds->mt), 256+(w_slot<<3), 16)
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /* Initialize Length tree. */
+ if (lzx_huffman_init(&(ds->lt), 249, 16) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ ds->error = 0;
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Release LZX decoder.
+ */
+static void
+lzx_decode_free(struct lzx_stream *strm)
+{
+
+ if (strm->ds == NULL)
+ return;
+ free(strm->ds->w_buff);
+ free(strm->ds->pos_tbl);
+ lzx_huffman_free(&(strm->ds->at));
+ lzx_huffman_free(&(strm->ds->pt));
+ lzx_huffman_free(&(strm->ds->mt));
+ lzx_huffman_free(&(strm->ds->lt));
+ free(strm->ds);
+ strm->ds = NULL;
+}
+
+/*
+ * E8 Call Translation reversal.
+ */
+static void
+lzx_translation(struct lzx_stream *strm, void *p, size_t size, uint32_t offset)
+{
+ struct lzx_dec *ds = strm->ds;
+ unsigned char *b, *end;
+
+ if (!ds->translation || size <= 10)
+ return;
+ b = p;
+ end = b + size - 10;
+ while (b < end && (b = memchr(b, 0xE8, end - b)) != NULL) {
+ size_t i = b - (unsigned char *)p;
+ long cp, displacement, value;
+
+ cp = offset + i;
+ value = archive_le32dec(&b[1]);
+ if (value >= -cp && value < (long)ds->translation_size) {
+ if (value >= 0)
+ displacement = value - cp;
+ else
+ displacement = value + ds->translation_size;
+ archive_le32enc(&b[1], (uint32_t)displacement);
+ }
+ b += 5;
+ }
+}
+
+/*
+ * Bit stream reader.
+ */
+/* Check that the cache buffer has enough bits. */
+#define lzx_br_has(br, n) ((br)->cache_avail >= n)
+/* Get compressed data by bit. */
+#define lzx_br_bits(br, n) \
+ (((uint32_t)((br)->cache_buffer >> \
+ ((br)->cache_avail - (n)))) & cache_masks[n])
+#define lzx_br_bits_forced(br, n) \
+ (((uint32_t)((br)->cache_buffer << \
+ ((n) - (br)->cache_avail))) & cache_masks[n])
+/* Read ahead to make sure the cache buffer has enough compressed data we
+ * will use.
+ * True : completed, there is enough data in the cache buffer.
+ * False : we met that strm->next_in is empty, we have to get following
+ * bytes. */
+#define lzx_br_read_ahead_0(strm, br, n) \
+ (lzx_br_has((br), (n)) || lzx_br_fillup(strm, br))
+/* True : the cache buffer has some bits as much as we need.
+ * False : there are no enough bits in the cache buffer to be used,
+ * we have to get following bytes if we could. */
+#define lzx_br_read_ahead(strm, br, n) \
+ (lzx_br_read_ahead_0((strm), (br), (n)) || lzx_br_has((br), (n)))
+
+/* Notify how many bits we consumed. */
+#define lzx_br_consume(br, n) ((br)->cache_avail -= (n))
+#define lzx_br_consume_unalined_bits(br) ((br)->cache_avail &= ~0x0f)
+
+static const uint32_t cache_masks[] = {
+ 0x00000000, 0x00000001, 0x00000003, 0x00000007,
+ 0x0000000F, 0x0000001F, 0x0000003F, 0x0000007F,
+ 0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF,
+ 0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF,
+ 0x0000FFFF, 0x0001FFFF, 0x0003FFFF, 0x0007FFFF,
+ 0x000FFFFF, 0x001FFFFF, 0x003FFFFF, 0x007FFFFF,
+ 0x00FFFFFF, 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF,
+ 0x0FFFFFFF, 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
+};
+
+/*
+ * Shift away used bits in the cache data and fill it up with following bits.
+ * Call this when cache buffer does not have enough bits you need.
+ *
+ * Returns 1 if the cache buffer is full.
+ * Returns 0 if the cache buffer is not full; input buffer is empty.
+ */
+static int
+lzx_br_fillup(struct lzx_stream *strm, struct lzx_br *br)
+{
+/*
+ * x86 proccessor family can read misaligned data without an access error.
+ */
+ int n = CACHE_BITS - br->cache_avail;
+
+ for (;;) {
+ switch (n >> 4) {
+ case 4:
+ if (strm->avail_in >= 8) {
+ br->cache_buffer =
+ ((uint64_t)strm->next_in[1]) << 56 |
+ ((uint64_t)strm->next_in[0]) << 48 |
+ ((uint64_t)strm->next_in[3]) << 40 |
+ ((uint64_t)strm->next_in[2]) << 32 |
+ ((uint32_t)strm->next_in[5]) << 24 |
+ ((uint32_t)strm->next_in[4]) << 16 |
+ ((uint32_t)strm->next_in[7]) << 8 |
+ (uint32_t)strm->next_in[6];
+ strm->next_in += 8;
+ strm->avail_in -= 8;
+ br->cache_avail += 8 * 8;
+ return (1);
+ }
+ break;
+ case 3:
+ if (strm->avail_in >= 6) {
+ br->cache_buffer =
+ (br->cache_buffer << 48) |
+ ((uint64_t)strm->next_in[1]) << 40 |
+ ((uint64_t)strm->next_in[0]) << 32 |
+ ((uint32_t)strm->next_in[3]) << 24 |
+ ((uint32_t)strm->next_in[2]) << 16 |
+ ((uint32_t)strm->next_in[5]) << 8 |
+ (uint32_t)strm->next_in[4];
+ strm->next_in += 6;
+ strm->avail_in -= 6;
+ br->cache_avail += 6 * 8;
+ return (1);
+ }
+ break;
+ case 0:
+ /* We have enough compressed data in
+ * the cache buffer.*/
+ return (1);
+ default:
+ break;
+ }
+ if (strm->avail_in < 2) {
+ /* There is not enough compressed data to
+ * fill up the cache buffer. */
+ if (strm->avail_in == 1) {
+ br->odd = *strm->next_in++;
+ strm->avail_in--;
+ br->have_odd = 1;
+ }
+ return (0);
+ }
+ br->cache_buffer =
+ (br->cache_buffer << 16) |
+ archive_le16dec(strm->next_in);
+ strm->next_in += 2;
+ strm->avail_in -= 2;
+ br->cache_avail += 16;
+ n -= 16;
+ }
+}
+
+static void
+lzx_br_fixup(struct lzx_stream *strm, struct lzx_br *br)
+{
+ int n = CACHE_BITS - br->cache_avail;
+
+ if (br->have_odd && n >= 16 && strm->avail_in > 0) {
+ br->cache_buffer =
+ (br->cache_buffer << 16) |
+ ((uint16_t)(*strm->next_in)) << 8 | br->odd;
+ strm->next_in++;
+ strm->avail_in--;
+ br->cache_avail += 16;
+ br->have_odd = 0;
+ }
+}
+
+static void
+lzx_cleanup_bitstream(struct lzx_stream *strm)
+{
+ strm->ds->br.cache_avail = 0;
+ strm->ds->br.have_odd = 0;
+}
+
+/*
+ * Decode LZX.
+ *
+ * 1. Returns ARCHIVE_OK if output buffer or input buffer are empty.
+ * Please set available buffer and call this function again.
+ * 2. Returns ARCHIVE_EOF if decompression has been completed.
+ * 3. Returns ARCHIVE_FAILED if an error occurred; compressed data
+ * is broken or you do not set 'last' flag properly.
+ */
+#define ST_RD_TRANSLATION 0
+#define ST_RD_TRANSLATION_SIZE 1
+#define ST_RD_BLOCK_TYPE 2
+#define ST_RD_BLOCK_SIZE 3
+#define ST_RD_R0 4
+#define ST_RD_R1 5
+#define ST_RD_R2 6
+#define ST_COPY_UNCOMP1 7
+#define ST_COPY_UNCOMP2 8
+#define ST_RD_ALIGNED_OFFSET 9
+#define ST_RD_VERBATIM 10
+#define ST_RD_PRE_MAIN_TREE_256 11
+#define ST_MAIN_TREE_256 12
+#define ST_RD_PRE_MAIN_TREE_REM 13
+#define ST_MAIN_TREE_REM 14
+#define ST_RD_PRE_LENGTH_TREE 15
+#define ST_LENGTH_TREE 16
+#define ST_MAIN 17
+#define ST_LENGTH 18
+#define ST_OFFSET 19
+#define ST_REAL_POS 20
+#define ST_COPY 21
+
+static int
+lzx_decode(struct lzx_stream *strm, int last)
+{
+ struct lzx_dec *ds = strm->ds;
+ int64_t avail_in;
+ int r;
+
+ if (ds->error)
+ return (ds->error);
+
+ avail_in = strm->avail_in;
+ lzx_br_fixup(strm, &(ds->br));
+ do {
+ if (ds->state < ST_MAIN)
+ r = lzx_read_blocks(strm, last);
+ else {
+ int64_t bytes_written = strm->avail_out;
+ r = lzx_decode_blocks(strm, last);
+ bytes_written -= strm->avail_out;
+ strm->next_out += bytes_written;
+ strm->total_out += bytes_written;
+ }
+ } while (r == 100);
+ strm->total_in += avail_in - strm->avail_in;
+ return (r);
+}
+
+static int
+lzx_read_blocks(struct lzx_stream *strm, int last)
+{
+ struct lzx_dec *ds = strm->ds;
+ struct lzx_br *br = &(ds->br);
+ int i, r;
+
+ for (;;) {
+ switch (ds->state) {
+ case ST_RD_TRANSLATION:
+ if (!lzx_br_read_ahead(strm, br, 1)) {
+ ds->state = ST_RD_TRANSLATION;
+ if (last)
+ goto failed;
+ return (ARCHIVE_OK);
+ }
+ ds->translation = lzx_br_bits(br, 1);
+ lzx_br_consume(br, 1);
+ /* FALL THROUGH */
+ case ST_RD_TRANSLATION_SIZE:
+ if (ds->translation) {
+ if (!lzx_br_read_ahead(strm, br, 32)) {
+ ds->state = ST_RD_TRANSLATION_SIZE;
+ if (last)
+ goto failed;
+ return (ARCHIVE_OK);
+ }
+ ds->translation_size = lzx_br_bits(br, 16);
+ lzx_br_consume(br, 16);
+ ds->translation_size <<= 16;
+ ds->translation_size |= lzx_br_bits(br, 16);
+ lzx_br_consume(br, 16);
+ }
+ /* FALL THROUGH */
+ case ST_RD_BLOCK_TYPE:
+ if (!lzx_br_read_ahead(strm, br, 3)) {
+ ds->state = ST_RD_BLOCK_TYPE;
+ if (last)
+ goto failed;
+ return (ARCHIVE_OK);
+ }
+ ds->block_type = lzx_br_bits(br, 3);
+ lzx_br_consume(br, 3);
+ /* Check a block type. */
+ switch (ds->block_type) {
+ case VERBATIM_BLOCK:
+ case ALIGNED_OFFSET_BLOCK:
+ case UNCOMPRESSED_BLOCK:
+ break;
+ default:
+ goto failed;/* Invalid */
+ }
+ /* FALL THROUGH */
+ case ST_RD_BLOCK_SIZE:
+ if (!lzx_br_read_ahead(strm, br, 24)) {
+ ds->state = ST_RD_BLOCK_SIZE;
+ if (last)
+ goto failed;
+ return (ARCHIVE_OK);
+ }
+ ds->block_size = lzx_br_bits(br, 8);
+ lzx_br_consume(br, 8);
+ ds->block_size <<= 16;
+ ds->block_size |= lzx_br_bits(br, 16);
+ lzx_br_consume(br, 16);
+ if (ds->block_size == 0)
+ goto failed;
+ ds->block_bytes_avail = ds->block_size;
+ if (ds->block_type != UNCOMPRESSED_BLOCK) {
+ if (ds->block_type == VERBATIM_BLOCK)
+ ds->state = ST_RD_VERBATIM;
+ else
+ ds->state = ST_RD_ALIGNED_OFFSET;
+ break;
+ }
+ /*
+ * Handle an Uncompressed Block.
+ */
+ /* Skip padding to align following field on
+ * 16-bit boundary. */
+ lzx_br_consume_unalined_bits(br);
+ /* Preparation to read repeated offsets R0,R1 and R2. */
+ ds->rbytes_avail = 0;
+ ds->state = ST_RD_R0;
+ /* FALL THROUGH */
+ case ST_RD_R0:
+ case ST_RD_R1:
+ case ST_RD_R2:
+ do {
+ uint16_t u16;
+ /* Drain bits in the cache buffer of
+ * bit-stream. */
+ if (lzx_br_has(br, 32)) {
+ u16 = lzx_br_bits(br, 16);
+ lzx_br_consume(br, 16);
+ archive_le16enc(ds->rbytes, u16);
+ u16 = lzx_br_bits(br, 16);
+ lzx_br_consume(br, 16);
+ archive_le16enc(ds->rbytes+2, u16);
+ ds->rbytes_avail = 4;
+ } else if (lzx_br_has(br, 16)) {
+ u16 = lzx_br_bits(br, 16);
+ lzx_br_consume(br, 16);
+ archive_le16enc(ds->rbytes, u16);
+ ds->rbytes_avail = 2;
+ } else
+ ds->rbytes_avail = 0;
+ if (ds->rbytes_avail < 4 && ds->br.have_odd) {
+ ds->rbytes[ds->rbytes_avail++] =
+ ds->br.odd;
+ ds->br.have_odd = 0;
+ }
+ while (ds->rbytes_avail < 4) {
+ if (strm->avail_in <= 0) {
+ if (last)
+ goto failed;
+ return (ARCHIVE_OK);
+ }
+ ds->rbytes[ds->rbytes_avail++] =
+ *strm->next_in++;
+ strm->avail_in--;
+ }
+ if (ds->state == ST_RD_R0) {
+ ds->r0 = archive_le32dec(ds->rbytes);
+ if (ds->r0 < 0)
+ goto failed;
+ ds->state = ST_RD_R1;
+ } else if (ds->state == ST_RD_R1) {
+ ds->r1 = archive_le32dec(ds->rbytes);
+ if (ds->r1 < 0)
+ goto failed;
+ ds->state = ST_RD_R2;
+ } else if (ds->state == ST_RD_R2) {
+ ds->r2 = archive_le32dec(ds->rbytes);
+ if (ds->r2 < 0)
+ goto failed;
+ /* We've gotten all repeated offsets. */
+ ds->state = ST_COPY_UNCOMP1;
+ }
+ } while (ds->state != ST_COPY_UNCOMP1);
+ /* FALL THROUGH */
+ case ST_COPY_UNCOMP1:
+ /*
+ * Copy bytes form next_in to next_out directly.
+ */
+ while (ds->block_bytes_avail) {
+ unsigned char *d;
+ int l,ll;
+
+ if (strm->avail_out <= 0)
+ /* Output buffer is empty. */
+ return (ARCHIVE_OK);
+ if (strm->avail_in <= 0) {
+ /* Input buffer is empty. */
+ if (last)
+ goto failed;
+ return (ARCHIVE_OK);
+ }
+ l = ds->block_bytes_avail;
+ if (l > ds->w_size - ds->w_pos)
+ l = ds->w_size - ds->w_pos;
+ if (l > strm->avail_out)
+ l = (int)strm->avail_out;
+ if (l > strm->avail_in)
+ l = (int)strm->avail_in;
+ ll = l;
+ d = &(ds->w_buff[ds->w_pos]);
+ while (--l >= 0) {
+ *strm->next_out++ = *strm->next_in;
+ *d++ = *strm->next_in++;
+ }
+ strm->avail_out -= ll;
+ strm->total_out += ll;
+ strm->avail_in -= ll;
+ ds->w_pos = (ds->w_pos + ll) & ds->w_mask;
+ ds->block_bytes_avail -= ll;
+ }
+ /* FALL THROUGH */
+ case ST_COPY_UNCOMP2:
+ /* Re-align; skip padding byte. */
+ if (ds->block_size & 1) {
+ if (strm->avail_in <= 0) {
+ /* Input buffer is empty. */
+ ds->state = ST_COPY_UNCOMP2;
+ if (last)
+ goto failed;
+ return (ARCHIVE_OK);
+ }
+ strm->next_in++;
+ strm->avail_in --;
+ }
+ /* This block ended. */
+ ds->state = ST_RD_BLOCK_TYPE;
+ return (ARCHIVE_EOF);
+ /********************/
+ case ST_RD_ALIGNED_OFFSET:
+ /*
+ * Read Aligned offset tree.
+ */
+ if (!lzx_br_read_ahead(strm, br, 3 * ds->at.len_size)) {
+ ds->state = ST_RD_ALIGNED_OFFSET;
+ if (last)
+ goto failed;
+ return (ARCHIVE_OK);
+ }
+ memset(ds->at.freq, 0, sizeof(ds->at.freq));
+ for (i = 0; i < ds->at.len_size; i++) {
+ ds->at.bitlen[i] = lzx_br_bits(br, 3);
+ ds->at.freq[ds->at.bitlen[i]]++;
+ lzx_br_consume(br, 3);
+ }
+ if (!lzx_make_huffman_table(&ds->at))
+ goto failed;
+ /* FALL THROUGH */
+ case ST_RD_VERBATIM:
+ ds->loop = 0;
+ /* FALL THROUGH */
+ case ST_RD_PRE_MAIN_TREE_256:
+ /*
+ * Read Pre-tree for first 256 elements of main tree.
+ */
+ if (!lzx_read_pre_tree(strm)) {
+ ds->state = ST_RD_PRE_MAIN_TREE_256;
+ if (last)
+ goto failed;
+ return (ARCHIVE_OK);
+ }
+ if (!lzx_make_huffman_table(&ds->pt))
+ goto failed;
+ ds->loop = 0;
+ /* FALL THROUGH */
+ case ST_MAIN_TREE_256:
+ /*
+ * Get path lengths of first 256 elements of main tree.
+ */
+ r = lzx_read_bitlen(strm, &ds->mt, 256);
+ if (r < 0)
+ goto failed;
+ else if (!r) {
+ ds->state = ST_MAIN_TREE_256;
+ if (last)
+ goto failed;
+ return (ARCHIVE_OK);
+ }
+ ds->loop = 0;
+ /* FALL THROUGH */
+ case ST_RD_PRE_MAIN_TREE_REM:
+ /*
+ * Read Pre-tree for remaining elements of main tree.
+ */
+ if (!lzx_read_pre_tree(strm)) {
+ ds->state = ST_RD_PRE_MAIN_TREE_REM;
+ if (last)
+ goto failed;
+ return (ARCHIVE_OK);
+ }
+ if (!lzx_make_huffman_table(&ds->pt))
+ goto failed;
+ ds->loop = 256;
+ /* FALL THROUGH */
+ case ST_MAIN_TREE_REM:
+ /*
+ * Get path lengths of remaining elements of main tree.
+ */
+ r = lzx_read_bitlen(strm, &ds->mt, -1);
+ if (r < 0)
+ goto failed;
+ else if (!r) {
+ ds->state = ST_MAIN_TREE_REM;
+ if (last)
+ goto failed;
+ return (ARCHIVE_OK);
+ }
+ if (!lzx_make_huffman_table(&ds->mt))
+ goto failed;
+ ds->loop = 0;
+ /* FALL THROUGH */
+ case ST_RD_PRE_LENGTH_TREE:
+ /*
+ * Read Pre-tree for remaining elements of main tree.
+ */
+ if (!lzx_read_pre_tree(strm)) {
+ ds->state = ST_RD_PRE_LENGTH_TREE;
+ if (last)
+ goto failed;
+ return (ARCHIVE_OK);
+ }
+ if (!lzx_make_huffman_table(&ds->pt))
+ goto failed;
+ ds->loop = 0;
+ /* FALL THROUGH */
+ case ST_LENGTH_TREE:
+ /*
+ * Get path lengths of remaining elements of main tree.
+ */
+ r = lzx_read_bitlen(strm, &ds->lt, -1);
+ if (r < 0)
+ goto failed;
+ else if (!r) {
+ ds->state = ST_LENGTH_TREE;
+ if (last)
+ goto failed;
+ return (ARCHIVE_OK);
+ }
+ if (!lzx_make_huffman_table(&ds->lt))
+ goto failed;
+ ds->state = ST_MAIN;
+ return (100);
+ }
+ }
+failed:
+ return (ds->error = ARCHIVE_FAILED);
+}
+
+static int
+lzx_decode_blocks(struct lzx_stream *strm, int last)
+{
+ struct lzx_dec *ds = strm->ds;
+ struct lzx_br bre = ds->br;
+ struct huffman *at = &(ds->at), *lt = &(ds->lt), *mt = &(ds->mt);
+ const struct lzx_pos_tbl *pos_tbl = ds->pos_tbl;
+ unsigned char *outp = strm->next_out;
+ unsigned char *endp = outp + strm->avail_out;
+ unsigned char *w_buff = ds->w_buff;
+ unsigned char *at_bitlen = at->bitlen;
+ unsigned char *lt_bitlen = lt->bitlen;
+ unsigned char *mt_bitlen = mt->bitlen;
+ size_t block_bytes_avail = ds->block_bytes_avail;
+ int at_max_bits = at->max_bits;
+ int lt_max_bits = lt->max_bits;
+ int mt_max_bits = mt->max_bits;
+ int c, copy_len = ds->copy_len, copy_pos = ds->copy_pos;
+ int w_pos = ds->w_pos, w_mask = ds->w_mask, w_size = ds->w_size;
+ int length_header = ds->length_header;
+ int offset_bits = ds->offset_bits;
+ int position_slot = ds->position_slot;
+ int r0 = ds->r0, r1 = ds->r1, r2 = ds->r2;
+ int state = ds->state;
+ char block_type = ds->block_type;
+
+ for (;;) {
+ switch (state) {
+ case ST_MAIN:
+ for (;;) {
+ if (block_bytes_avail == 0) {
+ /* This block ended. */
+ ds->state = ST_RD_BLOCK_TYPE;
+ ds->br = bre;
+ ds->block_bytes_avail =
+ block_bytes_avail;
+ ds->copy_len = copy_len;
+ ds->copy_pos = copy_pos;
+ ds->length_header = length_header;
+ ds->position_slot = position_slot;
+ ds->r0 = r0; ds->r1 = r1; ds->r2 = r2;
+ ds->w_pos = w_pos;
+ strm->avail_out = endp - outp;
+ return (ARCHIVE_EOF);
+ }
+ if (outp >= endp)
+ /* Output buffer is empty. */
+ goto next_data;
+
+ if (!lzx_br_read_ahead(strm, &bre,
+ mt_max_bits)) {
+ if (!last)
+ goto next_data;
+ /* Remaining bits are less than
+ * maximum bits(mt.max_bits) but maybe
+ * it still remains as much as we need,
+ * so we should try to use it with
+ * dummy bits. */
+ c = lzx_decode_huffman(mt,
+ lzx_br_bits_forced(
+ &bre, mt_max_bits));
+ lzx_br_consume(&bre, mt_bitlen[c]);
+ if (!lzx_br_has(&bre, 0))
+ goto failed;/* Over read. */
+ } else {
+ c = lzx_decode_huffman(mt,
+ lzx_br_bits(&bre, mt_max_bits));
+ lzx_br_consume(&bre, mt_bitlen[c]);
+ }
+ if (c > UCHAR_MAX)
+ break;
+ /*
+ * 'c' is exactly literal code.
+ */
+ /* Save a decoded code to reference it
+ * afterward. */
+ w_buff[w_pos] = c;
+ w_pos = (w_pos + 1) & w_mask;
+ /* Store the decoded code to output buffer. */
+ *outp++ = c;
+ block_bytes_avail--;
+ }
+ /*
+ * Get a match code, its length and offset.
+ */
+ c -= UCHAR_MAX + 1;
+ length_header = c & 7;
+ position_slot = c >> 3;
+ /* FALL THROUGH */
+ case ST_LENGTH:
+ /*
+ * Get a length.
+ */
+ if (length_header == 7) {
+ if (!lzx_br_read_ahead(strm, &bre,
+ lt_max_bits)) {
+ if (!last) {
+ state = ST_LENGTH;
+ goto next_data;
+ }
+ c = lzx_decode_huffman(lt,
+ lzx_br_bits_forced(
+ &bre, lt_max_bits));
+ lzx_br_consume(&bre, lt_bitlen[c]);
+ if (!lzx_br_has(&bre, 0))
+ goto failed;/* Over read. */
+ } else {
+ c = lzx_decode_huffman(lt,
+ lzx_br_bits(&bre, lt_max_bits));
+ lzx_br_consume(&bre, lt_bitlen[c]);
+ }
+ copy_len = c + 7 + 2;
+ } else
+ copy_len = length_header + 2;
+ if ((size_t)copy_len > block_bytes_avail)
+ goto failed;
+ /*
+ * Get an offset.
+ */
+ switch (position_slot) {
+ case 0: /* Use repeated offset 0. */
+ copy_pos = r0;
+ state = ST_REAL_POS;
+ continue;
+ case 1: /* Use repeated offset 1. */
+ copy_pos = r1;
+ /* Swap repeated offset. */
+ r1 = r0;
+ r0 = copy_pos;
+ state = ST_REAL_POS;
+ continue;
+ case 2: /* Use repeated offset 2. */
+ copy_pos = r2;
+ /* Swap repeated offset. */
+ r2 = r0;
+ r0 = copy_pos;
+ state = ST_REAL_POS;
+ continue;
+ default:
+ offset_bits =
+ pos_tbl[position_slot].footer_bits;
+ break;
+ }
+ /* FALL THROUGH */
+ case ST_OFFSET:
+ /*
+ * Get the offset, which is a distance from
+ * current window position.
+ */
+ if (block_type == ALIGNED_OFFSET_BLOCK &&
+ offset_bits >= 3) {
+ int offbits = offset_bits - 3;
+
+ if (!lzx_br_read_ahead(strm, &bre, offbits)) {
+ state = ST_OFFSET;
+ if (last)
+ goto failed;
+ goto next_data;
+ }
+ copy_pos = lzx_br_bits(&bre, offbits) << 3;
+
+ /* Get an aligned number. */
+ if (!lzx_br_read_ahead(strm, &bre,
+ offbits + at_max_bits)) {
+ if (!last) {
+ state = ST_OFFSET;
+ goto next_data;
+ }
+ lzx_br_consume(&bre, offbits);
+ c = lzx_decode_huffman(at,
+ lzx_br_bits_forced(&bre,
+ at_max_bits));
+ lzx_br_consume(&bre, at_bitlen[c]);
+ if (!lzx_br_has(&bre, 0))
+ goto failed;/* Over read. */
+ } else {
+ lzx_br_consume(&bre, offbits);
+ c = lzx_decode_huffman(at,
+ lzx_br_bits(&bre, at_max_bits));
+ lzx_br_consume(&bre, at_bitlen[c]);
+ }
+ /* Add an aligned number. */
+ copy_pos += c;
+ } else {
+ if (!lzx_br_read_ahead(strm, &bre,
+ offset_bits)) {
+ state = ST_OFFSET;
+ if (last)
+ goto failed;
+ goto next_data;
+ }
+ copy_pos = lzx_br_bits(&bre, offset_bits);
+ lzx_br_consume(&bre, offset_bits);
+ }
+ copy_pos += pos_tbl[position_slot].base -2;
+
+ /* Update repeated offset LRU queue. */
+ r2 = r1;
+ r1 = r0;
+ r0 = copy_pos;
+ /* FALL THROUGH */
+ case ST_REAL_POS:
+ /*
+ * Compute a real position in window.
+ */
+ copy_pos = (w_pos - copy_pos) & w_mask;
+ /* FALL THROUGH */
+ case ST_COPY:
+ /*
+ * Copy several bytes as extracted data from the window
+ * into the output buffer.
+ */
+ for (;;) {
+ const unsigned char *s;
+ int l;
+
+ l = copy_len;
+ if (copy_pos > w_pos) {
+ if (l > w_size - copy_pos)
+ l = w_size - copy_pos;
+ } else {
+ if (l > w_size - w_pos)
+ l = w_size - w_pos;
+ }
+ if (outp + l >= endp)
+ l = endp - outp;
+ s = w_buff + copy_pos;
+ if (l >= 8 && ((copy_pos + l < w_pos)
+ || (w_pos + l < copy_pos))) {
+ memcpy(w_buff + w_pos, s, l);
+ memcpy(outp, s, l);
+ } else {
+ unsigned char *d;
+ int li;
+
+ d = w_buff + w_pos;
+ for (li = 0; li < l; li++)
+ outp[li] = d[li] = s[li];
+ }
+ outp += l;
+ copy_pos = (copy_pos + l) & w_mask;
+ w_pos = (w_pos + l) & w_mask;
+ block_bytes_avail -= l;
+ if (copy_len <= l)
+ /* A copy of current pattern ended. */
+ break;
+ copy_len -= l;
+ if (outp >= endp) {
+ /* Output buffer is empty. */
+ state = ST_COPY;
+ goto next_data;
+ }
+ }
+ state = ST_MAIN;
+ break;
+ }
+ }
+failed:
+ return (ds->error = ARCHIVE_FAILED);
+next_data:
+ ds->br = bre;
+ ds->block_bytes_avail = block_bytes_avail;
+ ds->copy_len = copy_len;
+ ds->copy_pos = copy_pos;
+ ds->length_header = length_header;
+ ds->offset_bits = offset_bits;
+ ds->position_slot = position_slot;
+ ds->r0 = r0; ds->r1 = r1; ds->r2 = r2;
+ ds->state = state;
+ ds->w_pos = w_pos;
+ strm->avail_out = endp - outp;
+ return (ARCHIVE_OK);
+}
+
+static int
+lzx_read_pre_tree(struct lzx_stream *strm)
+{
+ struct lzx_dec *ds = strm->ds;
+ struct lzx_br *br = &(ds->br);
+ int i;
+
+ if (ds->loop == 0)
+ memset(ds->pt.freq, 0, sizeof(ds->pt.freq));
+ for (i = ds->loop; i < ds->pt.len_size; i++) {
+ if (!lzx_br_read_ahead(strm, br, 4)) {
+ ds->loop = i;
+ return (0);
+ }
+ ds->pt.bitlen[i] = lzx_br_bits(br, 4);
+ ds->pt.freq[ds->pt.bitlen[i]]++;
+ lzx_br_consume(br, 4);
+ }
+ ds->loop = i;
+ return (1);
+}
+
+/*
+ * Read a bunch of bit-lengths from pre-tree.
+ */
+static int
+lzx_read_bitlen(struct lzx_stream *strm, struct huffman *d, int end)
+{
+ struct lzx_dec *ds = strm->ds;
+ struct lzx_br *br = &(ds->br);
+ int c, i, j, ret, same;
+ unsigned rbits;
+
+ i = ds->loop;
+ if (i == 0)
+ memset(d->freq, 0, sizeof(d->freq));
+ ret = 0;
+ if (end < 0)
+ end = d->len_size;
+ while (i < end) {
+ ds->loop = i;
+ if (!lzx_br_read_ahead(strm, br, ds->pt.max_bits))
+ goto getdata;
+ rbits = lzx_br_bits(br, ds->pt.max_bits);
+ c = lzx_decode_huffman(&(ds->pt), rbits);
+ switch (c) {
+ case 17:/* several zero lengths, from 4 to 19. */
+ if (!lzx_br_read_ahead(strm, br, ds->pt.bitlen[c]+4))
+ goto getdata;
+ lzx_br_consume(br, ds->pt.bitlen[c]);
+ same = lzx_br_bits(br, 4) + 4;
+ if (i + same > end)
+ return (-1);/* Invalid */
+ lzx_br_consume(br, 4);
+ for (j = 0; j < same; j++)
+ d->bitlen[i++] = 0;
+ break;
+ case 18:/* many zero lengths, from 20 to 51. */
+ if (!lzx_br_read_ahead(strm, br, ds->pt.bitlen[c]+5))
+ goto getdata;
+ lzx_br_consume(br, ds->pt.bitlen[c]);
+ same = lzx_br_bits(br, 5) + 20;
+ if (i + same > end)
+ return (-1);/* Invalid */
+ lzx_br_consume(br, 5);
+ memset(d->bitlen + i, 0, same);
+ i += same;
+ break;
+ case 19:/* a few same lengths. */
+ if (!lzx_br_read_ahead(strm, br,
+ ds->pt.bitlen[c]+1+ds->pt.max_bits))
+ goto getdata;
+ lzx_br_consume(br, ds->pt.bitlen[c]);
+ same = lzx_br_bits(br, 1) + 4;
+ if (i + same > end)
+ return (-1);
+ lzx_br_consume(br, 1);
+ rbits = lzx_br_bits(br, ds->pt.max_bits);
+ c = lzx_decode_huffman(&(ds->pt), rbits);
+ lzx_br_consume(br, ds->pt.bitlen[c]);
+ c = (d->bitlen[i] - c + 17) % 17;
+ if (c < 0)
+ return (-1);/* Invalid */
+ for (j = 0; j < same; j++)
+ d->bitlen[i++] = c;
+ d->freq[c] += same;
+ break;
+ default:
+ lzx_br_consume(br, ds->pt.bitlen[c]);
+ c = (d->bitlen[i] - c + 17) % 17;
+ if (c < 0)
+ return (-1);/* Invalid */
+ d->freq[c]++;
+ d->bitlen[i++] = c;
+ break;
+ }
+ }
+ ret = 1;
+getdata:
+ ds->loop = i;
+ return (ret);
+}
+
+static int
+lzx_huffman_init(struct huffman *hf, size_t len_size, int tbl_bits)
+{
+ int bits;
+
+ if (hf->bitlen == NULL || hf->len_size != (int)len_size) {
+ free(hf->bitlen);
+ hf->bitlen = calloc(len_size, sizeof(hf->bitlen[0]));
+ if (hf->bitlen == NULL)
+ return (ARCHIVE_FATAL);
+ hf->len_size = len_size;
+ } else
+ memset(hf->bitlen, 0, len_size * sizeof(hf->bitlen[0]));
+ if (hf->tbl == NULL) {
+ if (tbl_bits < HTBL_BITS)
+ bits = tbl_bits;
+ else
+ bits = HTBL_BITS;
+ hf->tbl = malloc((1 << bits) * sizeof(hf->tbl[0]));
+ if (hf->tbl == NULL)
+ return (ARCHIVE_FATAL);
+ hf->tbl_bits = tbl_bits;
+ }
+ if (hf->tree == NULL && tbl_bits > HTBL_BITS) {
+ hf->tree_avail = 1 << (tbl_bits - HTBL_BITS + 4);
+ hf->tree = malloc(hf->tree_avail * sizeof(hf->tree[0]));
+ if (hf->tree == NULL)
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_OK);
+}
+
+static void
+lzx_huffman_free(struct huffman *hf)
+{
+ free(hf->bitlen);
+ free(hf->tbl);
+ free(hf->tree);
+}
+
+/*
+ * Make a huffman coding table.
+ */
+static int
+lzx_make_huffman_table(struct huffman *hf)
+{
+ uint16_t *tbl;
+ const unsigned char *bitlen;
+ int bitptn[17], weight[17];
+ int i, maxbits = 0, ptn, tbl_size, w;
+ int diffbits, len_avail;
+
+ /*
+ * Initialize bit patterns.
+ */
+ ptn = 0;
+ for (i = 1, w = 1 << 15; i <= 16; i++, w >>= 1) {
+ bitptn[i] = ptn;
+ weight[i] = w;
+ if (hf->freq[i]) {
+ ptn += hf->freq[i] * w;
+ maxbits = i;
+ }
+ }
+ if ((ptn & 0xffff) != 0 || maxbits > hf->tbl_bits)
+ return (0);/* Invalid */
+
+ hf->max_bits = maxbits;
+
+ /*
+ * Cut out extra bits which we won't house in the table.
+ * This preparation reduces the same calculation in the for-loop
+ * making the table.
+ */
+ if (maxbits < 16) {
+ int ebits = 16 - maxbits;
+ for (i = 1; i <= maxbits; i++) {
+ bitptn[i] >>= ebits;
+ weight[i] >>= ebits;
+ }
+ }
+ if (maxbits > HTBL_BITS) {
+ int htbl_max;
+ uint16_t *p;
+
+ diffbits = maxbits - HTBL_BITS;
+ for (i = 1; i <= HTBL_BITS; i++) {
+ bitptn[i] >>= diffbits;
+ weight[i] >>= diffbits;
+ }
+ htbl_max = bitptn[HTBL_BITS] +
+ weight[HTBL_BITS] * hf->freq[HTBL_BITS];
+ p = &(hf->tbl[htbl_max]);
+ while (p < &hf->tbl[1U<<HTBL_BITS])
+ *p++ = 0;
+ } else
+ diffbits = 0;
+ hf->shift_bits = diffbits;
+
+ /*
+ * Make the table.
+ */
+ tbl_size = 1 << HTBL_BITS;
+ tbl = hf->tbl;
+ bitlen = hf->bitlen;
+ len_avail = hf->len_size;
+ hf->tree_used = 0;
+ for (i = 0; i < len_avail; i++) {
+ uint16_t *p;
+ int len, cnt;
+ uint16_t bit;
+ int extlen;
+ struct htree_t *ht;
+
+ if (bitlen[i] == 0)
+ continue;
+ /* Get a bit pattern */
+ len = bitlen[i];
+ ptn = bitptn[len];
+ cnt = weight[len];
+ if (len <= HTBL_BITS) {
+ /* Calculate next bit pattern */
+ if ((bitptn[len] = ptn + cnt) > tbl_size)
+ return (0);/* Invalid */
+ /* Update the table */
+ p = &(tbl[ptn]);
+ while (--cnt >= 0)
+ p[cnt] = (uint16_t)i;
+ continue;
+ }
+
+ /*
+ * A bit length is too big to be housed to a direct table,
+ * so we use a tree model for its extra bits.
+ */
+ bitptn[len] = ptn + cnt;
+ bit = 1U << (diffbits -1);
+ extlen = len - HTBL_BITS;
+
+ p = &(tbl[ptn >> diffbits]);
+ if (*p == 0) {
+ *p = len_avail + hf->tree_used;
+ ht = &(hf->tree[hf->tree_used++]);
+ if (hf->tree_used > hf->tree_avail)
+ return (0);/* Invalid */
+ ht->left = 0;
+ ht->right = 0;
+ } else {
+ if (*p < len_avail ||
+ *p >= (len_avail + hf->tree_used))
+ return (0);/* Invalid */
+ ht = &(hf->tree[*p - len_avail]);
+ }
+ while (--extlen > 0) {
+ if (ptn & bit) {
+ if (ht->left < len_avail) {
+ ht->left = len_avail + hf->tree_used;
+ ht = &(hf->tree[hf->tree_used++]);
+ if (hf->tree_used > hf->tree_avail)
+ return (0);/* Invalid */
+ ht->left = 0;
+ ht->right = 0;
+ } else {
+ ht = &(hf->tree[ht->left - len_avail]);
+ }
+ } else {
+ if (ht->right < len_avail) {
+ ht->right = len_avail + hf->tree_used;
+ ht = &(hf->tree[hf->tree_used++]);
+ if (hf->tree_used > hf->tree_avail)
+ return (0);/* Invalid */
+ ht->left = 0;
+ ht->right = 0;
+ } else {
+ ht = &(hf->tree[ht->right - len_avail]);
+ }
+ }
+ bit >>= 1;
+ }
+ if (ptn & bit) {
+ if (ht->left != 0)
+ return (0);/* Invalid */
+ ht->left = (uint16_t)i;
+ } else {
+ if (ht->right != 0)
+ return (0);/* Invalid */
+ ht->right = (uint16_t)i;
+ }
+ }
+ return (1);
+}
+
+static int
+lzx_decode_huffman_tree(struct huffman *hf, unsigned rbits, int c)
+{
+ struct htree_t *ht;
+ int extlen;
+
+ ht = hf->tree;
+ extlen = hf->shift_bits;
+ while (c >= hf->len_size) {
+ c -= hf->len_size;
+ if (extlen-- <= 0 || c >= hf->tree_used)
+ return (0);
+ if (rbits & (1U << extlen))
+ c = ht[c].left;
+ else
+ c = ht[c].right;
+ }
+ return (c);
+}
+
+static inline int
+lzx_decode_huffman(struct huffman *hf, unsigned rbits)
+{
+ int c;
+ /*
+ * At first search an index table for a bit pattern.
+ * If it fails, search a huffman tree for.
+ */
+ c = hf->tbl[rbits >> hf->shift_bits];
+ if (c < hf->len_size)
+ return (c);
+ /* This bit pattern needs to be found out at a huffman tree. */
+ return (lzx_decode_huffman_tree(hf, rbits, c));
+}
+
diff --git a/libarchive/archive_read_support_format_cpio.c b/libarchive/archive_read_support_format_cpio.c
index 23a2025d0954..5ae73d7700ba 100644
--- a/libarchive/archive_read_support_format_cpio.c
+++ b/libarchive/archive_read_support_format_cpio.c
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2010-2011 Michihiro NAKAJIMA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -39,62 +40,127 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_cpio.c 20116
#include "archive.h"
#include "archive_entry.h"
+#include "archive_entry_locale.h"
#include "archive_private.h"
#include "archive_read_private.h"
-#ifdef _MSC_VER
-#define __packed
-#pragma pack(push, 1)
-#endif
-struct cpio_bin_header {
- unsigned char c_magic[2];
- unsigned char c_dev[2];
- unsigned char c_ino[2];
- unsigned char c_mode[2];
- unsigned char c_uid[2];
- unsigned char c_gid[2];
- unsigned char c_nlink[2];
- unsigned char c_rdev[2];
- unsigned char c_mtime[4];
- unsigned char c_namesize[2];
- unsigned char c_filesize[4];
-} __packed;
-
-struct cpio_odc_header {
- char c_magic[6];
- char c_dev[6];
- char c_ino[6];
- char c_mode[6];
- char c_uid[6];
- char c_gid[6];
- char c_nlink[6];
- char c_rdev[6];
- char c_mtime[11];
- char c_namesize[6];
- char c_filesize[11];
-} __packed;
-
-struct cpio_newc_header {
- char c_magic[6];
- char c_ino[8];
- char c_mode[8];
- char c_uid[8];
- char c_gid[8];
- char c_nlink[8];
- char c_mtime[8];
- char c_filesize[8];
- char c_devmajor[8];
- char c_devminor[8];
- char c_rdevmajor[8];
- char c_rdevminor[8];
- char c_namesize[8];
- char c_crc[8];
-} __packed;
-
-#ifdef _MSC_VER
-#undef __packed
-#pragma pack(pop)
-#endif
+#define bin_magic_offset 0
+#define bin_magic_size 2
+#define bin_dev_offset 2
+#define bin_dev_size 2
+#define bin_ino_offset 4
+#define bin_ino_size 2
+#define bin_mode_offset 6
+#define bin_mode_size 2
+#define bin_uid_offset 8
+#define bin_uid_size 2
+#define bin_gid_offset 10
+#define bin_gid_size 2
+#define bin_nlink_offset 12
+#define bin_nlink_size 2
+#define bin_rdev_offset 14
+#define bin_rdev_size 2
+#define bin_mtime_offset 16
+#define bin_mtime_size 4
+#define bin_namesize_offset 20
+#define bin_namesize_size 2
+#define bin_filesize_offset 22
+#define bin_filesize_size 4
+#define bin_header_size 26
+
+#define odc_magic_offset 0
+#define odc_magic_size 6
+#define odc_dev_offset 6
+#define odc_dev_size 6
+#define odc_ino_offset 12
+#define odc_ino_size 6
+#define odc_mode_offset 18
+#define odc_mode_size 6
+#define odc_uid_offset 24
+#define odc_uid_size 6
+#define odc_gid_offset 30
+#define odc_gid_size 6
+#define odc_nlink_offset 36
+#define odc_nlink_size 6
+#define odc_rdev_offset 42
+#define odc_rdev_size 6
+#define odc_mtime_offset 48
+#define odc_mtime_size 11
+#define odc_namesize_offset 59
+#define odc_namesize_size 6
+#define odc_filesize_offset 65
+#define odc_filesize_size 11
+#define odc_header_size 76
+
+#define newc_magic_offset 0
+#define newc_magic_size 6
+#define newc_ino_offset 6
+#define newc_ino_size 8
+#define newc_mode_offset 14
+#define newc_mode_size 8
+#define newc_uid_offset 22
+#define newc_uid_size 8
+#define newc_gid_offset 30
+#define newc_gid_size 8
+#define newc_nlink_offset 38
+#define newc_nlink_size 8
+#define newc_mtime_offset 46
+#define newc_mtime_size 8
+#define newc_filesize_offset 54
+#define newc_filesize_size 8
+#define newc_devmajor_offset 62
+#define newc_devmajor_size 8
+#define newc_devminor_offset 70
+#define newc_devminor_size 8
+#define newc_rdevmajor_offset 78
+#define newc_rdevmajor_size 8
+#define newc_rdevminor_offset 86
+#define newc_rdevminor_size 8
+#define newc_namesize_offset 94
+#define newc_namesize_size 8
+#define newc_checksum_offset 102
+#define newc_checksum_size 8
+#define newc_header_size 110
+
+/*
+ * An afio large ASCII header, which they named itself.
+ * afio utility uses this header, if a file size is larger than 2G bytes
+ * or inode/uid/gid is bigger than 65535(0xFFFF) or mtime is bigger than
+ * 0x7fffffff, which we cannot record to odc header because of its limit.
+ * If not, uses odc header.
+ */
+#define afiol_magic_offset 0
+#define afiol_magic_size 6
+#define afiol_dev_offset 6
+#define afiol_dev_size 8 /* hex */
+#define afiol_ino_offset 14
+#define afiol_ino_size 16 /* hex */
+#define afiol_ino_m_offset 30 /* 'm' */
+#define afiol_mode_offset 31
+#define afiol_mode_size 6 /* oct */
+#define afiol_uid_offset 37
+#define afiol_uid_size 8 /* hex */
+#define afiol_gid_offset 45
+#define afiol_gid_size 8 /* hex */
+#define afiol_nlink_offset 53
+#define afiol_nlink_size 8 /* hex */
+#define afiol_rdev_offset 61
+#define afiol_rdev_size 8 /* hex */
+#define afiol_mtime_offset 69
+#define afiol_mtime_size 16 /* hex */
+#define afiol_mtime_n_offset 85 /* 'n' */
+#define afiol_namesize_offset 86
+#define afiol_namesize_size 4 /* hex */
+#define afiol_flag_offset 90
+#define afiol_flag_size 4 /* hex */
+#define afiol_xsize_offset 94
+#define afiol_xsize_size 4 /* hex */
+#define afiol_xsize_s_offset 98 /* 's' */
+#define afiol_filesize_offset 99
+#define afiol_filesize_size 16 /* hex */
+#define afiol_filesize_c_offset 115 /* ':' */
+#define afiol_header_size 116
+
struct links_entry {
struct links_entry *next;
@@ -111,21 +177,27 @@ struct cpio {
int (*read_header)(struct archive_read *, struct cpio *,
struct archive_entry *, size_t *, size_t *);
struct links_entry *links_head;
- struct archive_string entry_name;
- struct archive_string entry_linkname;
- off_t entry_bytes_remaining;
- off_t entry_offset;
- off_t entry_padding;
+ int64_t entry_bytes_remaining;
+ int64_t entry_bytes_unconsumed;
+ int64_t entry_offset;
+ int64_t entry_padding;
+
+ struct archive_string_conv *opt_sconv;
+ struct archive_string_conv *sconv_default;
+ int init_default_conversion;
};
static int64_t atol16(const char *, unsigned);
static int64_t atol8(const char *, unsigned);
-static int archive_read_format_cpio_bid(struct archive_read *);
+static int archive_read_format_cpio_bid(struct archive_read *, int);
+static int archive_read_format_cpio_options(struct archive_read *,
+ const char *, const char *);
static int archive_read_format_cpio_cleanup(struct archive_read *);
static int archive_read_format_cpio_read_data(struct archive_read *,
- const void **, size_t *, off_t *);
+ const void **, size_t *, int64_t *);
static int archive_read_format_cpio_read_header(struct archive_read *,
struct archive_entry *);
+static int archive_read_format_cpio_skip(struct archive_read *);
static int be4(const unsigned char *);
static int find_odc_header(struct archive_read *);
static int find_newc_header(struct archive_read *);
@@ -137,10 +209,13 @@ static int header_newc(struct archive_read *, struct cpio *,
struct archive_entry *, size_t *, size_t *);
static int header_odc(struct archive_read *, struct cpio *,
struct archive_entry *, size_t *, size_t *);
+static int header_afiol(struct archive_read *, struct cpio *,
+ struct archive_entry *, size_t *, size_t *);
static int is_octal(const char *, size_t);
static int is_hex(const char *, size_t);
static int le4(const unsigned char *);
-static void record_hardlink(struct cpio *cpio, struct archive_entry *entry);
+static int record_hardlink(struct archive_read *a,
+ struct cpio *cpio, struct archive_entry *entry);
int
archive_read_support_format_cpio(struct archive *_a)
@@ -149,22 +224,24 @@ archive_read_support_format_cpio(struct archive *_a)
struct cpio *cpio;
int r;
- cpio = (struct cpio *)malloc(sizeof(*cpio));
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_cpio");
+
+ cpio = (struct cpio *)calloc(1, sizeof(*cpio));
if (cpio == NULL) {
archive_set_error(&a->archive, ENOMEM, "Can't allocate cpio data");
return (ARCHIVE_FATAL);
}
- memset(cpio, 0, sizeof(*cpio));
cpio->magic = CPIO_MAGIC;
r = __archive_read_register_format(a,
cpio,
"cpio",
archive_read_format_cpio_bid,
- NULL,
+ archive_read_format_cpio_options,
archive_read_format_cpio_read_header,
archive_read_format_cpio_read_data,
- NULL,
+ archive_read_format_cpio_skip,
archive_read_format_cpio_cleanup);
if (r != ARCHIVE_OK)
@@ -174,19 +251,19 @@ archive_read_support_format_cpio(struct archive *_a)
static int
-archive_read_format_cpio_bid(struct archive_read *a)
+archive_read_format_cpio_bid(struct archive_read *a, int best_bid)
{
- const void *h;
const unsigned char *p;
struct cpio *cpio;
int bid;
+ (void)best_bid; /* UNUSED */
+
cpio = (struct cpio *)(a->format->data);
- if ((h = __archive_read_ahead(a, 6, NULL)) == NULL)
+ if ((p = __archive_read_ahead(a, 6, NULL)) == NULL)
return (-1);
- p = (const unsigned char *)h;
bid = 0;
if (memcmp(p, "070707", 6) == 0) {
/* ASCII cpio archive (odc, POSIX.1) */
@@ -196,6 +273,14 @@ archive_read_format_cpio_bid(struct archive_read *a)
* XXX TODO: More verification; Could check that only octal
* digits appear in appropriate header locations. XXX
*/
+ } else if (memcmp(p, "070727", 6) == 0) {
+ /* afio large ASCII cpio archive */
+ cpio->read_header = header_odc;
+ bid += 48;
+ /*
+ * XXX TODO: More verification; Could check that almost hex
+ * digits appear in appropriate header locations. XXX
+ */
} else if (memcmp(p, "070701", 6) == 0) {
/* ASCII cpio archive (SVR4 without CRC) */
cpio->read_header = header_newc;
@@ -230,16 +315,60 @@ archive_read_format_cpio_bid(struct archive_read *a)
}
static int
+archive_read_format_cpio_options(struct archive_read *a,
+ const char *key, const char *val)
+{
+ struct cpio *cpio;
+ int ret = ARCHIVE_FAILED;
+
+ cpio = (struct cpio *)(a->format->data);
+ if (strcmp(key, "compat-2x") == 0) {
+ /* Handle filnames as libarchive 2.x */
+ cpio->init_default_conversion = (val != NULL)?1:0;
+ ret = ARCHIVE_OK;
+ } else if (strcmp(key, "hdrcharset") == 0) {
+ if (val == NULL || val[0] == 0)
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "cpio: hdrcharset option needs a character-set name");
+ else {
+ cpio->opt_sconv =
+ archive_string_conversion_from_charset(
+ &a->archive, val, 0);
+ if (cpio->opt_sconv != NULL)
+ ret = ARCHIVE_OK;
+ else
+ ret = ARCHIVE_FATAL;
+ }
+ } else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "cpio: unknown keyword ``%s''", key);
+
+ return (ret);
+}
+
+static int
archive_read_format_cpio_read_header(struct archive_read *a,
struct archive_entry *entry)
{
struct cpio *cpio;
const void *h;
+ struct archive_string_conv *sconv;
size_t namelength;
size_t name_pad;
int r;
cpio = (struct cpio *)(a->format->data);
+ sconv = cpio->opt_sconv;
+ if (sconv == NULL) {
+ if (!cpio->init_default_conversion) {
+ cpio->sconv_default =
+ archive_string_default_conversion_for_read(
+ &(a->archive));
+ cpio->init_default_conversion = 1;
+ }
+ sconv = cpio->sconv_default;
+ }
+
r = (cpio->read_header(a, cpio, entry, &namelength, &name_pad));
if (r < ARCHIVE_WARN)
@@ -249,20 +378,42 @@ archive_read_format_cpio_read_header(struct archive_read *a,
h = __archive_read_ahead(a, namelength + name_pad, NULL);
if (h == NULL)
return (ARCHIVE_FATAL);
- __archive_read_consume(a, namelength + name_pad);
- archive_strncpy(&cpio->entry_name, (const char *)h, namelength);
- archive_entry_set_pathname(entry, cpio->entry_name.s);
+ if (archive_entry_copy_pathname_l(entry,
+ (const char *)h, namelength, sconv) != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Pathname can't be converted from %s to current locale.",
+ archive_string_conversion_charset_name(sconv));
+ r = ARCHIVE_WARN;
+ }
cpio->entry_offset = 0;
+ __archive_read_consume(a, namelength + name_pad);
+
/* If this is a symlink, read the link contents. */
if (archive_entry_filetype(entry) == AE_IFLNK) {
h = __archive_read_ahead(a, cpio->entry_bytes_remaining, NULL);
if (h == NULL)
return (ARCHIVE_FATAL);
+ if (archive_entry_copy_symlink_l(entry, (const char *)h,
+ cpio->entry_bytes_remaining, sconv) != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Linkname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Linkname can't be converted from %s to "
+ "current locale.",
+ archive_string_conversion_charset_name(sconv));
+ r = ARCHIVE_WARN;
+ }
__archive_read_consume(a, cpio->entry_bytes_remaining);
- archive_strncpy(&cpio->entry_linkname, (const char *)h,
- cpio->entry_bytes_remaining);
- archive_entry_set_symlink(entry, cpio->entry_linkname.s);
cpio->entry_bytes_remaining = 0;
}
@@ -279,19 +430,27 @@ archive_read_format_cpio_read_header(struct archive_read *a,
}
/* Detect and record hardlinks to previously-extracted entries. */
- record_hardlink(cpio, entry);
+ if (record_hardlink(a, cpio, entry) != ARCHIVE_OK) {
+ return (ARCHIVE_FATAL);
+ }
return (r);
}
static int
archive_read_format_cpio_read_data(struct archive_read *a,
- const void **buff, size_t *size, off_t *offset)
+ const void **buff, size_t *size, int64_t *offset)
{
ssize_t bytes_read;
struct cpio *cpio;
cpio = (struct cpio *)(a->format->data);
+
+ if (cpio->entry_bytes_unconsumed) {
+ __archive_read_consume(a, cpio->entry_bytes_unconsumed);
+ cpio->entry_bytes_unconsumed = 0;
+ }
+
if (cpio->entry_bytes_remaining > 0) {
*buff = __archive_read_ahead(a, 1, &bytes_read);
if (bytes_read <= 0)
@@ -299,21 +458,17 @@ archive_read_format_cpio_read_data(struct archive_read *a,
if (bytes_read > cpio->entry_bytes_remaining)
bytes_read = cpio->entry_bytes_remaining;
*size = bytes_read;
+ cpio->entry_bytes_unconsumed = bytes_read;
*offset = cpio->entry_offset;
cpio->entry_offset += bytes_read;
cpio->entry_bytes_remaining -= bytes_read;
- __archive_read_consume(a, bytes_read);
return (ARCHIVE_OK);
} else {
- while (cpio->entry_padding > 0) {
- *buff = __archive_read_ahead(a, 1, &bytes_read);
- if (bytes_read <= 0)
- return (ARCHIVE_FATAL);
- if (bytes_read > cpio->entry_padding)
- bytes_read = cpio->entry_padding;
- __archive_read_consume(a, bytes_read);
- cpio->entry_padding -= bytes_read;
+ if (cpio->entry_padding !=
+ __archive_read_consume(a, cpio->entry_padding)) {
+ return (ARCHIVE_FATAL);
}
+ cpio->entry_padding = 0;
*buff = NULL;
*size = 0;
*offset = cpio->entry_offset;
@@ -321,6 +476,22 @@ archive_read_format_cpio_read_data(struct archive_read *a,
}
}
+static int
+archive_read_format_cpio_skip(struct archive_read *a)
+{
+ struct cpio *cpio = (struct cpio *)(a->format->data);
+ int64_t to_skip = cpio->entry_bytes_remaining + cpio->entry_padding +
+ cpio->entry_bytes_unconsumed;
+
+ if (to_skip != __archive_read_consume(a, to_skip)) {
+ return (ARCHIVE_FATAL);
+ }
+ cpio->entry_bytes_remaining = 0;
+ cpio->entry_padding = 0;
+ cpio->entry_bytes_unconsumed = 0;
+ return (ARCHIVE_OK);
+}
+
/*
* Skip forward to the next cpio newc header by searching for the
* 07070[12] string. This should be generalized and merged with
@@ -349,7 +520,7 @@ find_newc_header(struct archive_read *a)
ssize_t bytes;
for (;;) {
- h = __archive_read_ahead(a, sizeof(struct cpio_newc_header), &bytes);
+ h = __archive_read_ahead(a, newc_header_size, &bytes);
if (h == NULL)
return (ARCHIVE_FATAL);
p = h;
@@ -358,19 +529,19 @@ find_newc_header(struct archive_read *a)
/* Try the typical case first, then go into the slow search.*/
if (memcmp("07070", p, 5) == 0
&& (p[5] == '1' || p[5] == '2')
- && is_hex(p, sizeof(struct cpio_newc_header)))
+ && is_hex(p, newc_header_size))
return (ARCHIVE_OK);
/*
* Scan ahead until we find something that looks
- * like an odc header.
+ * like a newc header.
*/
- while (p + sizeof(struct cpio_newc_header) <= q) {
+ while (p + newc_header_size <= q) {
switch (p[5]) {
case '1':
case '2':
if (memcmp("07070", p, 5) == 0
- && is_hex(p, sizeof(struct cpio_newc_header))) {
+ && is_hex(p, newc_header_size)) {
skip = p - (const char *)h;
__archive_read_consume(a, skip);
skipped += skip;
@@ -405,7 +576,7 @@ header_newc(struct archive_read *a, struct cpio *cpio,
struct archive_entry *entry, size_t *namelength, size_t *name_pad)
{
const void *h;
- const struct cpio_newc_header *header;
+ const char *header;
int r;
r = find_newc_header(a);
@@ -413,35 +584,34 @@ header_newc(struct archive_read *a, struct cpio *cpio,
return (r);
/* Read fixed-size portion of header. */
- h = __archive_read_ahead(a, sizeof(struct cpio_newc_header), NULL);
+ h = __archive_read_ahead(a, newc_header_size, NULL);
if (h == NULL)
return (ARCHIVE_FATAL);
- __archive_read_consume(a, sizeof(struct cpio_newc_header));
/* Parse out hex fields. */
- header = (const struct cpio_newc_header *)h;
+ header = (const char *)h;
- if (memcmp(header->c_magic, "070701", 6) == 0) {
+ if (memcmp(header + newc_magic_offset, "070701", 6) == 0) {
a->archive.archive_format = ARCHIVE_FORMAT_CPIO_SVR4_NOCRC;
a->archive.archive_format_name = "ASCII cpio (SVR4 with no CRC)";
- } else if (memcmp(header->c_magic, "070702", 6) == 0) {
+ } else if (memcmp(header + newc_magic_offset, "070702", 6) == 0) {
a->archive.archive_format = ARCHIVE_FORMAT_CPIO_SVR4_CRC;
a->archive.archive_format_name = "ASCII cpio (SVR4 with CRC)";
} else {
/* TODO: Abort here? */
}
- archive_entry_set_devmajor(entry, atol16(header->c_devmajor, sizeof(header->c_devmajor)));
- archive_entry_set_devminor(entry, atol16(header->c_devminor, sizeof(header->c_devminor)));
- archive_entry_set_ino(entry, atol16(header->c_ino, sizeof(header->c_ino)));
- archive_entry_set_mode(entry, atol16(header->c_mode, sizeof(header->c_mode)));
- archive_entry_set_uid(entry, atol16(header->c_uid, sizeof(header->c_uid)));
- archive_entry_set_gid(entry, atol16(header->c_gid, sizeof(header->c_gid)));
- archive_entry_set_nlink(entry, atol16(header->c_nlink, sizeof(header->c_nlink)));
- archive_entry_set_rdevmajor(entry, atol16(header->c_rdevmajor, sizeof(header->c_rdevmajor)));
- archive_entry_set_rdevminor(entry, atol16(header->c_rdevminor, sizeof(header->c_rdevminor)));
- archive_entry_set_mtime(entry, atol16(header->c_mtime, sizeof(header->c_mtime)), 0);
- *namelength = atol16(header->c_namesize, sizeof(header->c_namesize));
+ archive_entry_set_devmajor(entry, atol16(header + newc_devmajor_offset, newc_devmajor_size));
+ archive_entry_set_devminor(entry, atol16(header + newc_devminor_offset, newc_devminor_size));
+ archive_entry_set_ino(entry, atol16(header + newc_ino_offset, newc_ino_size));
+ archive_entry_set_mode(entry, atol16(header + newc_mode_offset, newc_mode_size));
+ archive_entry_set_uid(entry, atol16(header + newc_uid_offset, newc_uid_size));
+ archive_entry_set_gid(entry, atol16(header + newc_gid_offset, newc_gid_size));
+ archive_entry_set_nlink(entry, atol16(header + newc_nlink_offset, newc_nlink_size));
+ archive_entry_set_rdevmajor(entry, atol16(header + newc_rdevmajor_offset, newc_rdevmajor_size));
+ archive_entry_set_rdevminor(entry, atol16(header + newc_rdevminor_offset, newc_rdevminor_size));
+ archive_entry_set_mtime(entry, atol16(header + newc_mtime_offset, newc_mtime_size), 0);
+ *namelength = atol16(header + newc_namesize_offset, newc_namesize_size);
/* Pad name to 2 more than a multiple of 4. */
*name_pad = (2 - *namelength) & 3;
@@ -451,10 +621,11 @@ header_newc(struct archive_read *a, struct cpio *cpio,
* size.
*/
cpio->entry_bytes_remaining =
- atol16(header->c_filesize, sizeof(header->c_filesize));
+ atol16(header + newc_filesize_offset, newc_filesize_size);
archive_entry_set_size(entry, cpio->entry_bytes_remaining);
/* Pad file contents to a multiple of 4. */
cpio->entry_padding = 3 & -cpio->entry_bytes_remaining;
+ __archive_read_consume(a, newc_header_size);
return (r);
}
@@ -476,6 +647,27 @@ is_octal(const char *p, size_t len)
}
static int
+is_afio_large(const char *h, size_t len)
+{
+ if (len < afiol_header_size)
+ return (0);
+ if (h[afiol_ino_m_offset] != 'm'
+ || h[afiol_mtime_n_offset] != 'n'
+ || h[afiol_xsize_s_offset] != 's'
+ || h[afiol_filesize_c_offset] != ':')
+ return (0);
+ if (!is_hex(h + afiol_dev_offset, afiol_ino_m_offset - afiol_dev_offset))
+ return (0);
+ if (!is_hex(h + afiol_mode_offset, afiol_mtime_n_offset - afiol_mode_offset))
+ return (0);
+ if (!is_hex(h + afiol_namesize_offset, afiol_xsize_s_offset - afiol_namesize_offset))
+ return (0);
+ if (!is_hex(h + afiol_filesize_offset, afiol_filesize_size))
+ return (0);
+ return (1);
+}
+
+static int
find_odc_header(struct archive_read *a)
{
const void *h;
@@ -484,29 +676,37 @@ find_odc_header(struct archive_read *a)
ssize_t bytes;
for (;;) {
- h = __archive_read_ahead(a, sizeof(struct cpio_odc_header), &bytes);
+ h = __archive_read_ahead(a, odc_header_size, &bytes);
if (h == NULL)
return (ARCHIVE_FATAL);
p = h;
q = p + bytes;
/* Try the typical case first, then go into the slow search.*/
- if (memcmp("070707", p, 6) == 0
- && is_octal(p, sizeof(struct cpio_odc_header)))
+ if (memcmp("070707", p, 6) == 0 && is_octal(p, odc_header_size))
+ return (ARCHIVE_OK);
+ if (memcmp("070727", p, 6) == 0 && is_afio_large(p, bytes)) {
+ a->archive.archive_format = ARCHIVE_FORMAT_CPIO_AFIO_LARGE;
return (ARCHIVE_OK);
+ }
/*
* Scan ahead until we find something that looks
* like an odc header.
*/
- while (p + sizeof(struct cpio_odc_header) <= q) {
+ while (p + odc_header_size <= q) {
switch (p[5]) {
case '7':
- if (memcmp("070707", p, 6) == 0
- && is_octal(p, sizeof(struct cpio_odc_header))) {
+ if ((memcmp("070707", p, 6) == 0
+ && is_octal(p, odc_header_size))
+ || (memcmp("070727", p, 6) == 0
+ && is_afio_large(p, q - p))) {
skip = p - (const char *)h;
__archive_read_consume(a, skip);
skipped += skip;
+ if (p[4] == '2')
+ a->archive.archive_format =
+ ARCHIVE_FORMAT_CPIO_AFIO_LARGE;
if (skipped > 0) {
archive_set_error(&a->archive,
0,
@@ -539,7 +739,7 @@ header_odc(struct archive_read *a, struct cpio *cpio,
{
const void *h;
int r;
- const struct cpio_odc_header *header;
+ const char *header;
a->archive.archive_format = ARCHIVE_FORMAT_CPIO_POSIX;
a->archive.archive_format_name = "POSIX octet-oriented cpio";
@@ -549,24 +749,31 @@ header_odc(struct archive_read *a, struct cpio *cpio,
if (r < ARCHIVE_WARN)
return (r);
+ if (a->archive.archive_format == ARCHIVE_FORMAT_CPIO_AFIO_LARGE) {
+ int r2 = (header_afiol(a, cpio, entry, namelength, name_pad));
+ if (r2 == ARCHIVE_OK)
+ return (r);
+ else
+ return (r2);
+ }
+
/* Read fixed-size portion of header. */
- h = __archive_read_ahead(a, sizeof(struct cpio_odc_header), NULL);
+ h = __archive_read_ahead(a, odc_header_size, NULL);
if (h == NULL)
return (ARCHIVE_FATAL);
- __archive_read_consume(a, sizeof(struct cpio_odc_header));
/* Parse out octal fields. */
- header = (const struct cpio_odc_header *)h;
-
- archive_entry_set_dev(entry, atol8(header->c_dev, sizeof(header->c_dev)));
- archive_entry_set_ino(entry, atol8(header->c_ino, sizeof(header->c_ino)));
- archive_entry_set_mode(entry, atol8(header->c_mode, sizeof(header->c_mode)));
- archive_entry_set_uid(entry, atol8(header->c_uid, sizeof(header->c_uid)));
- archive_entry_set_gid(entry, atol8(header->c_gid, sizeof(header->c_gid)));
- archive_entry_set_nlink(entry, atol8(header->c_nlink, sizeof(header->c_nlink)));
- archive_entry_set_rdev(entry, atol8(header->c_rdev, sizeof(header->c_rdev)));
- archive_entry_set_mtime(entry, atol8(header->c_mtime, sizeof(header->c_mtime)), 0);
- *namelength = atol8(header->c_namesize, sizeof(header->c_namesize));
+ header = (const char *)h;
+
+ archive_entry_set_dev(entry, atol8(header + odc_dev_offset, odc_dev_size));
+ archive_entry_set_ino(entry, atol8(header + odc_ino_offset, odc_ino_size));
+ archive_entry_set_mode(entry, atol8(header + odc_mode_offset, odc_mode_size));
+ archive_entry_set_uid(entry, atol8(header + odc_uid_offset, odc_uid_size));
+ archive_entry_set_gid(entry, atol8(header + odc_gid_offset, odc_gid_size));
+ archive_entry_set_nlink(entry, atol8(header + odc_nlink_offset, odc_nlink_size));
+ archive_entry_set_rdev(entry, atol8(header + odc_rdev_offset, odc_rdev_size));
+ archive_entry_set_mtime(entry, atol8(header + odc_mtime_offset, odc_mtime_size), 0);
+ *namelength = atol8(header + odc_namesize_offset, odc_namesize_size);
*name_pad = 0; /* No padding of filename. */
/*
@@ -575,45 +782,91 @@ header_odc(struct archive_read *a, struct cpio *cpio,
* size.
*/
cpio->entry_bytes_remaining =
- atol8(header->c_filesize, sizeof(header->c_filesize));
+ atol8(header + odc_filesize_offset, odc_filesize_size);
archive_entry_set_size(entry, cpio->entry_bytes_remaining);
cpio->entry_padding = 0;
+ __archive_read_consume(a, odc_header_size);
return (r);
}
+/*
+ * NOTE: if a filename suffix is ".z", it is the file gziped by afio.
+ * it would be nice that we can show uncompressed file size and we can
+ * uncompressed file contents automatically, unfortunately we have nothing
+ * to get a uncompressed file size while reading each header. it means
+ * we also cannot uncompressed file contens under the our framework.
+ */
+static int
+header_afiol(struct archive_read *a, struct cpio *cpio,
+ struct archive_entry *entry, size_t *namelength, size_t *name_pad)
+{
+ const void *h;
+ const char *header;
+
+ a->archive.archive_format = ARCHIVE_FORMAT_CPIO_AFIO_LARGE;
+ a->archive.archive_format_name = "afio large ASCII";
+
+ /* Read fixed-size portion of header. */
+ h = __archive_read_ahead(a, afiol_header_size, NULL);
+ if (h == NULL)
+ return (ARCHIVE_FATAL);
+
+ /* Parse out octal fields. */
+ header = (const char *)h;
+
+ archive_entry_set_dev(entry, atol16(header + afiol_dev_offset, afiol_dev_size));
+ archive_entry_set_ino(entry, atol16(header + afiol_ino_offset, afiol_ino_size));
+ archive_entry_set_mode(entry, atol8(header + afiol_mode_offset, afiol_mode_size));
+ archive_entry_set_uid(entry, atol16(header + afiol_uid_offset, afiol_uid_size));
+ archive_entry_set_gid(entry, atol16(header + afiol_gid_offset, afiol_gid_size));
+ archive_entry_set_nlink(entry, atol16(header + afiol_nlink_offset, afiol_nlink_size));
+ archive_entry_set_rdev(entry, atol16(header + afiol_rdev_offset, afiol_rdev_size));
+ archive_entry_set_mtime(entry, atol16(header + afiol_mtime_offset, afiol_mtime_size), 0);
+ *namelength = atol16(header + afiol_namesize_offset, afiol_namesize_size);
+ *name_pad = 0; /* No padding of filename. */
+
+ cpio->entry_bytes_remaining =
+ atol16(header + afiol_filesize_offset, afiol_filesize_size);
+ archive_entry_set_size(entry, cpio->entry_bytes_remaining);
+ cpio->entry_padding = 0;
+ __archive_read_consume(a, afiol_header_size);
+ return (ARCHIVE_OK);
+}
+
+
static int
header_bin_le(struct archive_read *a, struct cpio *cpio,
struct archive_entry *entry, size_t *namelength, size_t *name_pad)
{
const void *h;
- const struct cpio_bin_header *header;
+ const unsigned char *header;
a->archive.archive_format = ARCHIVE_FORMAT_CPIO_BIN_LE;
a->archive.archive_format_name = "cpio (little-endian binary)";
/* Read fixed-size portion of header. */
- h = __archive_read_ahead(a, sizeof(struct cpio_bin_header), NULL);
+ h = __archive_read_ahead(a, bin_header_size, NULL);
if (h == NULL)
return (ARCHIVE_FATAL);
- __archive_read_consume(a, sizeof(struct cpio_bin_header));
/* Parse out binary fields. */
- header = (const struct cpio_bin_header *)h;
-
- archive_entry_set_dev(entry, header->c_dev[0] + header->c_dev[1] * 256);
- archive_entry_set_ino(entry, header->c_ino[0] + header->c_ino[1] * 256);
- archive_entry_set_mode(entry, header->c_mode[0] + header->c_mode[1] * 256);
- archive_entry_set_uid(entry, header->c_uid[0] + header->c_uid[1] * 256);
- archive_entry_set_gid(entry, header->c_gid[0] + header->c_gid[1] * 256);
- archive_entry_set_nlink(entry, header->c_nlink[0] + header->c_nlink[1] * 256);
- archive_entry_set_rdev(entry, header->c_rdev[0] + header->c_rdev[1] * 256);
- archive_entry_set_mtime(entry, le4(header->c_mtime), 0);
- *namelength = header->c_namesize[0] + header->c_namesize[1] * 256;
+ header = (const unsigned char *)h;
+
+ archive_entry_set_dev(entry, header[bin_dev_offset] + header[bin_dev_offset + 1] * 256);
+ archive_entry_set_ino(entry, header[bin_ino_offset] + header[bin_ino_offset + 1] * 256);
+ archive_entry_set_mode(entry, header[bin_mode_offset] + header[bin_mode_offset + 1] * 256);
+ archive_entry_set_uid(entry, header[bin_uid_offset] + header[bin_uid_offset + 1] * 256);
+ archive_entry_set_gid(entry, header[bin_gid_offset] + header[bin_gid_offset + 1] * 256);
+ archive_entry_set_nlink(entry, header[bin_nlink_offset] + header[bin_nlink_offset + 1] * 256);
+ archive_entry_set_rdev(entry, header[bin_rdev_offset] + header[bin_rdev_offset + 1] * 256);
+ archive_entry_set_mtime(entry, le4(header + bin_mtime_offset), 0);
+ *namelength = header[bin_namesize_offset] + header[bin_namesize_offset + 1] * 256;
*name_pad = *namelength & 1; /* Pad to even. */
- cpio->entry_bytes_remaining = le4(header->c_filesize);
+ cpio->entry_bytes_remaining = le4(header + bin_filesize_offset);
archive_entry_set_size(entry, cpio->entry_bytes_remaining);
cpio->entry_padding = cpio->entry_bytes_remaining & 1; /* Pad to even. */
+ __archive_read_consume(a, bin_header_size);
return (ARCHIVE_OK);
}
@@ -622,33 +875,34 @@ header_bin_be(struct archive_read *a, struct cpio *cpio,
struct archive_entry *entry, size_t *namelength, size_t *name_pad)
{
const void *h;
- const struct cpio_bin_header *header;
+ const unsigned char *header;
a->archive.archive_format = ARCHIVE_FORMAT_CPIO_BIN_BE;
a->archive.archive_format_name = "cpio (big-endian binary)";
/* Read fixed-size portion of header. */
- h = __archive_read_ahead(a, sizeof(struct cpio_bin_header), NULL);
+ h = __archive_read_ahead(a, bin_header_size, NULL);
if (h == NULL)
return (ARCHIVE_FATAL);
- __archive_read_consume(a, sizeof(struct cpio_bin_header));
/* Parse out binary fields. */
- header = (const struct cpio_bin_header *)h;
- archive_entry_set_dev(entry, header->c_dev[0] * 256 + header->c_dev[1]);
- archive_entry_set_ino(entry, header->c_ino[0] * 256 + header->c_ino[1]);
- archive_entry_set_mode(entry, header->c_mode[0] * 256 + header->c_mode[1]);
- archive_entry_set_uid(entry, header->c_uid[0] * 256 + header->c_uid[1]);
- archive_entry_set_gid(entry, header->c_gid[0] * 256 + header->c_gid[1]);
- archive_entry_set_nlink(entry, header->c_nlink[0] * 256 + header->c_nlink[1]);
- archive_entry_set_rdev(entry, header->c_rdev[0] * 256 + header->c_rdev[1]);
- archive_entry_set_mtime(entry, be4(header->c_mtime), 0);
- *namelength = header->c_namesize[0] * 256 + header->c_namesize[1];
+ header = (const unsigned char *)h;
+
+ archive_entry_set_dev(entry, header[bin_dev_offset] * 256 + header[bin_dev_offset + 1]);
+ archive_entry_set_ino(entry, header[bin_ino_offset] * 256 + header[bin_ino_offset + 1]);
+ archive_entry_set_mode(entry, header[bin_mode_offset] * 256 + header[bin_mode_offset + 1]);
+ archive_entry_set_uid(entry, header[bin_uid_offset] * 256 + header[bin_uid_offset + 1]);
+ archive_entry_set_gid(entry, header[bin_gid_offset] * 256 + header[bin_gid_offset + 1]);
+ archive_entry_set_nlink(entry, header[bin_nlink_offset] * 256 + header[bin_nlink_offset + 1]);
+ archive_entry_set_rdev(entry, header[bin_rdev_offset] * 256 + header[bin_rdev_offset + 1]);
+ archive_entry_set_mtime(entry, be4(header + bin_mtime_offset), 0);
+ *namelength = header[bin_namesize_offset] * 256 + header[bin_namesize_offset + 1];
*name_pad = *namelength & 1; /* Pad to even. */
- cpio->entry_bytes_remaining = be4(header->c_filesize);
+ cpio->entry_bytes_remaining = be4(header + bin_filesize_offset);
archive_entry_set_size(entry, cpio->entry_bytes_remaining);
cpio->entry_padding = cpio->entry_bytes_remaining & 1; /* Pad to even. */
+ __archive_read_consume(a, bin_header_size);
return (ARCHIVE_OK);
}
@@ -667,7 +921,6 @@ archive_read_format_cpio_cleanup(struct archive_read *a)
free(cpio->links_head);
cpio->links_head = lp;
}
- archive_string_free(&cpio->entry_name);
free(cpio);
(a->format->data) = NULL;
return (ARCHIVE_OK);
@@ -733,15 +986,16 @@ atol16(const char *p, unsigned char_cnt)
return (l);
}
-static void
-record_hardlink(struct cpio *cpio, struct archive_entry *entry)
+static int
+record_hardlink(struct archive_read *a,
+ struct cpio *cpio, struct archive_entry *entry)
{
struct links_entry *le;
dev_t dev;
int64_t ino;
if (archive_entry_nlink(entry) <= 1)
- return;
+ return (ARCHIVE_OK);
dev = archive_entry_dev(entry);
ino = archive_entry_ino64(entry);
@@ -765,13 +1019,16 @@ record_hardlink(struct cpio *cpio, struct archive_entry *entry)
free(le);
}
- return;
+ return (ARCHIVE_OK);
}
}
le = (struct links_entry *)malloc(sizeof(struct links_entry));
- if (le == NULL)
- __archive_errx(1, "Out of memory adding file to list");
+ if (le == NULL) {
+ archive_set_error(&a->archive,
+ ENOMEM, "Out of memory adding file to list");
+ return (ARCHIVE_FATAL);
+ }
if (cpio->links_head != NULL)
cpio->links_head->previous = le;
le->next = cpio->links_head;
@@ -781,6 +1038,11 @@ record_hardlink(struct cpio *cpio, struct archive_entry *entry)
le->ino = ino;
le->links = archive_entry_nlink(entry) - 1;
le->name = strdup(archive_entry_pathname(entry));
- if (le->name == NULL)
- __archive_errx(1, "Out of memory adding file to list");
+ if (le->name == NULL) {
+ archive_set_error(&a->archive,
+ ENOMEM, "Out of memory adding file to list");
+ return (ARCHIVE_FATAL);
+ }
+
+ return (ARCHIVE_OK);
}
diff --git a/libarchive/archive_read_support_format_empty.c b/libarchive/archive_read_support_format_empty.c
index 518fdcb4913f..3dc2196cb99e 100644
--- a/libarchive/archive_read_support_format_empty.c
+++ b/libarchive/archive_read_support_format_empty.c
@@ -31,9 +31,9 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_empty.c 1915
#include "archive_private.h"
#include "archive_read_private.h"
-static int archive_read_format_empty_bid(struct archive_read *);
+static int archive_read_format_empty_bid(struct archive_read *, int);
static int archive_read_format_empty_read_data(struct archive_read *,
- const void **, size_t *, off_t *);
+ const void **, size_t *, int64_t *);
static int archive_read_format_empty_read_header(struct archive_read *,
struct archive_entry *);
int
@@ -42,6 +42,9 @@ archive_read_support_format_empty(struct archive *_a)
struct archive_read *a = (struct archive_read *)_a;
int r;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_empty");
+
r = __archive_read_register_format(a,
NULL,
NULL,
@@ -57,14 +60,11 @@ archive_read_support_format_empty(struct archive *_a)
static int
-archive_read_format_empty_bid(struct archive_read *a)
+archive_read_format_empty_bid(struct archive_read *a, int best_bid)
{
- ssize_t avail;
-
- (void)__archive_read_ahead(a, 1, &avail);
- if (avail != 0)
- return (-1);
- return (1);
+ if (best_bid < 1 && __archive_read_ahead(a, 1, NULL) == NULL)
+ return (1);
+ return (-1);
}
static int
@@ -82,7 +82,7 @@ archive_read_format_empty_read_header(struct archive_read *a,
static int
archive_read_format_empty_read_data(struct archive_read *a,
- const void **buff, size_t *size, off_t *offset)
+ const void **buff, size_t *size, int64_t *offset)
{
(void)a; /* UNUSED */
(void)buff; /* UNUSED */
diff --git a/libarchive/archive_read_support_format_iso9660.c b/libarchive/archive_read_support_format_iso9660.c
index 52944e0ae40b..739bf9134124 100644
--- a/libarchive/archive_read_support_format_iso9660.c
+++ b/libarchive/archive_read_support_format_iso9660.c
@@ -47,6 +47,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_iso9660.c 20
#include "archive.h"
#include "archive_endian.h"
#include "archive_entry.h"
+#include "archive_entry_locale.h"
#include "archive_private.h"
#include "archive_read_private.h"
#include "archive_string.h"
@@ -285,6 +286,8 @@ struct file_info {
int64_t number;
int nlinks;
struct archive_string name; /* Pathname */
+ unsigned char *utf16be_name;
+ size_t utf16be_bytes;
char name_continues; /* Non-zero if name continues */
struct archive_string symlink;
char symlink_continues; /* Non-zero if link continues */
@@ -357,22 +360,34 @@ struct iso9660 {
uint32_t size;
} primary, joliet;
- off_t entry_sparse_offset;
+ int64_t entry_sparse_offset;
int64_t entry_bytes_remaining;
+ size_t entry_bytes_unconsumed;
struct zisofs entry_zisofs;
struct content *entry_content;
+ struct archive_string_conv *sconv_utf16be;
+ /*
+ * Buffers for a full pathname in UTF-16BE in Joliet extensions.
+ */
+#define UTF16_NAME_MAX 1024
+ unsigned char *utf16be_path;
+ size_t utf16be_path_len;
+ unsigned char *utf16be_previous_path;
+ size_t utf16be_previous_path_len;
};
-static int archive_read_format_iso9660_bid(struct archive_read *);
+static int archive_read_format_iso9660_bid(struct archive_read *, int);
static int archive_read_format_iso9660_options(struct archive_read *,
const char *, const char *);
static int archive_read_format_iso9660_cleanup(struct archive_read *);
static int archive_read_format_iso9660_read_data(struct archive_read *,
- const void **, size_t *, off_t *);
+ const void **, size_t *, int64_t *);
static int archive_read_format_iso9660_read_data_skip(struct archive_read *);
static int archive_read_format_iso9660_read_header(struct archive_read *,
struct archive_entry *);
static const char *build_pathname(struct archive_string *, struct file_info *);
+static int build_pathname_utf16be(unsigned char *, size_t, size_t *,
+ struct file_info *);
#if DEBUG
static void dump_isodirrec(FILE *, const unsigned char *isodirrec);
#endif
@@ -388,8 +403,8 @@ static int isEVD(struct iso9660 *, const unsigned char *);
static int isPVD(struct iso9660 *, const unsigned char *);
static int next_cache_entry(struct archive_read *, struct iso9660 *,
struct file_info **);
-static int next_entry_seek(struct archive_read *a, struct iso9660 *iso9660,
- struct file_info **pfile);
+static int next_entry_seek(struct archive_read *, struct iso9660 *,
+ struct file_info **);
static struct file_info *
parse_file_info(struct archive_read *a,
struct file_info *parent, const unsigned char *isodirrec);
@@ -417,12 +432,12 @@ static inline struct file_info * rede_get_entry(struct file_info *);
static inline void cache_add_entry(struct iso9660 *iso9660,
struct file_info *file);
static inline struct file_info *cache_get_entry(struct iso9660 *iso9660);
-static void heap_add_entry(struct heap_queue *heap,
+static int heap_add_entry(struct archive_read *a, struct heap_queue *heap,
struct file_info *file, uint64_t key);
static struct file_info *heap_get_entry(struct heap_queue *heap);
-#define add_entry(iso9660, file) \
- heap_add_entry(&((iso9660)->pending_files), file, file->offset)
+#define add_entry(arch, iso9660, file) \
+ heap_add_entry(arch, &((iso9660)->pending_files), file, file->offset)
#define next_entry(iso9660) \
heap_get_entry(&((iso9660)->pending_files))
@@ -433,12 +448,15 @@ archive_read_support_format_iso9660(struct archive *_a)
struct iso9660 *iso9660;
int r;
- iso9660 = (struct iso9660 *)malloc(sizeof(*iso9660));
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_iso9660");
+
+ iso9660 = (struct iso9660 *)calloc(1, sizeof(*iso9660));
if (iso9660 == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Can't allocate iso9660 data");
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate iso9660 data");
return (ARCHIVE_FATAL);
}
- memset(iso9660, 0, sizeof(*iso9660));
iso9660->magic = ISO9660_MAGIC;
iso9660->cache_files.first = NULL;
iso9660->cache_files.last = &(iso9660->cache_files.first);
@@ -468,14 +486,18 @@ archive_read_support_format_iso9660(struct archive *_a)
static int
-archive_read_format_iso9660_bid(struct archive_read *a)
+archive_read_format_iso9660_bid(struct archive_read *a, int best_bid)
{
struct iso9660 *iso9660;
ssize_t bytes_read;
- const void *h;
const unsigned char *p;
int seenTerminator;
+ /* If there's already a better bid than we can ever
+ make, don't bother testing. */
+ if (best_bid > 48)
+ return (-1);
+
iso9660 = (struct iso9660 *)(a->format->data);
/*
@@ -484,12 +506,11 @@ archive_read_format_iso9660_bid(struct archive_read *a)
* if the I/O layer gives us more, we'll take it.
*/
#define RESERVED_AREA (SYSTEM_AREA_BLOCK * LOGICAL_BLOCK_SIZE)
- h = __archive_read_ahead(a,
+ p = __archive_read_ahead(a,
RESERVED_AREA + 8 * LOGICAL_BLOCK_SIZE,
&bytes_read);
- if (h == NULL)
+ if (p == NULL)
return (-1);
- p = (const unsigned char *)h;
/* Skip the reserved area. */
bytes_read -= RESERVED_AREA;
@@ -505,10 +526,8 @@ archive_read_format_iso9660_bid(struct archive_read *a)
/* Standard Identifier must be "CD001" */
if (memcmp(p + 1, "CD001", 5) != 0)
return (0);
- if (!iso9660->primary.location) {
- if (isPVD(iso9660, p))
- continue;
- }
+ if (isPVD(iso9660, p))
+ continue;
if (!iso9660->joliet.location) {
if (isJolietSVD(iso9660, p))
continue;
@@ -564,7 +583,7 @@ archive_read_format_iso9660_options(struct archive_read *a,
/* Note: The "warn" return is just to inform the options
* supervisor that we didn't handle it. It will generate
- * a suitable error if noone used this option. */
+ * a suitable error if no one used this option. */
return (ARCHIVE_WARN);
}
@@ -893,8 +912,10 @@ isPVD(struct iso9660 *iso9660, const unsigned char *h)
return (0);
/* Reserved field must be 0. */
+ /* But accept NetBSD/FreeBSD "makefs" images with 0x20 here. */
for (i = 0; i < PVD_reserved4_size; ++i)
- if (h[PVD_reserved4_offset + i] != 0)
+ if (h[PVD_reserved4_offset + i] != 0
+ && h[PVD_reserved4_offset + i] != 0x20)
return (0);
/* Reserved field must be 0. */
@@ -910,11 +931,13 @@ isPVD(struct iso9660 *iso9660, const unsigned char *h)
if (p[DR_length_offset] != 34)
return (0);
- iso9660->logical_block_size = logical_block_size;
- iso9660->volume_block = volume_block;
- iso9660->volume_size = logical_block_size * (uint64_t)volume_block;
- iso9660->primary.location = archive_le32dec(p + DR_extent_offset);
- iso9660->primary.size = archive_le32dec(p + DR_size_offset);
+ if (!iso9660->primary.location) {
+ iso9660->logical_block_size = logical_block_size;
+ iso9660->volume_block = volume_block;
+ iso9660->volume_size = logical_block_size * (uint64_t)volume_block;
+ iso9660->primary.location = archive_le32dec(p + DR_extent_offset);
+ iso9660->primary.size = archive_le32dec(p + DR_size_offset);
+ }
return (48);
}
@@ -925,7 +948,7 @@ read_children(struct archive_read *a, struct file_info *parent)
struct iso9660 *iso9660;
const unsigned char *b, *p;
struct file_info *multi;
- size_t step;
+ size_t step, skip_size;
iso9660 = (struct iso9660 *)(a->format->data);
if (iso9660->current_position > parent->offset) {
@@ -946,7 +969,7 @@ read_children(struct archive_read *a, struct file_info *parent)
int64_t skipsize;
skipsize = parent->offset - iso9660->current_position;
- skipsize = __archive_read_skip(a, skipsize);
+ skipsize = __archive_read_consume(a, skipsize);
if (skipsize < 0)
return ((int)skipsize);
iso9660->current_position = parent->offset;
@@ -961,9 +984,9 @@ read_children(struct archive_read *a, struct file_info *parent)
"ISO9660 directory list");
return (ARCHIVE_FATAL);
}
- __archive_read_consume(a, step);
iso9660->current_position += step;
multi = NULL;
+ skip_size = step;
while (step) {
p = b;
b += iso9660->logical_block_size;
@@ -985,8 +1008,10 @@ read_children(struct archive_read *a, struct file_info *parent)
&& *(p + DR_name_offset) == '\001')
continue;
child = parse_file_info(a, parent, p);
- if (child == NULL)
+ if (child == NULL) {
+ __archive_read_consume(a, skip_size);
return (ARCHIVE_FATAL);
+ }
if (child->cl_offset == 0 &&
(child->multi_extent || multi != NULL)) {
struct content *con;
@@ -1001,8 +1026,8 @@ read_children(struct archive_read *a, struct file_info *parent)
if (con == NULL) {
archive_set_error(
&a->archive, ENOMEM,
- "No memory for "
- "multi extent");
+ "No memory for multi extent");
+ __archive_read_consume(a, skip_size);
return (ARCHIVE_FATAL);
}
con->offset = child->offset;
@@ -1010,18 +1035,23 @@ read_children(struct archive_read *a, struct file_info *parent)
con->next = NULL;
*multi->contents.last = con;
multi->contents.last = &(con->next);
- if (multi == child)
- add_entry(iso9660, child);
- else {
+ if (multi == child) {
+ if (add_entry(a, iso9660, child)
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ } else {
multi->size += child->size;
if (!child->multi_extent)
multi = NULL;
}
} else
- add_entry(iso9660, child);
+ if (add_entry(a, iso9660, child) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
}
}
+ __archive_read_consume(a, skip_size);
+
/* Read data which recorded by RRIP "CE" extension. */
if (read_CE(a, iso9660) != ARCHIVE_OK)
return (ARCHIVE_FATAL);
@@ -1059,7 +1089,7 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
vd = &(iso9660->joliet);
skipsize = LOGICAL_BLOCK_SIZE * vd->location;
- skipsize = __archive_read_skip(a, skipsize);
+ skipsize = __archive_read_consume(a, skipsize);
if (skipsize < 0)
return ((int)skipsize);
iso9660->current_position = skipsize;
@@ -1097,7 +1127,7 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
vd = &(iso9660->joliet);
skipsize = LOGICAL_BLOCK_SIZE * vd->location;
skipsize -= iso9660->current_position;
- skipsize = __archive_read_skip(a, skipsize);
+ skipsize = __archive_read_consume(a, skipsize);
if (skipsize < 0)
return ((int)skipsize);
iso9660->current_position += skipsize;
@@ -1110,7 +1140,6 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
"ISO9660 directory list");
return (ARCHIVE_FATAL);
}
- seenJoliet = iso9660->seenJoliet;/* Save flag. */
iso9660->seenJoliet = 0;
file = parse_file_info(a, NULL, block);
if (file == NULL)
@@ -1118,7 +1147,8 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
iso9660->seenJoliet = seenJoliet;
}
/* Store the root directory in the pending list. */
- add_entry(iso9660, file);
+ if (add_entry(a, iso9660, file) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
if (iso9660->seenRockridge) {
a->archive.archive_format =
ARCHIVE_FORMAT_ISO9660_ROCKRIDGE;
@@ -1127,17 +1157,82 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
}
}
+ file = NULL;/* Eliminate a warning. */
/* Get the next entry that appears after the current offset. */
r = next_entry_seek(a, iso9660, &file);
if (r != ARCHIVE_OK)
return (r);
+ if (iso9660->seenJoliet) {
+ /*
+ * Convert UTF-16BE of a filename to local locale MBS
+ * and store the result into a filename field.
+ */
+ if (iso9660->sconv_utf16be == NULL) {
+ iso9660->sconv_utf16be =
+ archive_string_conversion_from_charset(
+ &(a->archive), "UTF-16BE", 1);
+ if (iso9660->sconv_utf16be == NULL)
+ /* Coundn't allocate memory */
+ return (ARCHIVE_FATAL);
+ }
+ if (iso9660->utf16be_path == NULL) {
+ iso9660->utf16be_path = malloc(UTF16_NAME_MAX);
+ if (iso9660->utf16be_path == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory");
+ return (ARCHIVE_FATAL);
+ }
+ }
+ if (iso9660->utf16be_previous_path == NULL) {
+ iso9660->utf16be_previous_path = malloc(UTF16_NAME_MAX);
+ if (iso9660->utf16be_previous_path == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory");
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ iso9660->utf16be_path_len = 0;
+ if (build_pathname_utf16be(iso9660->utf16be_path,
+ UTF16_NAME_MAX, &(iso9660->utf16be_path_len), file) != 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Pathname is too long");
+ }
+
+ r = archive_entry_copy_pathname_l(entry,
+ (const char *)iso9660->utf16be_path,
+ iso9660->utf16be_path_len,
+ iso9660->sconv_utf16be);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory for Pathname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Pathname cannot be converted "
+ "from %s to current locale.",
+ archive_string_conversion_charset_name(
+ iso9660->sconv_utf16be));
+
+ rd_r = ARCHIVE_WARN;
+ }
+ } else {
+ archive_string_empty(&iso9660->pathname);
+ archive_entry_set_pathname(entry,
+ build_pathname(&iso9660->pathname, file));
+ }
+
iso9660->entry_bytes_remaining = file->size;
iso9660->entry_sparse_offset = 0; /* Offset for sparse-file-aware clients. */
if (file->offset + file->size > iso9660->volume_size) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "File is beyond end-of-media: %s", file->name.s);
+ "File is beyond end-of-media: %s",
+ archive_entry_pathname(entry));
iso9660->entry_bytes_remaining = 0;
iso9660->entry_sparse_offset = 0;
return (ARCHIVE_WARN);
@@ -1158,9 +1253,6 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
/* N.B.: Rock Ridge supports 64-bit device numbers. */
archive_entry_set_rdev(entry, (dev_t)file->rdev);
archive_entry_set_size(entry, iso9660->entry_bytes_remaining);
- archive_string_empty(&iso9660->pathname);
- archive_entry_set_pathname(entry,
- build_pathname(&iso9660->pathname, file));
if (file->symlink.s != NULL)
archive_entry_copy_symlink(entry, file->symlink.s);
@@ -1170,12 +1262,32 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
* original entry. */
if (file->number != -1 &&
file->number == iso9660->previous_number) {
- archive_entry_set_hardlink(entry,
- iso9660->previous_pathname.s);
+ if (iso9660->seenJoliet) {
+ r = archive_entry_copy_hardlink_l(entry,
+ (const char *)iso9660->utf16be_previous_path,
+ iso9660->utf16be_previous_path_len,
+ iso9660->sconv_utf16be);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory for Linkname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Linkname cannot be converted "
+ "from %s to current locale.",
+ archive_string_conversion_charset_name(
+ iso9660->sconv_utf16be));
+ rd_r = ARCHIVE_WARN;
+ }
+ } else
+ archive_entry_set_hardlink(entry,
+ iso9660->previous_pathname.s);
archive_entry_unset_size(entry);
iso9660->entry_bytes_remaining = 0;
iso9660->entry_sparse_offset = 0;
- return (ARCHIVE_OK);
+ return (rd_r);
}
/* Except for the hardlink case above, if the offset of the
@@ -1196,7 +1308,8 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
if ((file->mode & AE_IFMT) != AE_IFDIR &&
file->offset < iso9660->current_position) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Ignoring out-of-order file (%s) %jd < %jd",
+ "Ignoring out-of-order file @%jx (%s) %jd < %jd",
+ (intmax_t)file->number,
iso9660->pathname.s,
(intmax_t)file->offset,
(intmax_t)iso9660->current_position);
@@ -1224,7 +1337,13 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
}
iso9660->previous_number = file->number;
- archive_strcpy(&iso9660->previous_pathname, iso9660->pathname.s);
+ if (iso9660->seenJoliet) {
+ memcpy(iso9660->utf16be_previous_path, iso9660->utf16be_path,
+ iso9660->utf16be_path_len);
+ iso9660->utf16be_previous_path_len = iso9660->utf16be_path_len;
+ } else
+ archive_strcpy(
+ &iso9660->previous_pathname, iso9660->pathname.s);
/* Reset entry_bytes_remaining if the file is multi extent. */
iso9660->entry_content = file->contents.first;
@@ -1258,7 +1377,7 @@ archive_read_format_iso9660_read_data_skip(struct archive_read *a)
static int
zisofs_read_data(struct archive_read *a,
- const void **buff, size_t *size, off_t *offset)
+ const void **buff, size_t *size, int64_t *offset)
{
struct iso9660 *iso9660;
struct zisofs *zisofs;
@@ -1380,7 +1499,7 @@ zisofs_read_data(struct archive_read *a,
}
if (!zisofs->initialized)
- goto next_data; /* We need more datas. */
+ goto next_data; /* We need more data. */
}
/*
@@ -1391,21 +1510,26 @@ zisofs_read_data(struct archive_read *a,
if (zisofs->block_off + 4 >= zisofs->block_pointers_size) {
/* There isn't a pair of offsets. */
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
"Illegal zisofs block pointers");
return (ARCHIVE_FATAL);
}
- bst = archive_le32dec(zisofs->block_pointers + zisofs->block_off);
+ bst = archive_le32dec(
+ zisofs->block_pointers + zisofs->block_off);
if (bst != zisofs->pz_offset + (bytes_read - avail)) {
- /* TODO: Should we seek offset of current file by bst ? */
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ /* TODO: Should we seek offset of current file
+ * by bst ? */
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
"Illegal zisofs block pointers(cannot seek)");
return (ARCHIVE_FATAL);
}
bed = archive_le32dec(
zisofs->block_pointers + zisofs->block_off + 4);
if (bed < bst) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
"Illegal zisofs block pointers");
return (ARCHIVE_FATAL);
}
@@ -1428,7 +1552,7 @@ zisofs_read_data(struct archive_read *a,
}
/*
- * Make uncompressed datas.
+ * Make uncompressed data.
*/
if (zisofs->block_avail == 0) {
memset(zisofs->uncompressed_buffer, 0,
@@ -1467,7 +1591,7 @@ next_data:
iso9660->entry_bytes_remaining -= bytes_read;
iso9660->current_position += bytes_read;
zisofs->pz_offset += bytes_read;
- __archive_read_consume(a, bytes_read);
+ iso9660->entry_bytes_unconsumed += bytes_read;
return (ARCHIVE_OK);
}
@@ -1476,7 +1600,7 @@ next_data:
static int
zisofs_read_data(struct archive_read *a,
- const void **buff, size_t *size, off_t *offset)
+ const void **buff, size_t *size, int64_t *offset)
{
(void)buff;/* UNUSED */
@@ -1491,12 +1615,18 @@ zisofs_read_data(struct archive_read *a,
static int
archive_read_format_iso9660_read_data(struct archive_read *a,
- const void **buff, size_t *size, off_t *offset)
+ const void **buff, size_t *size, int64_t *offset)
{
ssize_t bytes_read;
struct iso9660 *iso9660;
iso9660 = (struct iso9660 *)(a->format->data);
+
+ if (iso9660->entry_bytes_unconsumed) {
+ __archive_read_consume(a, iso9660->entry_bytes_unconsumed);
+ iso9660->entry_bytes_unconsumed = 0;
+ }
+
if (iso9660->entry_bytes_remaining <= 0) {
if (iso9660->entry_content != NULL)
iso9660->entry_content = iso9660->entry_content->next;
@@ -1512,7 +1642,7 @@ archive_read_format_iso9660_read_data(struct archive_read *a,
step = iso9660->entry_content->offset -
iso9660->current_position;
- step = __archive_read_skip(a, step);
+ step = __archive_read_consume(a, step);
if (step < 0)
return ((int)step);
iso9660->current_position =
@@ -1546,8 +1676,8 @@ archive_read_format_iso9660_read_data(struct archive_read *a,
*offset = iso9660->entry_sparse_offset;
iso9660->entry_sparse_offset += bytes_read;
iso9660->entry_bytes_remaining -= bytes_read;
+ iso9660->entry_bytes_unconsumed = bytes_read;
iso9660->current_position += bytes_read;
- __archive_read_consume(a, bytes_read);
return (ARCHIVE_OK);
}
@@ -1575,6 +1705,8 @@ archive_read_format_iso9660_cleanup(struct archive_read *a)
}
}
#endif
+ free(iso9660->utf16be_path);
+ free(iso9660->utf16be_previous_path);
free(iso9660);
(a->format->data) = NULL;
return (r);
@@ -1629,15 +1761,21 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
"Invalid location of extent of file");
return (NULL);
}
+ /* Sanity check that location doesn't have a negative value
+ * when the file is not empty. it's too large. */
+ if (fsize != 0 && location < 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Invalid location of extent of file");
+ return (NULL);
+ }
/* Create a new file entry and copy data from the ISO dir record. */
- file = (struct file_info *)malloc(sizeof(*file));
+ file = (struct file_info *)calloc(1, sizeof(*file));
if (file == NULL) {
archive_set_error(&a->archive, ENOMEM,
"No memory for file entry");
return (NULL);
}
- memset(file, 0, sizeof(*file));
file->parent = parent;
file->offset = iso9660->logical_block_size * (uint64_t)location;
file->size = fsize;
@@ -1658,24 +1796,13 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
* names which are 103 UCS2 characters(206 bytes) by their
* option '-joliet-long'.
*/
- wchar_t wbuff[103+1], *wp;
- const unsigned char *c;
-
if (name_len > 206)
name_len = 206;
- /* convert BE UTF-16 to wchar_t */
- for (c = p, wp = wbuff;
- c < (p + name_len) &&
- wp < (wbuff + sizeof(wbuff)/sizeof(*wbuff) - 1);
- c += 2) {
- *wp++ = (((255 & (int)c[0]) << 8) | (255 & (int)c[1]));
- }
- *wp = L'\0';
+ name_len &= ~1;
-#if 0 /* untested code, is it at all useful on Joliet? */
/* trim trailing first version and dot from filename.
*
- * Remember we where in UTF-16BE land!
+ * Remember we were in UTF-16BE land!
* SEPARATOR 1 (.) and SEPARATOR 2 (;) are both
* 16 bits big endian characters on Joliet.
*
@@ -1684,18 +1811,21 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
* *, /, :, ;, ? and \.
*/
/* Chop off trailing ';1' from files. */
- if (*(wp-2) == ';' && *(wp-1) == '1') {
- wp-=2;
- *wp = L'\0';
- }
-
+ if (name_len > 4 && p[name_len-4] == 0 && p[name_len-3] == ';'
+ && p[name_len-2] == 0 && p[name_len-1] == '1')
+ name_len -= 4;
+#if 0 /* XXX: this somehow manages to strip of single-character file extensions, like '.c'. */
/* Chop off trailing '.' from filenames. */
- if (*(wp-1) == '.')
- *(--wp) = L'\0';
+ if (name_len > 2 && p[name_len-2] == 0 && p[name_len-1] == '.')
+ name_len -= 2;
#endif
-
- /* store the result in the file name field. */
- archive_strappend_w_utf8(&file->name, wbuff);
+ if ((file->utf16be_name = malloc(name_len)) == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory for file name");
+ return (NULL);
+ }
+ memcpy(file->utf16be_name, p, name_len);
+ file->utf16be_bytes = name_len;
} else {
/* Chop off trailing ';1' from files. */
if (name_len > 2 && p[name_len - 2] == ';' &&
@@ -1718,22 +1848,24 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
else
file->multi_extent = 0;
/*
- * Use location for file number.
- * File number is treated as inode number to find out harlink
- * target. If Rockridge extensions is being used, file number
- * will be overwritten by FILE SERIAL NUMBER of RRIP "PX"
- * extension.
- * NOTE: Old mkisofs did not record that FILE SERIAL NUMBER
+ * Use a location for the file number, which is treated as an inode
+ * number to find out hardlink target. If Rockridge extensions is
+ * being used, the file number will be overwritten by FILE SERIAL
+ * NUMBER of RRIP "PX" extension.
+ * Note: Old mkisofs did not record that FILE SERIAL NUMBER
* in ISO images.
+ * Note2: xorriso set 0 to the location of a symlink file.
*/
- if (file->size == 0 && location >= 0)
- /* If file->size is zero, its location points wrong place.
- * Dot not use it for file number.
- * When location has negative value, it can be used
- * for file number.
+ if (file->size == 0 && location >= 0) {
+ /* If file->size is zero, its location points wrong place,
+ * and so we should not use it for the file number.
+ * When the location has negative value, it can be used
+ * for the file number.
*/
file->number = -1;
- else
+ /* Do not appear before any directory entries. */
+ file->offset = -1;
+ } else
file->number = (int64_t)(uint32_t)location;
/* Rockridge extensions overwrite information from above. */
@@ -2120,9 +2252,13 @@ register_CE(struct archive_read *a, int32_t location,
offset = ((uint64_t)location) * (uint64_t)iso9660->logical_block_size;
if (((file->mode & AE_IFMT) == AE_IFREG &&
offset >= file->offset) ||
- offset < iso9660->current_position) {
+ offset < iso9660->current_position ||
+ (((uint64_t)file->ce_offset) + file->ce_size)
+ > iso9660->logical_block_size ||
+ offset + file->ce_offset + file->ce_size
+ > iso9660->volume_size) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Invalid location in SUSP \"CE\" extension");
+ "Invalid parameter in SUSP \"CE\" extension");
return (ARCHIVE_FATAL);
}
@@ -2136,11 +2272,15 @@ register_CE(struct archive_read *a, int32_t location,
else
new_size = heap->allocated * 2;
/* Overflow might keep us from growing the list. */
- if (new_size <= heap->allocated)
- __archive_errx(1, "Out of memory");
+ if (new_size <= heap->allocated) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
p = malloc(new_size * sizeof(p[0]));
- if (p == NULL)
- __archive_errx(1, "Out of memory");
+ if (p == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
if (heap->reqs != NULL) {
memcpy(p, heap->reqs, heap->cnt * sizeof(*p));
free(heap->reqs);
@@ -2161,7 +2301,7 @@ register_CE(struct archive_read *a, int32_t location,
heap->reqs[hole].file = file;
return (ARCHIVE_OK);
}
- // Move parent into hole <==> move hole up tree.
+ /* Move parent into hole <==> move hole up tree. */
heap->reqs[hole] = heap->reqs[parent];
hole = parent;
}
@@ -2188,14 +2328,14 @@ next_CE(struct read_ce_queue *heap)
/*
* Rebalance the heap.
*/
- a = 0; // Starting element and its offset
+ a = 0; /* Starting element and its offset */
a_offset = heap->reqs[a].offset;
for (;;) {
- b = a + a + 1; // First child
+ b = a + a + 1; /* First child */
if (b >= heap->cnt)
return;
b_offset = heap->reqs[b].offset;
- c = b + 1; // Use second child if it is smaller.
+ c = b + 1; /* Use second child if it is smaller. */
if (c < heap->cnt) {
c_offset = heap->reqs[c].offset;
if (c_offset < b_offset) {
@@ -2237,6 +2377,12 @@ read_CE(struct archive_read *a, struct iso9660 *iso9660)
}
do {
file = heap->reqs[0].file;
+ if (file->ce_offset + file->ce_size > step) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Malformed CE information");
+ return (ARCHIVE_FATAL);
+ }
p = b + file->ce_offset;
end = p + file->ce_size;
next_CE(heap);
@@ -2277,12 +2423,14 @@ parse_rockridge_NM1(struct file_info *file,
case 0:
if (data_length < 2)
return;
- archive_strncat(&file->name, (const char *)data + 1, data_length - 1);
+ archive_strncat(&file->name,
+ (const char *)data + 1, data_length - 1);
break;
case 1:
if (data_length < 2)
return;
- archive_strncat(&file->name, (const char *)data + 1, data_length - 1);
+ archive_strncat(&file->name,
+ (const char *)data + 1, data_length - 1);
file->name_continues = 1;
break;
case 2:
@@ -2493,6 +2641,7 @@ release_files(struct iso9660 *iso9660)
archive_string_free(&file->name);
archive_string_free(&file->symlink);
+ free(file->utf16be_name);
con = file->contents.first;
while (con != NULL) {
connext = con->next;
@@ -2520,12 +2669,19 @@ next_entry_seek(struct archive_read *a, struct iso9660 *iso9660,
if (file->size == 0)
file->offset = iso9660->current_position;
+ /* flush any remaining bytes from the last round to ensure
+ * we're positioned */
+ if (iso9660->entry_bytes_unconsumed) {
+ __archive_read_consume(a, iso9660->entry_bytes_unconsumed);
+ iso9660->entry_bytes_unconsumed = 0;
+ }
+
/* Seek forward to the start of the entry. */
if (iso9660->current_position < file->offset) {
int64_t step;
step = file->offset - iso9660->current_position;
- step = __archive_read_skip(a, step);
+ step = __archive_read_consume(a, step);
if (step < 0)
return ((int)step);
iso9660->current_position = file->offset;
@@ -2816,13 +2972,15 @@ cache_get_entry(struct iso9660 *iso9660)
if ((file = iso9660->cache_files.first) != NULL) {
iso9660->cache_files.first = file->next;
if (iso9660->cache_files.first == NULL)
- iso9660->cache_files.last = &(iso9660->cache_files.first);
+ iso9660->cache_files.last =
+ &(iso9660->cache_files.first);
}
return (file);
}
-static void
-heap_add_entry(struct heap_queue *heap, struct file_info *file, uint64_t key)
+static int
+heap_add_entry(struct archive_read *a, struct heap_queue *heap,
+ struct file_info *file, uint64_t key)
{
uint64_t file_key, parent_key;
int hole, parent;
@@ -2835,12 +2993,18 @@ heap_add_entry(struct heap_queue *heap, struct file_info *file, uint64_t key)
if (heap->allocated < 1024)
new_size = 1024;
/* Overflow might keep us from growing the list. */
- if (new_size <= heap->allocated)
- __archive_errx(1, "Out of memory");
+ if (new_size <= heap->allocated) {
+ archive_set_error(&a->archive,
+ ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
new_pending_files = (struct file_info **)
malloc(new_size * sizeof(new_pending_files[0]));
- if (new_pending_files == NULL)
- __archive_errx(1, "Out of memory");
+ if (new_pending_files == NULL) {
+ archive_set_error(&a->archive,
+ ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
memcpy(new_pending_files, heap->files,
heap->allocated * sizeof(new_pending_files[0]));
if (heap->files != NULL)
@@ -2860,13 +3024,15 @@ heap_add_entry(struct heap_queue *heap, struct file_info *file, uint64_t key)
parent_key = heap->files[parent]->key;
if (file_key >= parent_key) {
heap->files[hole] = file;
- return;
+ return (ARCHIVE_OK);
}
- // Move parent into hole <==> move hole up tree.
+ /* Move parent into hole <==> move hole up tree. */
heap->files[hole] = heap->files[parent];
hole = parent;
}
heap->files[0] = file;
+
+ return (ARCHIVE_OK);
}
static struct file_info *
@@ -2892,14 +3058,14 @@ heap_get_entry(struct heap_queue *heap)
/*
* Rebalance the heap.
*/
- a = 0; // Starting element and its heap key
+ a = 0; /* Starting element and its heap key */
a_key = heap->files[a]->key;
for (;;) {
- b = a + a + 1; // First child
+ b = a + a + 1; /* First child */
if (b >= heap->used)
return (r);
b_key = heap->files[b]->key;
- c = b + 1; // Use second child if it is smaller.
+ c = b + 1; /* Use second child if it is smaller. */
if (c < heap->used) {
c_key = heap->files[c]->key;
if (c_key < b_key) {
@@ -2977,6 +3143,8 @@ time_from_tm(struct tm *t)
#if HAVE_TIMEGM
/* Use platform timegm() if available. */
return (timegm(t));
+#elif HAVE__MKGMTIME64
+ return (_mkgmtime64(t));
#else
/* Else use direct calculation using POSIX assumptions. */
/* First, fix up tm_yday based on the year/month/day. */
@@ -3004,6 +3172,32 @@ build_pathname(struct archive_string *as, struct file_info *file)
return (as->s);
}
+static int
+build_pathname_utf16be(unsigned char *p, size_t max, size_t *len,
+ struct file_info *file)
+{
+ if (file->parent != NULL && file->parent->utf16be_bytes > 0) {
+ if (build_pathname_utf16be(p, max, len, file->parent) != 0)
+ return (-1);
+ p[*len] = 0;
+ p[*len + 1] = '/';
+ *len += 2;
+ }
+ if (file->utf16be_bytes == 0) {
+ if (*len + 2 > max)
+ return (-1);/* Path is too long! */
+ p[*len] = 0;
+ p[*len + 1] = '.';
+ *len += 2;
+ } else {
+ if (*len + file->utf16be_bytes > max)
+ return (-1);/* Path is too long! */
+ memcpy(p + *len, file->utf16be_name, file->utf16be_bytes);
+ *len += file->utf16be_bytes;
+ }
+ return (0);
+}
+
#if DEBUG
static void
dump_isodirrec(FILE *out, const unsigned char *isodirrec)
@@ -3016,7 +3210,7 @@ dump_isodirrec(FILE *out, const unsigned char *isodirrec)
toi(isodirrec + DR_extent_offset, DR_extent_size));
fprintf(out, " s %d,",
toi(isodirrec + DR_size_offset, DR_extent_size));
- fprintf(out, " f 0x%02x,",
+ fprintf(out, " f 0x%x,",
toi(isodirrec + DR_flags_offset, DR_flags_size));
fprintf(out, " u %d,",
toi(isodirrec + DR_file_unit_size_offset, DR_file_unit_size_size));
diff --git a/libarchive/archive_read_support_format_lha.c b/libarchive/archive_read_support_format_lha.c
new file mode 100644
index 000000000000..f3c7d282b497
--- /dev/null
+++ b/libarchive/archive_read_support_format_lha.c
@@ -0,0 +1,2745 @@
+/*-
+ * Copyright (c) 2008-2011 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include "archive.h"
+#include "archive_entry.h"
+#include "archive_entry_locale.h"
+#include "archive_private.h"
+#include "archive_read_private.h"
+#include "archive_endian.h"
+
+
+#define MAXMATCH 256 /* Maximum match length. */
+#define MINMATCH 3 /* Minimum match length. */
+/*
+ * Literal table format:
+ * +0 +256 +510
+ * +---------------+-------------------------+
+ * | literal code | match length |
+ * | 0 ... 255 | MINMATCH ... MAXMATCH |
+ * +---------------+-------------------------+
+ * <--- LT_BITLEN_SIZE --->
+ */
+/* Literal table size. */
+#define LT_BITLEN_SIZE (UCHAR_MAX + 1 + MAXMATCH - MINMATCH + 1)
+/* Position table size.
+ * Note: this used for both position table and pre literal table.*/
+#define PT_BITLEN_SIZE (3 + 16)
+
+struct lzh_dec {
+ /* Decoding status. */
+ int state;
+
+ /*
+ * Window to see last 8Ki(lh5),32Ki(lh6),64Ki(lh7) bytes of decoded
+ * data.
+ */
+ int w_size;
+ int w_mask;
+ /* Window buffer, which is a loop buffer. */
+ unsigned char *w_buff;
+ /* The insert position to the window. */
+ int w_pos;
+ /* The position where we can copy decoded code from the window. */
+ int copy_pos;
+ /* The length how many bytes we can copy decoded code from
+ * the window. */
+ int copy_len;
+ /* The remaining bytes that we have not copied decoded data from
+ * the window to an output buffer. */
+ int w_remaining;
+
+ /*
+ * Bit stream reader.
+ */
+ struct lzh_br {
+#define CACHE_TYPE uint64_t
+#define CACHE_BITS (8 * sizeof(CACHE_TYPE))
+ /* Cache buffer. */
+ CACHE_TYPE cache_buffer;
+ /* Indicates how many bits avail in cache_buffer. */
+ int cache_avail;
+ } br;
+
+ /*
+ * Huffman coding.
+ */
+ struct huffman {
+ int len_size;
+ int len_avail;
+ int len_bits;
+ int freq[17];
+ unsigned char *bitlen;
+
+ /*
+ * Use a index table. It's faster than searching a huffman
+ * coding tree, which is a binary tree. But a use of a large
+ * index table causes L1 cache read miss many times.
+ */
+#define HTBL_BITS 10
+ int max_bits;
+ int shift_bits;
+ int tbl_bits;
+ int tree_used;
+ int tree_avail;
+ /* Direct access table. */
+ uint16_t *tbl;
+ /* Binary tree table for extra bits over the direct access. */
+ struct htree_t {
+ uint16_t left;
+ uint16_t right;
+ } *tree;
+ } lt, pt;
+
+ int blocks_avail;
+ int pos_pt_len_size;
+ int pos_pt_len_bits;
+ int literal_pt_len_size;
+ int literal_pt_len_bits;
+ int reading_position;
+ int loop;
+ int error;
+};
+
+struct lzh_stream {
+ const unsigned char *next_in;
+ int64_t avail_in;
+ int64_t total_in;
+ unsigned char *next_out;
+ int64_t avail_out;
+ int64_t total_out;
+ struct lzh_dec *ds;
+};
+
+struct lha {
+ /* entry_bytes_remaining is the number of bytes we expect. */
+ int64_t entry_offset;
+ int64_t entry_bytes_remaining;
+ int64_t entry_unconsumed;
+ uint16_t entry_crc_calculated;
+
+ size_t header_size; /* header size */
+ unsigned char level; /* header level */
+ char method[3]; /* compress type */
+ int64_t compsize; /* compressed data size */
+ int64_t origsize; /* original file size */
+ int setflag;
+#define BIRTHTIME_IS_SET 1
+#define ATIME_IS_SET 2
+#define UNIX_MODE_IS_SET 4
+#define CRC_IS_SET 8
+ time_t birthtime;
+ long birthtime_tv_nsec;
+ time_t mtime;
+ long mtime_tv_nsec;
+ time_t atime;
+ long atime_tv_nsec;
+ mode_t mode;
+ int64_t uid;
+ int64_t gid;
+ struct archive_string uname;
+ struct archive_string gname;
+ uint16_t header_crc;
+ uint16_t crc;
+ struct archive_string_conv *sconv;
+ struct archive_string_conv *opt_sconv;
+
+ struct archive_string dirname;
+ struct archive_string filename;
+ struct archive_wstring ws;
+
+ unsigned char dos_attr;
+
+ /* Flag to mark progress that an archive was read their first header.*/
+ char found_first_header;
+ /* Flag to mark that indicates an empty directory. */
+ char directory;
+
+ /* Flags to mark progress of decompression. */
+ char decompress_init;
+ char end_of_entry;
+ char end_of_entry_cleanup;
+ char entry_is_compressed;
+
+ unsigned char *uncompressed_buffer;
+ size_t uncompressed_buffer_size;
+
+ char format_name[64];
+
+ struct lzh_stream strm;
+};
+
+/*
+ * LHA header common member offset.
+ */
+#define H_METHOD_OFFSET 2 /* Compress type. */
+#define H_ATTR_OFFSET 19 /* DOS attribute. */
+#define H_LEVEL_OFFSET 20 /* Header Level. */
+#define H_SIZE 22 /* Minimum header size. */
+
+static const uint16_t crc16tbl[256] = {
+ 0x0000,0xC0C1,0xC181,0x0140,0xC301,0x03C0,0x0280,0xC241,
+ 0xC601,0x06C0,0x0780,0xC741,0x0500,0xC5C1,0xC481,0x0440,
+ 0xCC01,0x0CC0,0x0D80,0xCD41,0x0F00,0xCFC1,0xCE81,0x0E40,
+ 0x0A00,0xCAC1,0xCB81,0x0B40,0xC901,0x09C0,0x0880,0xC841,
+ 0xD801,0x18C0,0x1980,0xD941,0x1B00,0xDBC1,0xDA81,0x1A40,
+ 0x1E00,0xDEC1,0xDF81,0x1F40,0xDD01,0x1DC0,0x1C80,0xDC41,
+ 0x1400,0xD4C1,0xD581,0x1540,0xD701,0x17C0,0x1680,0xD641,
+ 0xD201,0x12C0,0x1380,0xD341,0x1100,0xD1C1,0xD081,0x1040,
+ 0xF001,0x30C0,0x3180,0xF141,0x3300,0xF3C1,0xF281,0x3240,
+ 0x3600,0xF6C1,0xF781,0x3740,0xF501,0x35C0,0x3480,0xF441,
+ 0x3C00,0xFCC1,0xFD81,0x3D40,0xFF01,0x3FC0,0x3E80,0xFE41,
+ 0xFA01,0x3AC0,0x3B80,0xFB41,0x3900,0xF9C1,0xF881,0x3840,
+ 0x2800,0xE8C1,0xE981,0x2940,0xEB01,0x2BC0,0x2A80,0xEA41,
+ 0xEE01,0x2EC0,0x2F80,0xEF41,0x2D00,0xEDC1,0xEC81,0x2C40,
+ 0xE401,0x24C0,0x2580,0xE541,0x2700,0xE7C1,0xE681,0x2640,
+ 0x2200,0xE2C1,0xE381,0x2340,0xE101,0x21C0,0x2080,0xE041,
+ 0xA001,0x60C0,0x6180,0xA141,0x6300,0xA3C1,0xA281,0x6240,
+ 0x6600,0xA6C1,0xA781,0x6740,0xA501,0x65C0,0x6480,0xA441,
+ 0x6C00,0xACC1,0xAD81,0x6D40,0xAF01,0x6FC0,0x6E80,0xAE41,
+ 0xAA01,0x6AC0,0x6B80,0xAB41,0x6900,0xA9C1,0xA881,0x6840,
+ 0x7800,0xB8C1,0xB981,0x7940,0xBB01,0x7BC0,0x7A80,0xBA41,
+ 0xBE01,0x7EC0,0x7F80,0xBF41,0x7D00,0xBDC1,0xBC81,0x7C40,
+ 0xB401,0x74C0,0x7580,0xB541,0x7700,0xB7C1,0xB681,0x7640,
+ 0x7200,0xB2C1,0xB381,0x7340,0xB101,0x71C0,0x7080,0xB041,
+ 0x5000,0x90C1,0x9181,0x5140,0x9301,0x53C0,0x5280,0x9241,
+ 0x9601,0x56C0,0x5780,0x9741,0x5500,0x95C1,0x9481,0x5440,
+ 0x9C01,0x5CC0,0x5D80,0x9D41,0x5F00,0x9FC1,0x9E81,0x5E40,
+ 0x5A00,0x9AC1,0x9B81,0x5B40,0x9901,0x59C0,0x5880,0x9841,
+ 0x8801,0x48C0,0x4980,0x8941,0x4B00,0x8BC1,0x8A81,0x4A40,
+ 0x4E00,0x8EC1,0x8F81,0x4F40,0x8D01,0x4DC0,0x4C80,0x8C41,
+ 0x4400,0x84C1,0x8581,0x4540,0x8701,0x47C0,0x4680,0x8641,
+ 0x8201,0x42C0,0x4380,0x8341,0x4100,0x81C1,0x8081,0x4040
+};
+
+static int archive_read_format_lha_bid(struct archive_read *, int);
+static int archive_read_format_lha_options(struct archive_read *,
+ const char *, const char *);
+static int archive_read_format_lha_read_header(struct archive_read *,
+ struct archive_entry *);
+static int archive_read_format_lha_read_data(struct archive_read *,
+ const void **, size_t *, int64_t *);
+static int archive_read_format_lha_read_data_skip(struct archive_read *);
+static int archive_read_format_lha_cleanup(struct archive_read *);
+
+static void lha_replace_path_separator(struct lha *,
+ struct archive_entry *);
+static int lha_read_file_header_0(struct archive_read *, struct lha *);
+static int lha_read_file_header_1(struct archive_read *, struct lha *);
+static int lha_read_file_header_2(struct archive_read *, struct lha *);
+static int lha_read_file_header_3(struct archive_read *, struct lha *);
+static int lha_read_file_extended_header(struct archive_read *,
+ struct lha *, uint16_t *, int, size_t, size_t *);
+static size_t lha_check_header_format(const void *);
+static int lha_skip_sfx(struct archive_read *);
+static time_t lha_dos_time(const unsigned char *);
+static time_t lha_win_time(uint64_t, long *);
+static unsigned char lha_calcsum(unsigned char, const void *,
+ int, int);
+static int lha_parse_linkname(struct archive_string *,
+ struct archive_string *);
+static int lha_read_data_none(struct archive_read *, const void **,
+ size_t *, int64_t *);
+static int lha_read_data_lzh(struct archive_read *, const void **,
+ size_t *, int64_t *);
+static uint16_t lha_crc16(uint16_t, const void *, size_t);
+static int lzh_decode_init(struct lzh_stream *, const char *);
+static void lzh_decode_free(struct lzh_stream *);
+static int lzh_decode(struct lzh_stream *, int);
+static int lzh_br_fillup(struct lzh_stream *, struct lzh_br *);
+static int lzh_huffman_init(struct huffman *, size_t, int);
+static void lzh_huffman_free(struct huffman *);
+static int lzh_read_pt_bitlen(struct lzh_stream *, int start, int end);
+static int lzh_make_fake_table(struct huffman *, uint16_t);
+static int lzh_make_huffman_table(struct huffman *);
+static int inline lzh_decode_huffman(struct huffman *, unsigned);
+static int lzh_decode_huffman_tree(struct huffman *, unsigned, int);
+
+
+int
+archive_read_support_format_lha(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct lha *lha;
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_lha");
+
+ lha = (struct lha *)calloc(1, sizeof(*lha));
+ if (lha == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate lha data");
+ return (ARCHIVE_FATAL);
+ }
+ archive_string_init(&lha->ws);
+
+ r = __archive_read_register_format(a,
+ lha,
+ "lha",
+ archive_read_format_lha_bid,
+ archive_read_format_lha_options,
+ archive_read_format_lha_read_header,
+ archive_read_format_lha_read_data,
+ archive_read_format_lha_read_data_skip,
+ archive_read_format_lha_cleanup);
+
+ if (r != ARCHIVE_OK)
+ free(lha);
+ return (ARCHIVE_OK);
+}
+
+static size_t
+lha_check_header_format(const void *h)
+{
+ const unsigned char *p = h;
+ size_t next_skip_bytes;
+
+ switch (p[H_METHOD_OFFSET+3]) {
+ /*
+ * "-lh0-" ... "-lh7-" "-lhd-"
+ * "-lzs-" "-lz5-"
+ */
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ case 'd':
+ case 's':
+ next_skip_bytes = 4;
+
+ /* b0 == 0 means the end of an LHa archive file. */
+ if (p[0] == 0)
+ break;
+ if (p[H_METHOD_OFFSET] != '-' || p[H_METHOD_OFFSET+1] != 'l'
+ || p[H_METHOD_OFFSET+4] != '-')
+ break;
+
+ if (p[H_METHOD_OFFSET+2] == 'h') {
+ /* "-lh?-" */
+ if (p[H_METHOD_OFFSET+3] == 's')
+ break;
+ if (p[H_LEVEL_OFFSET] == 0)
+ return (0);
+ if (p[H_LEVEL_OFFSET] <= 3 && p[H_ATTR_OFFSET] == 0x20)
+ return (0);
+ }
+ if (p[H_METHOD_OFFSET+2] == 'z') {
+ /* LArc extensions: -lzs-,-lz4- and -lz5- */
+ if (p[H_LEVEL_OFFSET] != 0)
+ break;
+ if (p[H_METHOD_OFFSET+3] == 's'
+ || p[H_METHOD_OFFSET+3] == '4'
+ || p[H_METHOD_OFFSET+3] == '5')
+ return (0);
+ }
+ break;
+ case 'h': next_skip_bytes = 1; break;
+ case 'z': next_skip_bytes = 1; break;
+ case 'l': next_skip_bytes = 2; break;
+ case '-': next_skip_bytes = 3; break;
+ default : next_skip_bytes = 4; break;
+ }
+
+ return (next_skip_bytes);
+}
+
+static int
+archive_read_format_lha_bid(struct archive_read *a, int best_bid)
+{
+ const char *p;
+ const void *buff;
+ ssize_t bytes_avail, offset, window;
+ size_t next;
+
+ /* If there's already a better bid than we can ever
+ make, don't bother testing. */
+ if (best_bid > 30)
+ return (-1);
+
+ if ((p = __archive_read_ahead(a, H_SIZE, NULL)) == NULL)
+ return (-1);
+
+ if (lha_check_header_format(p) == 0)
+ return (30);
+
+ if (p[0] == 'M' && p[1] == 'Z') {
+ /* PE file */
+ offset = 0;
+ window = 4096;
+ while (offset < (1024 * 20)) {
+ buff = __archive_read_ahead(a, offset + window,
+ &bytes_avail);
+ if (buff == NULL) {
+ /* Remaining bytes are less than window. */
+ window >>= 1;
+ if (window < (H_SIZE + 3))
+ return (0);
+ continue;
+ }
+ p = (const char *)buff + offset;
+ while (p + H_SIZE < (const char *)buff + bytes_avail) {
+ if ((next = lha_check_header_format(p)) == 0)
+ return (30);
+ p += next;
+ }
+ offset = p - (const char *)buff;
+ }
+ }
+ return (0);
+}
+
+static int
+archive_read_format_lha_options(struct archive_read *a,
+ const char *key, const char *val)
+{
+ struct lha *lha;
+ int ret = ARCHIVE_FAILED;
+
+ lha = (struct lha *)(a->format->data);
+ if (strcmp(key, "hdrcharset") == 0) {
+ if (val == NULL || val[0] == 0)
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "lha: hdrcharset option needs a character-set name");
+ else {
+ lha->opt_sconv =
+ archive_string_conversion_from_charset(
+ &a->archive, val, 0);
+ if (lha->opt_sconv != NULL)
+ ret = ARCHIVE_OK;
+ else
+ ret = ARCHIVE_FATAL;
+ }
+ } else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "lha: unknown keyword ``%s''", key);
+
+ return (ret);
+}
+
+static int
+lha_skip_sfx(struct archive_read *a)
+{
+ const void *h;
+ const char *p, *q;
+ size_t next, skip;
+ ssize_t bytes, window;
+
+ window = 4096;
+ for (;;) {
+ h = __archive_read_ahead(a, window, &bytes);
+ if (h == NULL) {
+ /* Remaining bytes are less than window. */
+ window >>= 1;
+ if (window < (H_SIZE + 3))
+ goto fatal;
+ continue;
+ }
+ if (bytes < H_SIZE)
+ goto fatal;
+ p = h;
+ q = p + bytes;
+
+ /*
+ * Scan ahead until we find something that looks
+ * like the lha header.
+ */
+ while (p + H_SIZE < q) {
+ if ((next = lha_check_header_format(p)) == 0) {
+ skip = p - (const char *)h;
+ __archive_read_consume(a, skip);
+ return (ARCHIVE_OK);
+ }
+ p += next;
+ }
+ skip = p - (const char *)h;
+ __archive_read_consume(a, skip);
+ }
+fatal:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Couldn't find out LHa header");
+ return (ARCHIVE_FATAL);
+}
+
+static int
+truncated_error(struct archive_read *a)
+{
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated LHa header");
+ return (ARCHIVE_FATAL);
+}
+
+static int
+archive_read_format_lha_read_header(struct archive_read *a,
+ struct archive_entry *entry)
+{
+ struct archive_string linkname;
+ struct archive_string pathname;
+ struct lha *lha;
+ const unsigned char *p;
+ const char *signature;
+ int err;
+
+ a->archive.archive_format = ARCHIVE_FORMAT_LHA;
+ if (a->archive.archive_format_name == NULL)
+ a->archive.archive_format_name = "lha";
+
+ lha = (struct lha *)(a->format->data);
+ lha->decompress_init = 0;
+ lha->end_of_entry = 0;
+ lha->end_of_entry_cleanup = 0;
+ lha->entry_unconsumed = 0;
+
+ if ((p = __archive_read_ahead(a, H_SIZE, NULL)) == NULL) {
+ /*
+ * LHa archiver added 0 to the tail of its archive file as
+ * the mark of the end of the archive.
+ */
+ signature = __archive_read_ahead(a, sizeof(signature[0]), NULL);
+ if (signature == NULL || signature[0] == 0)
+ return (ARCHIVE_EOF);
+ return (truncated_error(a));
+ }
+
+ signature = (const char *)p;
+ if (lha->found_first_header == 0 &&
+ signature[0] == 'M' && signature[1] == 'Z') {
+ /* This is an executable? Must be self-extracting... */
+ err = lha_skip_sfx(a);
+ if (err < ARCHIVE_WARN)
+ return (err);
+
+ if ((p = __archive_read_ahead(a, sizeof(*p), NULL)) == NULL)
+ return (truncated_error(a));
+ signature = (const char *)p;
+ }
+ /* signature[0] == 0 means the end of an LHa archive file. */
+ if (signature[0] == 0)
+ return (ARCHIVE_EOF);
+
+ /*
+ * Check the header format and method type.
+ */
+ if (lha_check_header_format(p) != 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Bad LHa file");
+ return (ARCHIVE_FATAL);
+ }
+
+ /* We've found the first header. */
+ lha->found_first_header = 1;
+ /* Set a default value and common data */
+ lha->header_size = 0;
+ lha->level = p[H_LEVEL_OFFSET];
+ lha->method[0] = p[H_METHOD_OFFSET+1];
+ lha->method[1] = p[H_METHOD_OFFSET+2];
+ lha->method[2] = p[H_METHOD_OFFSET+3];
+ if (memcmp(lha->method, "lhd", 3) == 0)
+ lha->directory = 1;
+ else
+ lha->directory = 0;
+ if (memcmp(lha->method, "lh0", 3) == 0 ||
+ memcmp(lha->method, "lz4", 3) == 0)
+ lha->entry_is_compressed = 0;
+ else
+ lha->entry_is_compressed = 1;
+
+ lha->compsize = 0;
+ lha->origsize = 0;
+ lha->setflag = 0;
+ lha->birthtime = 0;
+ lha->birthtime_tv_nsec = 0;
+ lha->mtime = 0;
+ lha->mtime_tv_nsec = 0;
+ lha->atime = 0;
+ lha->atime_tv_nsec = 0;
+ lha->mode = (lha->directory)? 0777 : 0666;
+ lha->uid = 0;
+ lha->gid = 0;
+ archive_string_empty(&lha->dirname);
+ archive_string_empty(&lha->filename);
+ lha->dos_attr = 0;
+ if (lha->opt_sconv != NULL)
+ lha->sconv = lha->opt_sconv;
+ else
+ lha->sconv = NULL;
+
+ switch (p[H_LEVEL_OFFSET]) {
+ case 0:
+ err = lha_read_file_header_0(a, lha);
+ break;
+ case 1:
+ err = lha_read_file_header_1(a, lha);
+ break;
+ case 2:
+ err = lha_read_file_header_2(a, lha);
+ break;
+ case 3:
+ err = lha_read_file_header_3(a, lha);
+ break;
+ default:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Unsupported LHa header level %d", p[H_LEVEL_OFFSET]);
+ err = ARCHIVE_FATAL;
+ break;
+ }
+ if (err < ARCHIVE_WARN)
+ return (err);
+
+
+ if (!lha->directory && archive_strlen(&lha->filename) == 0)
+ /* The filename has not been set */
+ return (truncated_error(a));
+
+ /*
+ * Make a pathname from a dirname and a filename.
+ */
+ archive_string_concat(&lha->dirname, &lha->filename);
+ archive_string_init(&pathname);
+ archive_string_init(&linkname);
+ archive_string_copy(&pathname, &lha->dirname);
+
+ if ((lha->mode & AE_IFMT) == AE_IFLNK) {
+ /*
+ * Extract the symlink-name if it's included in the pathname.
+ */
+ if (!lha_parse_linkname(&linkname, &pathname)) {
+ /* We couldn't get the symlink-name. */
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Unknown symlink-name");
+ archive_string_free(&pathname);
+ archive_string_free(&linkname);
+ return (ARCHIVE_FAILED);
+ }
+ } else {
+ /*
+ * Make sure a file-type is set.
+ * The mode has been overridden if it is in the extended data.
+ */
+ lha->mode = (lha->mode & ~AE_IFMT) |
+ ((lha->directory)? AE_IFDIR: AE_IFREG);
+ }
+ if ((lha->setflag & UNIX_MODE_IS_SET) == 0 &&
+ (lha->dos_attr & 1) != 0)
+ lha->mode &= ~(0222);/* read only. */
+
+ /*
+ * Set basic file parameters.
+ */
+ if (archive_entry_copy_pathname_l(entry, pathname.s,
+ pathname.length, lha->sconv) != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Pathname cannot be converted "
+ "from %s to current locale.",
+ archive_string_conversion_charset_name(lha->sconv));
+ err = ARCHIVE_WARN;
+ }
+ archive_string_free(&pathname);
+ if (archive_strlen(&linkname) > 0) {
+ if (archive_entry_copy_symlink_l(entry, linkname.s,
+ linkname.length, lha->sconv) != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Linkname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Linkname cannot be converted "
+ "from %s to current locale.",
+ archive_string_conversion_charset_name(lha->sconv));
+ err = ARCHIVE_WARN;
+ }
+ } else
+ archive_entry_set_symlink(entry, NULL);
+ archive_string_free(&linkname);
+ /*
+ * When a header level is 0, there is a possibility that
+ * a pathname and a symlink has '\' character, a directory
+ * separator in DOS/Windows. So we should convert it to '/'.
+ */
+ if (p[H_LEVEL_OFFSET] == 0)
+ lha_replace_path_separator(lha, entry);
+
+ archive_entry_set_mode(entry, lha->mode);
+ archive_entry_set_uid(entry, lha->uid);
+ archive_entry_set_gid(entry, lha->gid);
+ if (archive_strlen(&lha->uname) > 0)
+ archive_entry_set_uname(entry, lha->uname.s);
+ if (archive_strlen(&lha->gname) > 0)
+ archive_entry_set_gname(entry, lha->gname.s);
+ if (lha->setflag & BIRTHTIME_IS_SET) {
+ archive_entry_set_birthtime(entry, lha->birthtime,
+ lha->birthtime_tv_nsec);
+ archive_entry_set_ctime(entry, lha->birthtime,
+ lha->birthtime_tv_nsec);
+ } else {
+ archive_entry_unset_birthtime(entry);
+ archive_entry_unset_ctime(entry);
+ }
+ archive_entry_set_mtime(entry, lha->mtime, lha->mtime_tv_nsec);
+ if (lha->setflag & ATIME_IS_SET)
+ archive_entry_set_atime(entry, lha->atime,
+ lha->atime_tv_nsec);
+ else
+ archive_entry_unset_atime(entry);
+ if (lha->directory || archive_entry_symlink(entry) != NULL)
+ archive_entry_unset_size(entry);
+ else
+ archive_entry_set_size(entry, lha->origsize);
+
+ /*
+ * Prepare variables used to read a file content.
+ */
+ lha->entry_bytes_remaining = lha->compsize;
+ lha->entry_offset = 0;
+ lha->entry_crc_calculated = 0;
+
+ /*
+ * This file does not have a content.
+ */
+ if (lha->directory || lha->compsize == 0)
+ lha->end_of_entry = 1;
+
+ sprintf(lha->format_name, "lha -%c%c%c-",
+ lha->method[0], lha->method[1], lha->method[2]);
+ a->archive.archive_format_name = lha->format_name;
+
+ return (err);
+}
+
+/*
+ * Replace a DOS path separator '\' by a character '/'.
+ * Some multi-byte character set have a character '\' in its second byte.
+ */
+static void
+lha_replace_path_separator(struct lha *lha, struct archive_entry *entry)
+{
+ const wchar_t *wp;
+ size_t i;
+
+ if ((wp = archive_entry_pathname_w(entry)) != NULL) {
+ archive_wstrcpy(&(lha->ws), wp);
+ for (i = 0; i < archive_strlen(&(lha->ws)); i++) {
+ if (lha->ws.s[i] == L'\\')
+ lha->ws.s[i] = L'/';
+ }
+ archive_entry_copy_pathname_w(entry, lha->ws.s);
+ }
+
+ if ((wp = archive_entry_symlink_w(entry)) != NULL) {
+ archive_wstrcpy(&(lha->ws), wp);
+ for (i = 0; i < archive_strlen(&(lha->ws)); i++) {
+ if (lha->ws.s[i] == L'\\')
+ lha->ws.s[i] = L'/';
+ }
+ archive_entry_copy_symlink_w(entry, lha->ws.s);
+ }
+}
+
+/*
+ * Header 0 format
+ *
+ * +0 +1 +2 +7 +11
+ * +---------------+----------+----------------+-------------------+
+ * |header size(*1)|header sum|compression type|compressed size(*2)|
+ * +---------------+----------+----------------+-------------------+
+ * <---------------------(*1)----------*
+ *
+ * +11 +15 +17 +19 +20 +21
+ * +-----------------+---------+---------+--------------+----------------+
+ * |uncompressed size|time(DOS)|date(DOS)|attribute(DOS)|header level(=0)|
+ * +-----------------+---------+---------+--------------+----------------+
+ * *--------------------------------(*1)---------------------------------*
+ *
+ * +21 +22 +22+(*3) +22+(*3)+2 +22+(*3)+2+(*4)
+ * +---------------+---------+----------+----------------+------------------+
+ * |name length(*3)|file name|file CRC16|extra header(*4)| compressed data |
+ * +---------------+---------+----------+----------------+------------------+
+ * <--(*3)-> <------(*2)------>
+ * *----------------------(*1)-------------------------->
+ *
+ */
+#define H0_HEADER_SIZE_OFFSET 0
+#define H0_HEADER_SUM_OFFSET 1
+#define H0_COMP_SIZE_OFFSET 7
+#define H0_ORIG_SIZE_OFFSET 11
+#define H0_DOS_TIME_OFFSET 15
+#define H0_NAME_LEN_OFFSET 21
+#define H0_FILE_NAME_OFFSET 22
+#define H0_FIXED_SIZE 24
+static int
+lha_read_file_header_0(struct archive_read *a, struct lha *lha)
+{
+ const unsigned char *p;
+ int extdsize, namelen;
+ unsigned char headersum, sum_calculated;
+
+ if ((p = __archive_read_ahead(a, H0_FIXED_SIZE, NULL)) == NULL)
+ return (truncated_error(a));
+ lha->header_size = p[H0_HEADER_SIZE_OFFSET] + 2;
+ headersum = p[H0_HEADER_SUM_OFFSET];
+ lha->compsize = archive_le32dec(p + H0_COMP_SIZE_OFFSET);
+ lha->origsize = archive_le32dec(p + H0_ORIG_SIZE_OFFSET);
+ lha->mtime = lha_dos_time(p + H0_DOS_TIME_OFFSET);
+ namelen = p[H0_NAME_LEN_OFFSET];
+ extdsize = (int)lha->header_size - H0_FIXED_SIZE - namelen;
+ if ((namelen > 221 || extdsize < 0) && extdsize != -2) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid LHa header");
+ return (ARCHIVE_FATAL);
+ }
+ if ((p = __archive_read_ahead(a, lha->header_size, NULL)) == NULL)
+ return (truncated_error(a));
+
+ archive_strncpy(&lha->filename, p + H0_FILE_NAME_OFFSET, namelen);
+ /* When extdsize == -2, A CRC16 value is not present in the header. */
+ if (extdsize >= 0) {
+ lha->crc = archive_le16dec(p + H0_FILE_NAME_OFFSET + namelen);
+ lha->setflag |= CRC_IS_SET;
+ }
+ sum_calculated = lha_calcsum(0, p, 2, lha->header_size - 2);
+
+ /* Read an extended header */
+ if (extdsize > 0) {
+ /* This extended data is set by 'LHa for UNIX' only.
+ * Maybe fixed size.
+ */
+ p += H0_FILE_NAME_OFFSET + namelen + 2;
+ if (p[0] == 'U' && extdsize == 12) {
+ /* p[1] is a minor version. */
+ lha->mtime = archive_le32dec(&p[2]);
+ lha->mode = archive_le16dec(&p[6]);
+ lha->uid = archive_le16dec(&p[8]);
+ lha->gid = archive_le16dec(&p[10]);
+ lha->setflag |= UNIX_MODE_IS_SET;
+ }
+ }
+ __archive_read_consume(a, lha->header_size);
+
+ if (sum_calculated != headersum) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "LHa header sum error");
+ return (ARCHIVE_FATAL);
+ }
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Header 1 format
+ *
+ * +0 +1 +2 +7 +11
+ * +---------------+----------+----------------+-------------+
+ * |header size(*1)|header sum|compression type|skip size(*2)|
+ * +---------------+----------+----------------+-------------+
+ * <---------------(*1)----------*
+ *
+ * +11 +15 +17 +19 +20 +21
+ * +-----------------+---------+---------+--------------+----------------+
+ * |uncompressed size|time(DOS)|date(DOS)|attribute(DOS)|header level(=1)|
+ * +-----------------+---------+---------+--------------+----------------+
+ * *-------------------------------(*1)----------------------------------*
+ *
+ * +21 +22 +22+(*3) +22+(*3)+2 +22+(*3)+3 +22+(*3)+3+(*4)
+ * +---------------+---------+----------+-----------+-----------+
+ * |name length(*3)|file name|file CRC16| creator |padding(*4)|
+ * +---------------+---------+----------+-----------+-----------+
+ * <--(*3)->
+ * *----------------------------(*1)----------------------------*
+ *
+ * +22+(*3)+3+(*4) +22+(*3)+3+(*4)+2 +22+(*3)+3+(*4)+2+(*5)
+ * +----------------+---------------------+------------------------+
+ * |next header size| extended header(*5) | compressed data |
+ * +----------------+---------------------+------------------------+
+ * *------(*1)-----> <--------------------(*2)-------------------->
+ */
+#define H1_HEADER_SIZE_OFFSET 0
+#define H1_HEADER_SUM_OFFSET 1
+#define H1_COMP_SIZE_OFFSET 7
+#define H1_ORIG_SIZE_OFFSET 11
+#define H1_DOS_TIME_OFFSET 15
+#define H1_NAME_LEN_OFFSET 21
+#define H1_FILE_NAME_OFFSET 22
+#define H1_FIXED_SIZE 27
+static int
+lha_read_file_header_1(struct archive_read *a, struct lha *lha)
+{
+ const unsigned char *p;
+ size_t extdsize;
+ int i, err, err2;
+ int namelen, padding;
+ unsigned char headersum, sum_calculated;
+
+ err = ARCHIVE_OK;
+
+ if ((p = __archive_read_ahead(a, H1_FIXED_SIZE, NULL)) == NULL)
+ return (truncated_error(a));
+
+ lha->header_size = p[H1_HEADER_SIZE_OFFSET] + 2;
+ headersum = p[H1_HEADER_SUM_OFFSET];
+ /* Note: An extended header size is included in a compsize. */
+ lha->compsize = archive_le32dec(p + H1_COMP_SIZE_OFFSET);
+ lha->origsize = archive_le32dec(p + H1_ORIG_SIZE_OFFSET);
+ lha->mtime = lha_dos_time(p + H1_DOS_TIME_OFFSET);
+ namelen = p[H1_NAME_LEN_OFFSET];
+ /* Calculate a padding size. The result will be normally 0 only(?) */
+ padding = ((int)lha->header_size) - H1_FIXED_SIZE - namelen;
+
+ if (namelen > 230 || padding < 0)
+ goto invalid;
+
+ if ((p = __archive_read_ahead(a, lha->header_size, NULL)) == NULL)
+ return (truncated_error(a));
+
+ for (i = 0; i < namelen; i++) {
+ if (p[i + H1_FILE_NAME_OFFSET] == 0xff)
+ goto invalid;/* Invalid filename. */
+ }
+ archive_strncpy(&lha->filename, p + H1_FILE_NAME_OFFSET, namelen);
+ lha->crc = archive_le16dec(p + H1_FILE_NAME_OFFSET + namelen);
+ lha->setflag |= CRC_IS_SET;
+
+ sum_calculated = lha_calcsum(0, p, 2, lha->header_size - 2);
+ /* Consume used bytes but not include `next header size' data
+ * since it will be consumed in lha_read_file_extended_header(). */
+ __archive_read_consume(a, lha->header_size - 2);
+
+ /* Read extended headers */
+ err2 = lha_read_file_extended_header(a, lha, NULL, 2,
+ lha->compsize + 2, &extdsize);
+ if (err2 < ARCHIVE_WARN)
+ return (err2);
+ if (err2 < err)
+ err = err2;
+ /* Get a real compressed file size. */
+ lha->compsize -= extdsize - 2;
+
+ if (sum_calculated != headersum) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "LHa header sum error");
+ return (ARCHIVE_FATAL);
+ }
+ return (err);
+invalid:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid LHa header");
+ return (ARCHIVE_FATAL);
+}
+
+/*
+ * Header 2 format
+ *
+ * +0 +2 +7 +11 +15
+ * +---------------+----------------+-------------------+-----------------+
+ * |header size(*1)|compression type|compressed size(*2)|uncompressed size|
+ * +---------------+----------------+-------------------+-----------------+
+ * <--------------------------------(*1)---------------------------------*
+ *
+ * +15 +19 +20 +21 +23 +24
+ * +-----------------+------------+----------------+----------+-----------+
+ * |data/time(time_t)| 0x20 fixed |header level(=2)|file CRC16| creator |
+ * +-----------------+------------+----------------+----------+-----------+
+ * *---------------------------------(*1)---------------------------------*
+ *
+ * +24 +26 +26+(*3) +26+(*3)+(*4)
+ * +----------------+-------------------+-------------+-------------------+
+ * |next header size|extended header(*3)| padding(*4) | compressed data |
+ * +----------------+-------------------+-------------+-------------------+
+ * *--------------------------(*1)-------------------> <------(*2)------->
+ *
+ */
+#define H2_HEADER_SIZE_OFFSET 0
+#define H2_COMP_SIZE_OFFSET 7
+#define H2_ORIG_SIZE_OFFSET 11
+#define H2_TIME_OFFSET 15
+#define H2_CRC_OFFSET 21
+#define H2_FIXED_SIZE 24
+static int
+lha_read_file_header_2(struct archive_read *a, struct lha *lha)
+{
+ const unsigned char *p;
+ size_t extdsize;
+ int err, padding;
+ uint16_t header_crc;
+
+ if ((p = __archive_read_ahead(a, H2_FIXED_SIZE, NULL)) == NULL)
+ return (truncated_error(a));
+
+ lha->header_size =archive_le16dec(p + H2_HEADER_SIZE_OFFSET);
+ lha->compsize = archive_le32dec(p + H2_COMP_SIZE_OFFSET);
+ lha->origsize = archive_le32dec(p + H2_ORIG_SIZE_OFFSET);
+ lha->mtime = archive_le32dec(p + H2_TIME_OFFSET);
+ lha->crc = archive_le16dec(p + H2_CRC_OFFSET);
+ lha->setflag |= CRC_IS_SET;
+
+ if (lha->header_size < H2_FIXED_SIZE) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid LHa header size");
+ return (ARCHIVE_FATAL);
+ }
+
+ header_crc = lha_crc16(0, p, H2_FIXED_SIZE);
+ __archive_read_consume(a, H2_FIXED_SIZE);
+
+ /* Read extended headers */
+ err = lha_read_file_extended_header(a, lha, &header_crc, 2,
+ lha->header_size - H2_FIXED_SIZE, &extdsize);
+ if (err < ARCHIVE_WARN)
+ return (err);
+
+ /* Calculate a padding size. The result will be normally 0 or 1. */
+ padding = (int)lha->header_size - (int)(H2_FIXED_SIZE + extdsize);
+ if (padding > 0) {
+ if ((p = __archive_read_ahead(a, padding, NULL)) == NULL)
+ return (truncated_error(a));
+ header_crc = lha_crc16(header_crc, p, padding);
+ __archive_read_consume(a, padding);
+ }
+
+ if (header_crc != lha->header_crc) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "LHa header CRC error");
+ return (ARCHIVE_FATAL);
+ }
+ return (err);
+}
+
+/*
+ * Header 3 format
+ *
+ * +0 +2 +7 +11 +15
+ * +------------+----------------+-------------------+-----------------+
+ * | 0x04 fixed |compression type|compressed size(*2)|uncompressed size|
+ * +------------+----------------+-------------------+-----------------+
+ * <-------------------------------(*1)-------------------------------*
+ *
+ * +15 +19 +20 +21 +23 +24
+ * +-----------------+------------+----------------+----------+-----------+
+ * |date/time(time_t)| 0x20 fixed |header level(=3)|file CRC16| creator |
+ * +-----------------+------------+----------------+----------+-----------+
+ * *--------------------------------(*1)----------------------------------*
+ *
+ * +24 +28 +32 +32+(*3)
+ * +---------------+----------------+-------------------+-----------------+
+ * |header size(*1)|next header size|extended header(*3)| compressed data |
+ * +---------------+----------------+-------------------+-----------------+
+ * *------------------------(*1)-----------------------> <------(*2)----->
+ *
+ */
+#define H3_FIELD_LEN_OFFSET 0
+#define H3_COMP_SIZE_OFFSET 7
+#define H3_ORIG_SIZE_OFFSET 11
+#define H3_TIME_OFFSET 15
+#define H3_CRC_OFFSET 21
+#define H3_HEADER_SIZE_OFFSET 24
+#define H3_FIXED_SIZE 28
+static int
+lha_read_file_header_3(struct archive_read *a, struct lha *lha)
+{
+ const unsigned char *p;
+ size_t extdsize;
+ int err;
+ uint16_t header_crc;
+
+ if ((p = __archive_read_ahead(a, H3_FIXED_SIZE, NULL)) == NULL)
+ return (truncated_error(a));
+
+ if (archive_le16dec(p + H3_FIELD_LEN_OFFSET) != 4)
+ goto invalid;
+ lha->header_size =archive_le32dec(p + H3_HEADER_SIZE_OFFSET);
+ lha->compsize = archive_le32dec(p + H3_COMP_SIZE_OFFSET);
+ lha->origsize = archive_le32dec(p + H3_ORIG_SIZE_OFFSET);
+ lha->mtime = archive_le32dec(p + H3_TIME_OFFSET);
+ lha->crc = archive_le16dec(p + H3_CRC_OFFSET);
+ lha->setflag |= CRC_IS_SET;
+
+ if (lha->header_size < H3_FIXED_SIZE + 4)
+ goto invalid;
+ header_crc = lha_crc16(0, p, H3_FIXED_SIZE);
+ __archive_read_consume(a, H3_FIXED_SIZE);
+
+ /* Read extended headers */
+ err = lha_read_file_extended_header(a, lha, &header_crc, 4,
+ lha->header_size - H3_FIXED_SIZE, &extdsize);
+ if (err < ARCHIVE_WARN)
+ return (err);
+
+ if (header_crc != lha->header_crc) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "LHa header CRC error");
+ return (ARCHIVE_FATAL);
+ }
+ return (err);
+invalid:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid LHa header");
+ return (ARCHIVE_FATAL);
+}
+
+/*
+ * Extended header format
+ *
+ * +0 +2 +3 -- used in header 1 and 2
+ * +0 +4 +5 -- used in header 3
+ * +--------------+---------+-------------------+--------------+--
+ * |ex-header size|header id| data |ex-header size| .......
+ * +--------------+---------+-------------------+--------------+--
+ * <-------------( ex-header size)------------> <-- next extended header --*
+ *
+ * If the ex-header size is zero, it is the make of the end of extended
+ * headers.
+ *
+ */
+static int
+lha_read_file_extended_header(struct archive_read *a, struct lha *lha,
+ uint16_t *crc, int sizefield_length, size_t limitsize, size_t *total_size)
+{
+ const void *h;
+ const unsigned char *extdheader;
+ size_t extdsize;
+ size_t datasize;
+ unsigned int i;
+ unsigned char extdtype;
+
+#define EXT_HEADER_CRC 0x00 /* Header CRC and information*/
+#define EXT_FILENAME 0x01 /* Filename */
+#define EXT_DIRECTORY 0x02 /* Directory name */
+#define EXT_DOS_ATTR 0x40 /* MS-DOS attribute */
+#define EXT_TIMESTAMP 0x41 /* Windows time stamp */
+#define EXT_FILESIZE 0x42 /* Large file size */
+#define EXT_TIMEZONE 0x43 /* Time zone */
+#define EXT_UTF16_FILENAME 0x44 /* UTF-16 filename */
+#define EXT_UTF16_DIRECTORY 0x45 /* UTF-16 directory name */
+#define EXT_CODEPAGE 0x46 /* Codepage */
+#define EXT_UNIX_MODE 0x50 /* File permission */
+#define EXT_UNIX_GID_UID 0x51 /* gid,uid */
+#define EXT_UNIX_GNAME 0x52 /* Group name */
+#define EXT_UNIX_UNAME 0x53 /* User name */
+#define EXT_UNIX_MTIME 0x54 /* Modified time */
+#define EXT_OS2_NEW_ATTR 0x7f /* new attribute(OS/2 only) */
+#define EXT_NEW_ATTR 0xff /* new attribute */
+
+ *total_size = sizefield_length;
+
+ for (;;) {
+ /* Read an extended header size. */
+ if ((h =
+ __archive_read_ahead(a, sizefield_length, NULL)) == NULL)
+ return (truncated_error(a));
+ /* Check if the size is the zero indicates the end of the
+ * extended header. */
+ if (sizefield_length == sizeof(uint16_t))
+ extdsize = archive_le16dec(h);
+ else
+ extdsize = archive_le32dec(h);
+ if (extdsize == 0) {
+ /* End of extended header */
+ if (crc != NULL)
+ *crc = lha_crc16(*crc, h, sizefield_length);
+ __archive_read_consume(a, sizefield_length);
+ return (ARCHIVE_OK);
+ }
+
+ /* Sanity check to the extended header size. */
+ if (((uint64_t)*total_size + extdsize) >
+ (uint64_t)limitsize ||
+ extdsize <= (size_t)sizefield_length)
+ goto invalid;
+
+ /* Read the extended header. */
+ if ((h = __archive_read_ahead(a, extdsize, NULL)) == NULL)
+ return (truncated_error(a));
+ *total_size += extdsize;
+
+ extdheader = (const unsigned char *)h;
+ /* Get the extended header type. */
+ extdtype = extdheader[sizefield_length];
+ /* Calculate an extended data size. */
+ datasize = extdsize - (1 + sizefield_length);
+ /* Skip an extended header size field and type field. */
+ extdheader += sizefield_length + 1;
+
+ if (crc != NULL && extdtype != EXT_HEADER_CRC)
+ *crc = lha_crc16(*crc, h, extdsize);
+ switch (extdtype) {
+ case EXT_HEADER_CRC:
+ /* We only use a header CRC. Following data will not
+ * be used. */
+ if (datasize >= 2) {
+ lha->header_crc = archive_le16dec(extdheader);
+ if (crc != NULL) {
+ static const char zeros[2] = {0, 0};
+ *crc = lha_crc16(*crc, h,
+ extdsize - datasize);
+ /* CRC value itself as zero */
+ *crc = lha_crc16(*crc, zeros, 2);
+ *crc = lha_crc16(*crc,
+ extdheader+2, datasize - 2);
+ }
+ }
+ break;
+ case EXT_FILENAME:
+ if (datasize == 0) {
+ /* maybe directory header */
+ archive_string_empty(&lha->filename);
+ break;
+ }
+ archive_strncpy(&lha->filename,
+ (const char *)extdheader, datasize);
+ break;
+ case EXT_DIRECTORY:
+ if (datasize == 0)
+ /* no directory name data. exit this case. */
+ break;
+
+ archive_strncpy(&lha->dirname,
+ (const char *)extdheader, datasize);
+ /*
+ * Convert directory delimiter from 0xFF
+ * to '/' for local system.
+ */
+ for (i = 0; i < lha->dirname.length; i++) {
+ if ((unsigned char)lha->dirname.s[i] == 0xFF)
+ lha->dirname.s[i] = '/';
+ }
+ /* Is last character directory separator? */
+ if (lha->dirname.s[lha->dirname.length-1] != '/')
+ /* invalid directory data */
+ goto invalid;
+ break;
+ case EXT_DOS_ATTR:
+ if (datasize == 2)
+ lha->dos_attr = (unsigned char)
+ (archive_le16dec(extdheader) & 0xff);
+ break;
+ case EXT_TIMESTAMP:
+ if (datasize == (sizeof(uint64_t) * 3)) {
+ lha->birthtime = lha_win_time(
+ archive_le64dec(extdheader),
+ &lha->birthtime_tv_nsec);
+ extdheader += sizeof(uint64_t);
+ lha->mtime = lha_win_time(
+ archive_le64dec(extdheader),
+ &lha->mtime_tv_nsec);
+ extdheader += sizeof(uint64_t);
+ lha->atime = lha_win_time(
+ archive_le64dec(extdheader),
+ &lha->atime_tv_nsec);
+ lha->setflag |= BIRTHTIME_IS_SET |
+ ATIME_IS_SET;
+ }
+ break;
+ case EXT_FILESIZE:
+ if (datasize == sizeof(uint64_t) * 2) {
+ lha->compsize = archive_le64dec(extdheader);
+ extdheader += sizeof(uint64_t);
+ lha->origsize = archive_le64dec(extdheader);
+ }
+ break;
+ case EXT_CODEPAGE:
+ /* Get an archived filename charset from codepage.
+ * This overwrites the charset specified by
+ * hdrcharset option. */
+ if (datasize == sizeof(uint32_t)) {
+ struct archive_string cp;
+ const char *charset;
+
+ archive_string_init(&cp);
+ switch (archive_le32dec(extdheader)) {
+ case 65001: /* UTF-8 */
+ charset = "UTF-8";
+ break;
+ default:
+ archive_string_sprintf(&cp, "CP%d",
+ (int)archive_le32dec(extdheader));
+ charset = cp.s;
+ break;
+ }
+ lha->sconv =
+ archive_string_conversion_from_charset(
+ &(a->archive), charset, 1);
+ archive_string_free(&cp);
+ if (lha->sconv == NULL)
+ return (ARCHIVE_FATAL);
+ }
+ break;
+ case EXT_UNIX_MODE:
+ if (datasize == sizeof(uint16_t)) {
+ lha->mode = archive_le16dec(extdheader);
+ lha->setflag |= UNIX_MODE_IS_SET;
+ }
+ break;
+ case EXT_UNIX_GID_UID:
+ if (datasize == (sizeof(uint16_t) * 2)) {
+ lha->gid = archive_le16dec(extdheader);
+ lha->uid = archive_le16dec(extdheader+2);
+ }
+ break;
+ case EXT_UNIX_GNAME:
+ if (datasize > 0)
+ archive_strncpy(&lha->gname,
+ (const char *)extdheader, datasize);
+ break;
+ case EXT_UNIX_UNAME:
+ if (datasize > 0)
+ archive_strncpy(&lha->uname,
+ (const char *)extdheader, datasize);
+ break;
+ case EXT_UNIX_MTIME:
+ if (datasize == sizeof(uint32_t))
+ lha->mtime = archive_le32dec(extdheader);
+ break;
+ case EXT_OS2_NEW_ATTR:
+ /* This extended header is OS/2 depend. */
+ if (datasize == 16) {
+ lha->dos_attr = (unsigned char)
+ (archive_le16dec(extdheader) & 0xff);
+ lha->mode = archive_le16dec(extdheader+2);
+ lha->gid = archive_le16dec(extdheader+4);
+ lha->uid = archive_le16dec(extdheader+6);
+ lha->birthtime = archive_le32dec(extdheader+8);
+ lha->atime = archive_le32dec(extdheader+12);
+ lha->setflag |= UNIX_MODE_IS_SET
+ | BIRTHTIME_IS_SET | ATIME_IS_SET;
+ }
+ break;
+ case EXT_NEW_ATTR:
+ if (datasize == 20) {
+ lha->mode = (mode_t)archive_le32dec(extdheader);
+ lha->gid = archive_le32dec(extdheader+4);
+ lha->uid = archive_le32dec(extdheader+8);
+ lha->birthtime = archive_le32dec(extdheader+12);
+ lha->atime = archive_le32dec(extdheader+16);
+ lha->setflag |= UNIX_MODE_IS_SET
+ | BIRTHTIME_IS_SET | ATIME_IS_SET;
+ }
+ break;
+ case EXT_TIMEZONE: /* Not supported */
+ case EXT_UTF16_FILENAME: /* Not supported */
+ case EXT_UTF16_DIRECTORY: /* Not supported */
+ default:
+ break;
+ }
+
+ __archive_read_consume(a, extdsize);
+ }
+invalid:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid extended LHa header");
+ return (ARCHIVE_FATAL);
+}
+
+static int
+archive_read_format_lha_read_data(struct archive_read *a,
+ const void **buff, size_t *size, int64_t *offset)
+{
+ struct lha *lha = (struct lha *)(a->format->data);
+ int r;
+
+ if (lha->entry_unconsumed) {
+ /* Consume as much as the decompressor actually used. */
+ __archive_read_consume(a, lha->entry_unconsumed);
+ lha->entry_unconsumed = 0;
+ }
+ if (lha->end_of_entry) {
+ if (!lha->end_of_entry_cleanup) {
+ if ((lha->setflag & CRC_IS_SET) &&
+ lha->crc != lha->entry_crc_calculated) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "LHa data CRC error");
+ return (ARCHIVE_WARN);
+ }
+
+ /* End-of-entry cleanup done. */
+ lha->end_of_entry_cleanup = 1;
+ }
+ *offset = lha->entry_offset;
+ *size = 0;
+ *buff = NULL;
+ return (ARCHIVE_EOF);
+ }
+
+ if (lha->entry_is_compressed)
+ r = lha_read_data_lzh(a, buff, size, offset);
+ else
+ /* No compression. */
+ r = lha_read_data_none(a, buff, size, offset);
+ return (r);
+}
+
+/*
+ * Read a file content in no compression.
+ *
+ * Returns ARCHIVE_OK if successful, ARCHIVE_FATAL otherwise, sets
+ * lha->end_of_entry if it consumes all of the data.
+ */
+static int
+lha_read_data_none(struct archive_read *a, const void **buff,
+ size_t *size, int64_t *offset)
+{
+ struct lha *lha = (struct lha *)(a->format->data);
+ ssize_t bytes_avail;
+
+ if (lha->entry_bytes_remaining == 0) {
+ *buff = NULL;
+ *size = 0;
+ *offset = lha->entry_offset;
+ lha->end_of_entry = 1;
+ return (ARCHIVE_OK);
+ }
+ /*
+ * Note: '1' here is a performance optimization.
+ * Recall that the decompression layer returns a count of
+ * available bytes; asking for more than that forces the
+ * decompressor to combine reads by copying data.
+ */
+ *buff = __archive_read_ahead(a, 1, &bytes_avail);
+ if (bytes_avail <= 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated LHa file data");
+ return (ARCHIVE_FATAL);
+ }
+ if (bytes_avail > lha->entry_bytes_remaining)
+ bytes_avail = lha->entry_bytes_remaining;
+ lha->entry_crc_calculated =
+ lha_crc16(lha->entry_crc_calculated, *buff, bytes_avail);
+ *size = bytes_avail;
+ *offset = lha->entry_offset;
+ lha->entry_offset += bytes_avail;
+ lha->entry_bytes_remaining -= bytes_avail;
+ if (lha->entry_bytes_remaining == 0)
+ lha->end_of_entry = 1;
+ lha->entry_unconsumed = bytes_avail;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Read a file content in LZHUFF encoding.
+ *
+ * Returns ARCHIVE_OK if successful, returns ARCHIVE_WARN if compression is
+ * unsupported, ARCHIVE_FATAL otherwise, sets lha->end_of_entry if it consumes
+ * all of the data.
+ */
+static int
+lha_read_data_lzh(struct archive_read *a, const void **buff,
+ size_t *size, int64_t *offset)
+{
+ struct lha *lha = (struct lha *)(a->format->data);
+ ssize_t bytes_avail;
+ int r;
+
+ /* If the buffer hasn't been allocated, allocate it now. */
+ if (lha->uncompressed_buffer == NULL) {
+ lha->uncompressed_buffer_size = 64 * 1024;
+ lha->uncompressed_buffer
+ = (unsigned char *)malloc(lha->uncompressed_buffer_size);
+ if (lha->uncompressed_buffer == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory for lzh decompression");
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ /* If we haven't yet read any data, initialize the decompressor. */
+ if (!lha->decompress_init) {
+ r = lzh_decode_init(&(lha->strm), lha->method);
+ switch (r) {
+ case ARCHIVE_OK:
+ break;
+ case ARCHIVE_FAILED:
+ /* Unsupported compression. */
+ *buff = NULL;
+ *size = 0;
+ *offset = 0;
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Unsupported lzh compression method -%c%c%c-",
+ lha->method[0], lha->method[1], lha->method[2]);
+ /* We know compressed size; just skip it. */
+ archive_read_format_lha_read_data_skip(a);
+ return (ARCHIVE_WARN);
+ default:
+ archive_set_error(&a->archive, ENOMEM,
+ "Couldn't allocate memory "
+ "for lzh decompression");
+ return (ARCHIVE_FATAL);
+ }
+ /* We've initialized decompression for this stream. */
+ lha->decompress_init = 1;
+ lha->strm.avail_out = 0;
+ lha->strm.total_out = 0;
+ }
+
+ /*
+ * Note: '1' here is a performance optimization.
+ * Recall that the decompression layer returns a count of
+ * available bytes; asking for more than that forces the
+ * decompressor to combine reads by copying data.
+ */
+ lha->strm.next_in = __archive_read_ahead(a, 1, &bytes_avail);
+ if (bytes_avail <= 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated LHa file body");
+ return (ARCHIVE_FATAL);
+ }
+ if (bytes_avail > lha->entry_bytes_remaining)
+ bytes_avail = lha->entry_bytes_remaining;
+
+ lha->strm.avail_in = bytes_avail;
+ lha->strm.total_in = 0;
+ if (lha->strm.avail_out == 0) {
+ lha->strm.next_out = lha->uncompressed_buffer;
+ lha->strm.avail_out = lha->uncompressed_buffer_size;
+ }
+
+ r = lzh_decode(&(lha->strm), bytes_avail == lha->entry_bytes_remaining);
+ switch (r) {
+ case ARCHIVE_OK:
+ break;
+ case ARCHIVE_EOF:
+ lha->end_of_entry = 1;
+ break;
+ default:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Bad lzh data");
+ return (ARCHIVE_FAILED);
+ }
+ lha->entry_unconsumed = lha->strm.total_in;
+ lha->entry_bytes_remaining -= lha->strm.total_in;
+
+ if (lha->strm.avail_out == 0 || lha->end_of_entry) {
+ *offset = lha->entry_offset;
+ *size = lha->strm.next_out - lha->uncompressed_buffer;
+ *buff = lha->uncompressed_buffer;
+ lha->entry_crc_calculated =
+ lha_crc16(lha->entry_crc_calculated, *buff, *size);
+ lha->entry_offset += *size;
+ } else {
+ *offset = lha->entry_offset;
+ *size = 0;
+ *buff = NULL;
+ }
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Skip a file content.
+ */
+static int
+archive_read_format_lha_read_data_skip(struct archive_read *a)
+{
+ struct lha *lha;
+ off_t bytes_skipped;
+
+ lha = (struct lha *)(a->format->data);
+
+ if (lha->entry_unconsumed) {
+ /* Consume as much as the decompressor actually used. */
+ __archive_read_consume(a, lha->entry_unconsumed);
+ lha->entry_unconsumed = 0;
+ }
+
+ /* if we've already read to end of data, we're done. */
+ if (lha->end_of_entry_cleanup)
+ return (ARCHIVE_OK);
+
+ /*
+ * If the length is at the beginning, we can skip the
+ * compressed data much more quickly.
+ */
+ bytes_skipped = __archive_read_consume(a, lha->entry_bytes_remaining);
+ if (bytes_skipped < 0)
+ return (ARCHIVE_FATAL);
+
+ /* This entry is finished and done. */
+ lha->end_of_entry_cleanup = lha->end_of_entry = 1;
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_read_format_lha_cleanup(struct archive_read *a)
+{
+ struct lha *lha = (struct lha *)(a->format->data);
+
+ lzh_decode_free(&(lha->strm));
+ free(lha->uncompressed_buffer);
+ archive_string_free(&(lha->dirname));
+ archive_string_free(&(lha->filename));
+ archive_string_free(&(lha->uname));
+ archive_string_free(&(lha->gname));
+ archive_wstring_free(&(lha->ws));
+ free(lha);
+ (a->format->data) = NULL;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * 'LHa for UNIX' utility has archived a symbolic-link name after
+ * a pathname with '|' character.
+ * This function extracts the symbolic-link name from the pathname.
+ *
+ * example.
+ * 1. a symbolic-name is 'aaa/bb/cc'
+ * 2. a filename is 'xxx/bbb'
+ * then a archived pathname is 'xxx/bbb|aaa/bb/cc'
+ */
+static int
+lha_parse_linkname(struct archive_string *linkname,
+ struct archive_string *pathname)
+{
+ char * linkptr;
+ int symlen;
+
+ linkptr = strchr(pathname->s, '|');
+ if (linkptr != NULL) {
+ symlen = strlen(linkptr + 1);
+ archive_strncpy(linkname, linkptr+1, symlen);
+
+ *linkptr = 0;
+ pathname->length = strlen(pathname->s);
+
+ return (1);
+ }
+ return (0);
+}
+
+/* Convert an MSDOS-style date/time into Unix-style time. */
+static time_t
+lha_dos_time(const unsigned char *p)
+{
+ int msTime, msDate;
+ struct tm ts;
+
+ msTime = archive_le16dec(p);
+ msDate = archive_le16dec(p+2);
+
+ memset(&ts, 0, sizeof(ts));
+ ts.tm_year = ((msDate >> 9) & 0x7f) + 80; /* Years since 1900. */
+ ts.tm_mon = ((msDate >> 5) & 0x0f) - 1; /* Month number. */
+ ts.tm_mday = msDate & 0x1f; /* Day of month. */
+ ts.tm_hour = (msTime >> 11) & 0x1f;
+ ts.tm_min = (msTime >> 5) & 0x3f;
+ ts.tm_sec = (msTime << 1) & 0x3e;
+ ts.tm_isdst = -1;
+ return (mktime(&ts));
+}
+
+/* Convert an MS-Windows-style date/time into Unix-style time. */
+static time_t
+lha_win_time(uint64_t wintime, long *ns)
+{
+#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
+
+ if (wintime >= EPOC_TIME) {
+ wintime -= EPOC_TIME; /* 1970-01-01 00:00:00 (UTC) */
+ if (ns != NULL)
+ *ns = (long)(wintime % 10000000) * 100;
+ return (wintime / 10000000);
+ } else {
+ if (ns != NULL)
+ *ns = 0;
+ return (0);
+ }
+}
+
+static unsigned char
+lha_calcsum(unsigned char sum, const void *pp, int offset, int size)
+{
+ unsigned char const *p = (unsigned char const *)pp;
+
+ p += offset;
+ while (--size >= 0)
+ sum += *p++;
+ return (sum);
+}
+
+#define CRC16(crc, v) do { \
+ (crc) = crc16tbl[((crc) ^ v) & 0xFF] ^ ((crc) >> 8); \
+} while (0)
+
+static uint16_t
+lha_crc16(uint16_t crc, const void *pp, size_t len)
+{
+ const unsigned char *buff = (const unsigned char *)pp;
+
+ while (len >= 8) {
+ CRC16(crc, *buff++); CRC16(crc, *buff++);
+ CRC16(crc, *buff++); CRC16(crc, *buff++);
+ CRC16(crc, *buff++); CRC16(crc, *buff++);
+ CRC16(crc, *buff++); CRC16(crc, *buff++);
+ len -= 8;
+ }
+ switch (len) {
+ case 7:
+ CRC16(crc, *buff++);
+ /* FALL THROUGH */
+ case 6:
+ CRC16(crc, *buff++);
+ /* FALL THROUGH */
+ case 5:
+ CRC16(crc, *buff++);
+ /* FALL THROUGH */
+ case 4:
+ CRC16(crc, *buff++);
+ /* FALL THROUGH */
+ case 3:
+ CRC16(crc, *buff++);
+ /* FALL THROUGH */
+ case 2:
+ CRC16(crc, *buff++);
+ /* FALL THROUGH */
+ case 1:
+ CRC16(crc, *buff);
+ /* FALL THROUGH */
+ case 0:
+ break;
+ }
+ return (crc);
+}
+
+
+/*
+ * Initialize LZHUF decoder.
+ *
+ * Returns ARCHIVE_OK if initialization was successful.
+ * Returns ARCHIVE_FAILED if method is unsupported.
+ * Returns ARCHIVE_FATAL if initialization failed; memory allocation
+ * error occurred.
+ */
+static int
+lzh_decode_init(struct lzh_stream *strm, const char *method)
+{
+ struct lzh_dec *ds;
+ int w_bits, w_size;
+
+ if (strm->ds == NULL) {
+ strm->ds = calloc(1, sizeof(*strm->ds));
+ if (strm->ds == NULL)
+ return (ARCHIVE_FATAL);
+ }
+ ds = strm->ds;
+ ds->error = ARCHIVE_FAILED;
+ if (method == NULL || method[0] != 'l' || method[1] != 'h')
+ return (ARCHIVE_FAILED);
+ switch (method[2]) {
+ case '5':
+ w_bits = 13;/* 8KiB for window */
+ break;
+ case '6':
+ w_bits = 15;/* 32KiB for window */
+ break;
+ case '7':
+ w_bits = 16;/* 64KiB for window */
+ break;
+ default:
+ return (ARCHIVE_FAILED);/* Not supported. */
+ }
+ ds->error = ARCHIVE_FATAL;
+ w_size = ds->w_size;
+ ds->w_size = 1U << w_bits;
+ ds->w_mask = ds->w_size -1;
+ if (ds->w_buff == NULL || w_size != ds->w_size) {
+ free(ds->w_buff);
+ ds->w_buff = malloc(ds->w_size);
+ if (ds->w_buff == NULL)
+ return (ARCHIVE_FATAL);
+ }
+ memset(ds->w_buff, 0x20, ds->w_size);
+ ds->w_pos = 0;
+ ds->w_remaining = 0;
+ ds->state = 0;
+ ds->pos_pt_len_size = w_bits + 1;
+ ds->pos_pt_len_bits = (w_bits == 15 || w_bits == 16)? 5: 4;
+ ds->literal_pt_len_size = PT_BITLEN_SIZE;
+ ds->literal_pt_len_bits = 5;
+ ds->br.cache_buffer = 0;
+ ds->br.cache_avail = 0;
+
+ if (lzh_huffman_init(&(ds->lt), LT_BITLEN_SIZE, 16)
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ ds->lt.len_bits = 9;
+ if (lzh_huffman_init(&(ds->pt), PT_BITLEN_SIZE, 16)
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ ds->error = 0;
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Release LZHUF decoder.
+ */
+static void
+lzh_decode_free(struct lzh_stream *strm)
+{
+
+ if (strm->ds == NULL)
+ return;
+ free(strm->ds->w_buff);
+ lzh_huffman_free(&(strm->ds->lt));
+ lzh_huffman_free(&(strm->ds->pt));
+ free(strm->ds);
+ strm->ds = NULL;
+}
+
+/*
+ * Bit stream reader.
+ */
+/* Check that the cache buffer has enough bits. */
+#define lzh_br_has(br, n) ((br)->cache_avail >= n)
+/* Get compressed data by bit. */
+#define lzh_br_bits(br, n) \
+ (((uint16_t)((br)->cache_buffer >> \
+ ((br)->cache_avail - (n)))) & cache_masks[n])
+#define lzh_br_bits_forced(br, n) \
+ (((uint16_t)((br)->cache_buffer << \
+ ((n) - (br)->cache_avail))) & cache_masks[n])
+/* Read ahead to make sure the cache buffer has enough compressed data we
+ * will use.
+ * True : completed, there is enough data in the cache buffer.
+ * False : we met that strm->next_in is empty, we have to get following
+ * bytes. */
+#define lzh_br_read_ahead_0(strm, br, n) \
+ (lzh_br_has(br, (n)) || lzh_br_fillup(strm, br))
+/* True : the cache buffer has some bits as much as we need.
+ * False : there are no enough bits in the cache buffer to be used,
+ * we have to get following bytes if we could. */
+#define lzh_br_read_ahead(strm, br, n) \
+ (lzh_br_read_ahead_0((strm), (br), (n)) || lzh_br_has((br), (n)))
+
+/* Notify how many bits we consumed. */
+#define lzh_br_consume(br, n) ((br)->cache_avail -= (n))
+#define lzh_br_unconsume(br, n) ((br)->cache_avail += (n))
+
+static const uint16_t cache_masks[] = {
+ 0x0000, 0x0001, 0x0003, 0x0007,
+ 0x000F, 0x001F, 0x003F, 0x007F,
+ 0x00FF, 0x01FF, 0x03FF, 0x07FF,
+ 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF,
+ 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF
+};
+
+/*
+ * Shift away used bits in the cache data and fill it up with following bits.
+ * Call this when cache buffer does not have enough bits you need.
+ *
+ * Returns 1 if the cache buffer is full.
+ * Returns 0 if the cache buffer is not full; input buffer is empty.
+ */
+static int
+lzh_br_fillup(struct lzh_stream *strm, struct lzh_br *br)
+{
+ int n = CACHE_BITS - br->cache_avail;
+
+ for (;;) {
+ switch (n >> 3) {
+ case 8:
+ if (strm->avail_in >= 8) {
+ br->cache_buffer =
+ ((uint64_t)strm->next_in[0]) << 56 |
+ ((uint64_t)strm->next_in[1]) << 48 |
+ ((uint64_t)strm->next_in[2]) << 40 |
+ ((uint64_t)strm->next_in[3]) << 32 |
+ ((uint32_t)strm->next_in[4]) << 24 |
+ ((uint32_t)strm->next_in[5]) << 16 |
+ ((uint32_t)strm->next_in[6]) << 8 |
+ (uint32_t)strm->next_in[7];
+ strm->next_in += 8;
+ strm->avail_in -= 8;
+ br->cache_avail += 8 * 8;
+ return (1);
+ }
+ break;
+ case 7:
+ if (strm->avail_in >= 7) {
+ br->cache_buffer =
+ (br->cache_buffer << 56) |
+ ((uint64_t)strm->next_in[0]) << 48 |
+ ((uint64_t)strm->next_in[1]) << 40 |
+ ((uint64_t)strm->next_in[2]) << 32 |
+ ((uint32_t)strm->next_in[3]) << 24 |
+ ((uint32_t)strm->next_in[4]) << 16 |
+ ((uint32_t)strm->next_in[5]) << 8 |
+ (uint32_t)strm->next_in[6];
+ strm->next_in += 7;
+ strm->avail_in -= 7;
+ br->cache_avail += 7 * 8;
+ return (1);
+ }
+ break;
+ case 6:
+ if (strm->avail_in >= 6) {
+ br->cache_buffer =
+ (br->cache_buffer << 48) |
+ ((uint64_t)strm->next_in[0]) << 40 |
+ ((uint64_t)strm->next_in[1]) << 32 |
+ ((uint32_t)strm->next_in[2]) << 24 |
+ ((uint32_t)strm->next_in[3]) << 16 |
+ ((uint32_t)strm->next_in[4]) << 8 |
+ (uint32_t)strm->next_in[5];
+ strm->next_in += 6;
+ strm->avail_in -= 6;
+ br->cache_avail += 6 * 8;
+ return (1);
+ }
+ break;
+ case 0:
+ /* We have enough compressed data in
+ * the cache buffer.*/
+ return (1);
+ default:
+ break;
+ }
+ if (strm->avail_in == 0) {
+ /* There is not enough compressed data to fill up the
+ * cache buffer. */
+ return (0);
+ }
+ br->cache_buffer =
+ (br->cache_buffer << 8) | *strm->next_in++;
+ strm->avail_in--;
+ br->cache_avail += 8;
+ n -= 8;
+ }
+}
+
+/*
+ * Decode LZHUF.
+ *
+ * 1. Returns ARCHIVE_OK if output buffer or input buffer are empty.
+ * Please set available buffer and call this function again.
+ * 2. Returns ARCHIVE_EOF if decompression has been completed.
+ * 3. Returns ARCHIVE_FAILED if an error occurred; compressed data
+ * is broken or you do not set 'last' flag properly.
+ * 4. 'last' flag is very important, you must set 1 to the flag if there
+ * is no input data. The lha compressed data format does not provide how
+ * to know the compressed data is really finished.
+ * Note: lha command utility check if the total size of output bytes is
+ * reached the uncompressed size recorded in its header. it does not mind
+ * that the decoding process is properly finished.
+ * GNU ZIP can decompress another compressed file made by SCO LZH compress.
+ * it handles EOF as null to fill read buffer with zero until the decoding
+ * process meet 2 bytes of zeros at reading a size of a next chunk, so the
+ * zeros are treated as the mark of the end of the data although the zeros
+ * is dummy, not the file data.
+ */
+static int lzh_read_blocks(struct lzh_stream *, int);
+static int lzh_decode_blocks(struct lzh_stream *, int);
+#define ST_RD_BLOCK 0
+#define ST_RD_PT_1 1
+#define ST_RD_PT_2 2
+#define ST_RD_PT_3 3
+#define ST_RD_PT_4 4
+#define ST_RD_LITERAL_1 5
+#define ST_RD_LITERAL_2 6
+#define ST_RD_LITERAL_3 7
+#define ST_RD_POS_DATA_1 8
+#define ST_GET_LITERAL 9
+#define ST_GET_POS_1 10
+#define ST_GET_POS_2 11
+#define ST_COPY_DATA 12
+
+static int
+lzh_decode(struct lzh_stream *strm, int last)
+{
+ struct lzh_dec *ds = strm->ds;
+ int64_t avail_in;
+ int r;
+
+ if (ds->error)
+ return (ds->error);
+
+ avail_in = strm->avail_in;
+ do {
+ if (ds->state < ST_GET_LITERAL)
+ r = lzh_read_blocks(strm, last);
+ else
+ r = lzh_decode_blocks(strm, last);
+ } while (r == 100);
+ strm->total_in += avail_in - strm->avail_in;
+ return (r);
+}
+
+static int
+lzh_copy_from_window(struct lzh_stream *strm, struct lzh_dec *ds)
+{
+ size_t copy_bytes;
+
+ if (ds->w_remaining == 0 && ds->w_pos > 0) {
+ if (ds->w_pos - ds->copy_pos <= strm->avail_out)
+ copy_bytes = ds->w_pos - ds->copy_pos;
+ else
+ copy_bytes = strm->avail_out;
+ memcpy(strm->next_out,
+ ds->w_buff + ds->copy_pos, copy_bytes);
+ ds->copy_pos += copy_bytes;
+ } else {
+ if (ds->w_remaining <= strm->avail_out)
+ copy_bytes = ds->w_remaining;
+ else
+ copy_bytes = strm->avail_out;
+ memcpy(strm->next_out,
+ ds->w_buff + ds->w_size - ds->w_remaining, copy_bytes);
+ ds->w_remaining -= copy_bytes;
+ }
+ strm->next_out += copy_bytes;
+ strm->avail_out -= copy_bytes;
+ strm->total_out += copy_bytes;
+ if (strm->avail_out == 0)
+ return (0);
+ else
+ return (1);
+}
+
+static int
+lzh_read_blocks(struct lzh_stream *strm, int last)
+{
+ struct lzh_dec *ds = strm->ds;
+ struct lzh_br *br = &(ds->br);
+ int c = 0, i;
+ unsigned rbits;
+
+ for (;;) {
+ switch (ds->state) {
+ case ST_RD_BLOCK:
+ /*
+ * Read a block number indicates how many blocks
+ * we will handle. The block is composed of a
+ * literal and a match, sometimes a literal only
+ * in particular, there are no reference data at
+ * the beginning of the decompression.
+ */
+ if (!lzh_br_read_ahead_0(strm, br, 16)) {
+ if (!last)
+ /* We need following data. */
+ return (ARCHIVE_OK);
+ if (lzh_br_has(br, 8)) {
+ /*
+ * It seems there are extra bits.
+ * 1. Compressed data is broken.
+ * 2. `last' flag does not properly
+ * set.
+ */
+ goto failed;
+ }
+ if (ds->w_pos > 0) {
+ if (!lzh_copy_from_window(strm, ds))
+ return (ARCHIVE_OK);
+ }
+ /* End of compressed data; we have completely
+ * handled all compressed data. */
+ return (ARCHIVE_EOF);
+ }
+ ds->blocks_avail = lzh_br_bits(br, 16);
+ if (ds->blocks_avail == 0)
+ goto failed;
+ lzh_br_consume(br, 16);
+ /*
+ * Read a literal table compressed in huffman
+ * coding.
+ */
+ ds->pt.len_size = ds->literal_pt_len_size;
+ ds->pt.len_bits = ds->literal_pt_len_bits;
+ ds->reading_position = 0;
+ /* FALL THROUGH */
+ case ST_RD_PT_1:
+ /* Note: ST_RD_PT_1, ST_RD_PT_2 and ST_RD_PT_4 are
+ * used in reading both a literal table and a
+ * position table. */
+ if (!lzh_br_read_ahead(strm, br, ds->pt.len_bits)) {
+ if (last)
+ goto failed;/* Truncated data. */
+ ds->state = ST_RD_PT_1;
+ return (ARCHIVE_OK);
+ }
+ ds->pt.len_avail = lzh_br_bits(br, ds->pt.len_bits);
+ lzh_br_consume(br, ds->pt.len_bits);
+ /* FALL THROUGH */
+ case ST_RD_PT_2:
+ if (ds->pt.len_avail == 0) {
+ /* There is no bitlen. */
+ if (!lzh_br_read_ahead(strm, br,
+ ds->pt.len_bits)) {
+ if (last)
+ goto failed;/* Truncated data.*/
+ ds->state = ST_RD_PT_2;
+ return (ARCHIVE_OK);
+ }
+ if (!lzh_make_fake_table(&(ds->pt),
+ lzh_br_bits(br, ds->pt.len_bits)))
+ goto failed;/* Invalid data. */
+ lzh_br_consume(br, ds->pt.len_bits);
+ if (ds->reading_position)
+ ds->state = ST_GET_LITERAL;
+ else
+ ds->state = ST_RD_LITERAL_1;
+ break;
+ } else if (ds->pt.len_avail > ds->pt.len_size)
+ goto failed;/* Invalid data. */
+ ds->loop = 0;
+ memset(ds->pt.freq, 0, sizeof(ds->pt.freq));
+ if (ds->pt.len_avail < 3 ||
+ ds->pt.len_size == ds->pos_pt_len_size) {
+ ds->state = ST_RD_PT_4;
+ break;
+ }
+ /* FALL THROUGH */
+ case ST_RD_PT_3:
+ ds->loop = lzh_read_pt_bitlen(strm, ds->loop, 3);
+ if (ds->loop < 3) {
+ if (ds->loop < 0 || last)
+ goto failed;/* Invalid data. */
+ /* Not completed, get following data. */
+ ds->state = ST_RD_PT_3;
+ return (ARCHIVE_OK);
+ }
+ /* There are some null in bitlen of the literal. */
+ if (!lzh_br_read_ahead(strm, br, 2)) {
+ if (last)
+ goto failed;/* Truncated data. */
+ ds->state = ST_RD_PT_3;
+ return (ARCHIVE_OK);
+ }
+ c = lzh_br_bits(br, 2);
+ lzh_br_consume(br, 2);
+ if (c > ds->pt.len_avail - 3)
+ goto failed;/* Invalid data. */
+ for (i = 3; c-- > 0 ;)
+ ds->pt.bitlen[i++] = 0;
+ ds->loop = i;
+ /* FALL THROUGH */
+ case ST_RD_PT_4:
+ ds->loop = lzh_read_pt_bitlen(strm, ds->loop,
+ ds->pt.len_avail);
+ if (ds->loop < ds->pt.len_avail) {
+ if (ds->loop < 0 || last)
+ goto failed;/* Invalid data. */
+ /* Not completed, get following data. */
+ ds->state = ST_RD_PT_4;
+ return (ARCHIVE_OK);
+ }
+ if (!lzh_make_huffman_table(&(ds->pt)))
+ goto failed;/* Invalid data */
+ if (ds->reading_position) {
+ ds->state = ST_GET_LITERAL;
+ break;
+ }
+ /* FALL THROUGH */
+ case ST_RD_LITERAL_1:
+ if (!lzh_br_read_ahead(strm, br, ds->lt.len_bits)) {
+ if (last)
+ goto failed;/* Truncated data. */
+ ds->state = ST_RD_LITERAL_1;
+ return (ARCHIVE_OK);
+ }
+ ds->lt.len_avail = lzh_br_bits(br, ds->lt.len_bits);
+ lzh_br_consume(br, ds->lt.len_bits);
+ /* FALL THROUGH */
+ case ST_RD_LITERAL_2:
+ if (ds->lt.len_avail == 0) {
+ /* There is no bitlen. */
+ if (!lzh_br_read_ahead(strm, br,
+ ds->lt.len_bits)) {
+ if (last)
+ goto failed;/* Truncated data.*/
+ ds->state = ST_RD_LITERAL_2;
+ return (ARCHIVE_OK);
+ }
+ if (!lzh_make_fake_table(&(ds->lt),
+ lzh_br_bits(br, ds->lt.len_bits)))
+ goto failed;/* Invalid data */
+ lzh_br_consume(br, ds->lt.len_bits);
+ ds->state = ST_RD_POS_DATA_1;
+ break;
+ } else if (ds->lt.len_avail > ds->lt.len_size)
+ goto failed;/* Invalid data */
+ ds->loop = 0;
+ memset(ds->lt.freq, 0, sizeof(ds->lt.freq));
+ /* FALL THROUGH */
+ case ST_RD_LITERAL_3:
+ i = ds->loop;
+ while (i < ds->lt.len_avail) {
+ if (!lzh_br_read_ahead(strm, br,
+ ds->pt.max_bits)) {
+ if (last)
+ goto failed;/* Truncated data.*/
+ ds->loop = i;
+ ds->state = ST_RD_LITERAL_3;
+ return (ARCHIVE_OK);
+ }
+ rbits = lzh_br_bits(br, ds->pt.max_bits);
+ c = lzh_decode_huffman(&(ds->pt), rbits);
+ if (c > 2) {
+ /* Note: 'c' will never be more than
+ * eighteen since it's limited by
+ * PT_BITLEN_SIZE, which is being set
+ * to ds->pt.len_size through
+ * ds->literal_pt_len_size. */
+ lzh_br_consume(br, ds->pt.bitlen[c]);
+ c -= 2;
+ ds->lt.freq[c]++;
+ ds->lt.bitlen[i++] = c;
+ } else if (c == 0) {
+ lzh_br_consume(br, ds->pt.bitlen[c]);
+ ds->lt.bitlen[i++] = 0;
+ } else {
+ /* c == 1 or c == 2 */
+ int n = (c == 1)?4:9;
+ if (!lzh_br_read_ahead(strm, br,
+ ds->pt.bitlen[c] + n)) {
+ if (last) /* Truncated data. */
+ goto failed;
+ ds->loop = i;
+ ds->state = ST_RD_LITERAL_3;
+ return (ARCHIVE_OK);
+ }
+ lzh_br_consume(br, ds->pt.bitlen[c]);
+ c = lzh_br_bits(br, n);
+ lzh_br_consume(br, n);
+ c += (n == 4)?3:20;
+ if (i + c > ds->lt.len_avail)
+ goto failed;/* Invalid data */
+ memset(&(ds->lt.bitlen[i]), 0, c);
+ i += c;
+ }
+ }
+ if (i > ds->lt.len_avail ||
+ !lzh_make_huffman_table(&(ds->lt)))
+ goto failed;/* Invalid data */
+ /* FALL THROUGH */
+ case ST_RD_POS_DATA_1:
+ /*
+ * Read a position table compressed in huffman
+ * coding.
+ */
+ ds->pt.len_size = ds->pos_pt_len_size;
+ ds->pt.len_bits = ds->pos_pt_len_bits;
+ ds->reading_position = 1;
+ ds->state = ST_RD_PT_1;
+ break;
+ case ST_GET_LITERAL:
+ return (100);
+ }
+ }
+failed:
+ return (ds->error = ARCHIVE_FAILED);
+}
+
+static int
+lzh_decode_blocks(struct lzh_stream *strm, int last)
+{
+ struct lzh_dec *ds = strm->ds;
+ struct lzh_br bre = ds->br;
+ struct huffman *lt = &(ds->lt);
+ struct huffman *pt = &(ds->pt);
+ unsigned char *w_buff = ds->w_buff;
+ unsigned char *lt_bitlen = lt->bitlen;
+ unsigned char *pt_bitlen = pt->bitlen;
+ int blocks_avail = ds->blocks_avail, c = 0;
+ int copy_len = ds->copy_len, copy_pos = ds->copy_pos;
+ int w_pos = ds->w_pos, w_mask = ds->w_mask, w_size = ds->w_size;
+ int lt_max_bits = lt->max_bits, pt_max_bits = pt->max_bits;
+ int state = ds->state;
+
+ if (ds->w_remaining > 0) {
+ if (!lzh_copy_from_window(strm, ds))
+ goto next_data;
+ }
+ for (;;) {
+ switch (state) {
+ case ST_GET_LITERAL:
+ for (;;) {
+ if (blocks_avail == 0) {
+ /* We have decoded all blocks.
+ * Let's handle next blocks. */
+ ds->state = ST_RD_BLOCK;
+ ds->br = bre;
+ ds->blocks_avail = 0;
+ ds->w_pos = w_pos;
+ ds->copy_pos = 0;
+ return (100);
+ }
+
+ /* lzh_br_read_ahead() always try to fill the
+ * cache buffer up. In specific situation we
+ * are close to the end of the data, the cache
+ * buffer will not be full and thus we have to
+ * determine if the cache buffer has some bits
+ * as much as we need after lzh_br_read_ahead()
+ * failed. */
+ if (!lzh_br_read_ahead(strm, &bre,
+ lt_max_bits)) {
+ if (!last)
+ goto next_data;
+ /* Remaining bits are less than
+ * maximum bits(lt.max_bits) but maybe
+ * it still remains as much as we need,
+ * so we should try to use it with
+ * dummy bits. */
+ c = lzh_decode_huffman(lt,
+ lzh_br_bits_forced(&bre,
+ lt_max_bits));
+ lzh_br_consume(&bre, lt_bitlen[c]);
+ if (!lzh_br_has(&bre, 0))
+ goto failed;/* Over read. */
+ } else {
+ c = lzh_decode_huffman(lt,
+ lzh_br_bits(&bre, lt_max_bits));
+ lzh_br_consume(&bre, lt_bitlen[c]);
+ }
+ blocks_avail--;
+ if (c > UCHAR_MAX)
+ /* Current block is a match data. */
+ break;
+ /*
+ * 'c' is exactly a literal code.
+ */
+ /* Save a decoded code to reference it
+ * afterward. */
+ w_buff[w_pos] = c;
+ if (++w_pos >= w_size) {
+ w_pos = 0;
+ ds->w_remaining = w_size;
+ if (!lzh_copy_from_window(strm, ds))
+ goto next_data;
+ }
+ }
+ /* 'c' is the length of a match pattern we have
+ * already extracted, which has be stored in
+ * window(ds->w_buff). */
+ copy_len = c - (UCHAR_MAX + 1) + MINMATCH;
+ /* FALL THROUGH */
+ case ST_GET_POS_1:
+ /*
+ * Get a reference position.
+ */
+ if (!lzh_br_read_ahead(strm, &bre, pt_max_bits)) {
+ if (!last) {
+ state = ST_GET_POS_1;
+ ds->copy_len = copy_len;
+ goto next_data;
+ }
+ copy_pos = lzh_decode_huffman(pt,
+ lzh_br_bits_forced(&bre, pt_max_bits));
+ lzh_br_consume(&bre, pt_bitlen[copy_pos]);
+ if (!lzh_br_has(&bre, 0))
+ goto failed;/* Over read. */
+ } else {
+ copy_pos = lzh_decode_huffman(pt,
+ lzh_br_bits(&bre, pt_max_bits));
+ lzh_br_consume(&bre, pt_bitlen[copy_pos]);
+ }
+ /* FALL THROUGH */
+ case ST_GET_POS_2:
+ if (copy_pos > 1) {
+ /* We need an additional adjustment number to
+ * the position. */
+ int p = copy_pos - 1;
+ if (!lzh_br_read_ahead(strm, &bre, p)) {
+ if (last)
+ goto failed;/* Truncated data.*/
+ state = ST_GET_POS_2;
+ ds->copy_len = copy_len;
+ ds->copy_pos = copy_pos;
+ goto next_data;
+ }
+ copy_pos = (1 << p) + lzh_br_bits(&bre, p);
+ lzh_br_consume(&bre, p);
+ }
+ /* The position is actually a distance from the last
+ * code we had extracted and thus we have to convert
+ * it to a position of the window. */
+ copy_pos = (w_pos - copy_pos - 1) & w_mask;
+ /* FALL THROUGH */
+ case ST_COPY_DATA:
+ /*
+ * Copy `copy_len' bytes as extracted data from
+ * the window into the output buffer.
+ */
+ for (;;) {
+ int l;
+
+ l = copy_len;
+ if (copy_pos > w_pos) {
+ if (l > w_size - copy_pos)
+ l = w_size - copy_pos;
+ } else {
+ if (l > w_size - w_pos)
+ l = w_size - w_pos;
+ }
+ if ((copy_pos + l < w_pos)
+ || (w_pos + l < copy_pos)) {
+ /* No overlap. */
+ memcpy(w_buff + w_pos,
+ w_buff + copy_pos, l);
+ } else {
+ const unsigned char *s;
+ unsigned char *d;
+ int li;
+
+ d = w_buff + w_pos;
+ s = w_buff + copy_pos;
+ for (li = 0; li < l; li++)
+ d[li] = s[li];
+ }
+ w_pos = (w_pos + l) & w_mask;
+ if (w_pos == 0) {
+ ds->w_remaining = w_size;
+ if (!lzh_copy_from_window(strm, ds)) {
+ if (copy_len <= l)
+ state = ST_GET_LITERAL;
+ else {
+ state = ST_COPY_DATA;
+ ds->copy_len =
+ copy_len - l;
+ ds->copy_pos =
+ (copy_pos + l)
+ & w_mask;
+ }
+ goto next_data;
+ }
+ }
+ if (copy_len <= l)
+ /* A copy of current pattern ended. */
+ break;
+ copy_len -= l;
+ copy_pos = (copy_pos + l) & w_mask;
+ }
+ state = ST_GET_LITERAL;
+ break;
+ }
+ }
+failed:
+ return (ds->error = ARCHIVE_FAILED);
+next_data:
+ ds->br = bre;
+ ds->blocks_avail = blocks_avail;
+ ds->state = state;
+ ds->w_pos = w_pos;
+ return (ARCHIVE_OK);
+}
+
+static int
+lzh_huffman_init(struct huffman *hf, size_t len_size, int tbl_bits)
+{
+ int bits;
+
+ if (hf->bitlen == NULL) {
+ hf->bitlen = malloc(len_size * sizeof(hf->bitlen[0]));
+ if (hf->bitlen == NULL)
+ return (ARCHIVE_FATAL);
+ }
+ if (hf->tbl == NULL) {
+ if (tbl_bits < HTBL_BITS)
+ bits = tbl_bits;
+ else
+ bits = HTBL_BITS;
+ hf->tbl = malloc((1 << bits) * sizeof(hf->tbl[0]));
+ if (hf->tbl == NULL)
+ return (ARCHIVE_FATAL);
+ }
+ if (hf->tree == NULL && tbl_bits > HTBL_BITS) {
+ hf->tree_avail = 1 << (tbl_bits - HTBL_BITS + 4);
+ hf->tree = malloc(hf->tree_avail * sizeof(hf->tree[0]));
+ if (hf->tree == NULL)
+ return (ARCHIVE_FATAL);
+ }
+ hf->len_size = len_size;
+ hf->tbl_bits = tbl_bits;
+ return (ARCHIVE_OK);
+}
+
+static void
+lzh_huffman_free(struct huffman *hf)
+{
+ free(hf->bitlen);
+ free(hf->tbl);
+ free(hf->tree);
+}
+
+static int
+lzh_read_pt_bitlen(struct lzh_stream *strm, int start, int end)
+{
+ struct lzh_dec *ds = strm->ds;
+ struct lzh_br * br = &(ds->br);
+ int c, i;
+
+ for (i = start; i < end;) {
+ /*
+ * bit pattern the number we need
+ * 000 -> 0
+ * 001 -> 1
+ * 010 -> 2
+ * ...
+ * 110 -> 6
+ * 1110 -> 7
+ * 11110 -> 8
+ * ...
+ * 1111111111110 -> 16
+ */
+ if (!lzh_br_read_ahead(strm, br, 3))
+ return (i);
+ if ((c = lzh_br_bits(br, 3)) == 7) {
+ int d;
+ if (!lzh_br_read_ahead(strm, br, 13))
+ return (i);
+ d = lzh_br_bits(br, 13);
+ while (d & 0x200) {
+ c++;
+ d <<= 1;
+ }
+ if (c > 16)
+ return (-1);/* Invalid data. */
+ lzh_br_consume(br, c - 3);
+ } else
+ lzh_br_consume(br, 3);
+ ds->pt.bitlen[i++] = c;
+ ds->pt.freq[c]++;
+ }
+ return (i);
+}
+
+static int
+lzh_make_fake_table(struct huffman *hf, uint16_t c)
+{
+ if (c >= hf->len_size)
+ return (0);
+ hf->tbl[0] = c;
+ hf->max_bits = 0;
+ hf->shift_bits = 0;
+ hf->bitlen[hf->tbl[0]] = 0;
+ return (1);
+}
+
+/*
+ * Make a huffman coding table.
+ */
+static int
+lzh_make_huffman_table(struct huffman *hf)
+{
+ uint16_t *tbl;
+ const unsigned char *bitlen;
+ int bitptn[17], weight[17];
+ int i, maxbits = 0, ptn, tbl_size, w;
+ int diffbits, len_avail;
+
+ /*
+ * Initialize bit patterns.
+ */
+ ptn = 0;
+ for (i = 1, w = 1 << 15; i <= 16; i++, w >>= 1) {
+ bitptn[i] = ptn;
+ weight[i] = w;
+ if (hf->freq[i]) {
+ ptn += hf->freq[i] * w;
+ maxbits = i;
+ }
+ }
+ if (ptn != 0x10000 || maxbits > hf->tbl_bits)
+ return (0);/* Invalid */
+
+ hf->max_bits = maxbits;
+
+ /*
+ * Cut out extra bits which we won't house in the table.
+ * This preparation reduces the same calculation in the for-loop
+ * making the table.
+ */
+ if (maxbits < 16) {
+ int ebits = 16 - maxbits;
+ for (i = 1; i <= maxbits; i++) {
+ bitptn[i] >>= ebits;
+ weight[i] >>= ebits;
+ }
+ }
+ if (maxbits > HTBL_BITS) {
+ int htbl_max;
+ uint16_t *p;
+
+ diffbits = maxbits - HTBL_BITS;
+ for (i = 1; i <= HTBL_BITS; i++) {
+ bitptn[i] >>= diffbits;
+ weight[i] >>= diffbits;
+ }
+ htbl_max = bitptn[HTBL_BITS] +
+ weight[HTBL_BITS] * hf->freq[HTBL_BITS];
+ p = &(hf->tbl[htbl_max]);
+ while (p < &hf->tbl[1U<<HTBL_BITS])
+ *p++ = 0;
+ } else
+ diffbits = 0;
+ hf->shift_bits = diffbits;
+
+ /*
+ * Make the table.
+ */
+ tbl_size = 1 << HTBL_BITS;
+ tbl = hf->tbl;
+ bitlen = hf->bitlen;
+ len_avail = hf->len_avail;
+ hf->tree_used = 0;
+ for (i = 0; i < len_avail; i++) {
+ uint16_t *p;
+ int len, cnt;
+ uint16_t bit;
+ int extlen;
+ struct htree_t *ht;
+
+ if (bitlen[i] == 0)
+ continue;
+ /* Get a bit pattern */
+ len = bitlen[i];
+ ptn = bitptn[len];
+ cnt = weight[len];
+ if (len <= HTBL_BITS) {
+ /* Calculate next bit pattern */
+ if ((bitptn[len] = ptn + cnt) > tbl_size)
+ return (0);/* Invalid */
+ /* Update the table */
+ p = &(tbl[ptn]);
+ while (--cnt >= 0)
+ p[cnt] = (uint16_t)i;
+ continue;
+ }
+
+ /*
+ * A bit length is too big to be housed to a direct table,
+ * so we use a tree model for its extra bits.
+ */
+ bitptn[len] = ptn + cnt;
+ bit = 1U << (diffbits -1);
+ extlen = len - HTBL_BITS;
+
+ p = &(tbl[ptn >> diffbits]);
+ if (*p == 0) {
+ *p = len_avail + hf->tree_used;
+ ht = &(hf->tree[hf->tree_used++]);
+ if (hf->tree_used > hf->tree_avail)
+ return (0);/* Invalid */
+ ht->left = 0;
+ ht->right = 0;
+ } else {
+ if (*p < len_avail ||
+ *p >= (len_avail + hf->tree_used))
+ return (0);/* Invalid */
+ ht = &(hf->tree[*p - len_avail]);
+ }
+ while (--extlen > 0) {
+ if (ptn & bit) {
+ if (ht->left < len_avail) {
+ ht->left = len_avail + hf->tree_used;
+ ht = &(hf->tree[hf->tree_used++]);
+ if (hf->tree_used > hf->tree_avail)
+ return (0);/* Invalid */
+ ht->left = 0;
+ ht->right = 0;
+ } else {
+ ht = &(hf->tree[ht->left - len_avail]);
+ }
+ } else {
+ if (ht->right < len_avail) {
+ ht->right = len_avail + hf->tree_used;
+ ht = &(hf->tree[hf->tree_used++]);
+ if (hf->tree_used > hf->tree_avail)
+ return (0);/* Invalid */
+ ht->left = 0;
+ ht->right = 0;
+ } else {
+ ht = &(hf->tree[ht->right - len_avail]);
+ }
+ }
+ bit >>= 1;
+ }
+ if (ptn & bit) {
+ if (ht->left != 0)
+ return (0);/* Invalid */
+ ht->left = (uint16_t)i;
+ } else {
+ if (ht->right != 0)
+ return (0);/* Invalid */
+ ht->right = (uint16_t)i;
+ }
+ }
+ return (1);
+}
+
+static int
+lzh_decode_huffman_tree(struct huffman *hf, unsigned rbits, int c)
+{
+ struct htree_t *ht;
+ int extlen;
+
+ ht = hf->tree;
+ extlen = hf->shift_bits;
+ while (c >= hf->len_avail) {
+ c -= hf->len_avail;
+ if (extlen-- <= 0 || c >= hf->tree_used)
+ return (0);
+ if (rbits & (1U << extlen))
+ c = ht[c].left;
+ else
+ c = ht[c].right;
+ }
+ return (c);
+}
+
+static inline int
+lzh_decode_huffman(struct huffman *hf, unsigned rbits)
+{
+ int c;
+ /*
+ * At first search an index table for a bit pattern.
+ * If it fails, search a huffman tree for.
+ */
+ c = hf->tbl[rbits >> hf->shift_bits];
+ if (c < hf->len_avail)
+ return (c);
+ /* This bit pattern needs to be found out at a huffman tree. */
+ return (lzh_decode_huffman_tree(hf, rbits, c));
+}
+
diff --git a/libarchive/archive_read_support_format_mtree.c b/libarchive/archive_read_support_format_mtree.c
index 811d1a3f93e2..3ba4be008e01 100644
--- a/libarchive/archive_read_support_format_mtree.c
+++ b/libarchive/archive_read_support_format_mtree.c
@@ -1,6 +1,7 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* Copyright (c) 2008 Joerg Sonnenberger
+ * Copyright (c) 2011 Michihiro NAKAJIMA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -86,9 +87,8 @@ struct mtree {
struct archive_string line;
size_t buffsize;
char *buff;
- off_t offset;
+ int64_t offset;
int fd;
- int filetype;
int archive_format;
const char *archive_format_name;
struct mtree_entry *entries;
@@ -98,11 +98,11 @@ struct mtree {
struct archive_entry_linkresolver *resolver;
- off_t cur_size, cur_offset;
+ int64_t cur_size;
};
static int cleanup(struct archive_read *);
-static int mtree_bid(struct archive_read *);
+static int mtree_bid(struct archive_read *, int);
static int parse_file(struct archive_read *, struct archive_entry *,
struct mtree *, struct mtree_entry *, int *);
static void parse_escapes(char *, struct mtree_entry *);
@@ -111,7 +111,7 @@ static int parse_line(struct archive_read *, struct archive_entry *,
static int parse_keyword(struct archive_read *, struct mtree *,
struct archive_entry *, struct mtree_option *, int *);
static int read_data(struct archive_read *a,
- const void **buff, size_t *size, off_t *offset);
+ const void **buff, size_t *size, int64_t *offset);
static ssize_t readline(struct archive_read *, struct mtree *, char **, ssize_t);
static int skip(struct archive_read *a);
static int read_header(struct archive_read *,
@@ -120,6 +120,53 @@ static int64_t mtree_atol10(char **);
static int64_t mtree_atol8(char **);
static int64_t mtree_atol(char **);
+/*
+ * There's no standard for TIME_T_MAX/TIME_T_MIN. So we compute them
+ * here. TODO: Move this to configure time, but be careful
+ * about cross-compile environments.
+ */
+static int64_t
+get_time_t_max(void)
+{
+#if defined(TIME_T_MAX)
+ return TIME_T_MAX;
+#else
+ static time_t t;
+ time_t a;
+ if (t == 0) {
+ a = 1;
+ while (a > t) {
+ t = a;
+ a = a * 2 + 1;
+ }
+ }
+ return t;
+#endif
+}
+
+static int64_t
+get_time_t_min(void)
+{
+#if defined(TIME_T_MIN)
+ return TIME_T_MIN;
+#else
+ /* 't' will hold the minimum value, which will be zero (if
+ * time_t is unsigned) or -2^n (if time_t is signed). */
+ static int computed;
+ static time_t t;
+ time_t a;
+ if (computed == 0) {
+ a = (time_t)-1;
+ while (a < t) {
+ t = a;
+ a = a * 2;
+ }
+ computed = 1;
+ }
+ return t;
+#endif
+}
+
static void
free_options(struct mtree_option *head)
{
@@ -139,6 +186,9 @@ archive_read_support_format_mtree(struct archive *_a)
struct mtree *mtree;
int r;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_mtree");
+
mtree = (struct mtree *)malloc(sizeof(*mtree));
if (mtree == NULL) {
archive_set_error(&a->archive, ENOMEM,
@@ -183,20 +233,389 @@ cleanup(struct archive_read *a)
return (ARCHIVE_OK);
}
+static ssize_t
+get_line_size(const char *b, ssize_t avail, ssize_t *nlsize)
+{
+ ssize_t len;
+
+ len = 0;
+ while (len < avail) {
+ switch (*b) {
+ case '\0':/* Non-ascii character or control character. */
+ if (nlsize != NULL)
+ *nlsize = 0;
+ return (-1);
+ case '\r':
+ if (avail-len > 1 && b[1] == '\n') {
+ if (nlsize != NULL)
+ *nlsize = 2;
+ return (len+2);
+ }
+ /* FALL THROUGH */
+ case '\n':
+ if (nlsize != NULL)
+ *nlsize = 1;
+ return (len+1);
+ default:
+ b++;
+ len++;
+ break;
+ }
+ }
+ if (nlsize != NULL)
+ *nlsize = 0;
+ return (avail);
+}
+
+static ssize_t
+next_line(struct archive_read *a,
+ const char **b, ssize_t *avail, ssize_t *ravail, ssize_t *nl)
+{
+ ssize_t len;
+ int quit;
+
+ quit = 0;
+ if (*avail == 0) {
+ *nl = 0;
+ len = 0;
+ } else
+ len = get_line_size(*b, *avail, nl);
+ /*
+ * Read bytes more while it does not reach the end of line.
+ */
+ while (*nl == 0 && len == *avail && !quit) {
+ ssize_t diff = *ravail - *avail;
+ size_t nbytes_req = (*ravail+1023) & ~1023U;
+ ssize_t tested;
+
+ /* Increase reading bytes if it is not enough to at least
+ * new two lines. */
+ if (nbytes_req < (size_t)*ravail + 160)
+ nbytes_req <<= 1;
+
+ *b = __archive_read_ahead(a, nbytes_req, avail);
+ if (*b == NULL) {
+ if (*ravail >= *avail)
+ return (0);
+ /* Reading bytes reaches the end of file. */
+ *b = __archive_read_ahead(a, *avail, avail);
+ quit = 1;
+ }
+ *ravail = *avail;
+ *b += diff;
+ *avail -= diff;
+ tested = len;/* Skip some bytes we already determinated. */
+ len = get_line_size(*b, *avail, nl);
+ if (len >= 0)
+ len += tested;
+ }
+ return (len);
+}
+/*
+ * Compare characters with a mtree keyword.
+ * Returns the length of a mtree keyword if matched.
+ * Returns 0 if not matched.
+ */
+int
+bid_keycmp(const char *p, const char *key, ssize_t len)
+{
+ int match_len = 0;
+
+ while (len > 0 && *p && *key) {
+ if (*p == *key) {
+ --len;
+ ++p;
+ ++key;
+ ++match_len;
+ continue;
+ }
+ return (0);/* Not match */
+ }
+ if (*key != '\0')
+ return (0);/* Not match */
+
+ /* A following character should be specified characters */
+ if (p[0] == '=' || p[0] == ' ' || p[0] == '\t' ||
+ p[0] == '\n' || p[0] == '\r' ||
+ (p[0] == '\\' && (p[1] == '\n' || p[1] == '\r')))
+ return (match_len);
+ return (0);/* Not match */
+}
+
+/*
+ * Test whether the characters 'p' has is mtree keyword.
+ * Returns the length of a detected keyword.
+ * Returns 0 if any keywords were not found.
+ */
+static ssize_t
+bid_keyword(const char *p, ssize_t len)
+{
+ static const char *keys_c[] = {
+ "content", "contents", "cksum", NULL
+ };
+ static const char *keys_df[] = {
+ "device", "flags", NULL
+ };
+ static const char *keys_g[] = {
+ "gid", "gname", NULL
+ };
+ static const char *keys_il[] = {
+ "ignore", "link", NULL
+ };
+ static const char *keys_m[] = {
+ "md5", "md5digest", "mode", NULL
+ };
+ static const char *keys_no[] = {
+ "nlink", "optional", NULL
+ };
+ static const char *keys_r[] = {
+ "rmd160", "rmd160digest", NULL
+ };
+ static const char *keys_s[] = {
+ "sha1", "sha1digest",
+ "sha256", "sha256digest",
+ "sha384", "sha384digest",
+ "sha512", "sha512digest",
+ "size", NULL
+ };
+ static const char *keys_t[] = {
+ "tags", "time", "type", NULL
+ };
+ static const char *keys_u[] = {
+ "uid", "uname", NULL
+ };
+ const char **keys;
+ int i;
+
+ switch (*p) {
+ case 'c': keys = keys_c; break;
+ case 'd': case 'f': keys = keys_df; break;
+ case 'g': keys = keys_g; break;
+ case 'i': case 'l': keys = keys_il; break;
+ case 'm': keys = keys_m; break;
+ case 'n': case 'o': keys = keys_no; break;
+ case 'r': keys = keys_r; break;
+ case 's': keys = keys_s; break;
+ case 't': keys = keys_t; break;
+ case 'u': keys = keys_u; break;
+ default: return (0);/* Unknown key */
+ }
+
+ for (i = 0; keys[i] != NULL; i++) {
+ int l = bid_keycmp(p, keys[i], len);
+ if (l > 0)
+ return (l);
+ }
+ return (0);/* Unknown key */
+}
+
+/*
+ * Test whether there is a set of mtree keywords.
+ * Returns the number of keyword.
+ * Returns -1 if we got incorrect sequence.
+ * This function expects a set of "<space characters>keyword=value".
+ * When "unset" is specified, expects a set of "<space characters>keyword".
+ */
static int
-mtree_bid(struct archive_read *a)
+bid_keyword_list(const char *p, ssize_t len, int unset)
+{
+ int l;
+ int keycnt = 0;
+
+ while (len > 0 && *p) {
+ int blank = 0;
+
+ /* Test whether there are blank characters in the line. */
+ while (len >0 && (*p == ' ' || *p == '\t')) {
+ ++p;
+ --len;
+ blank = 1;
+ }
+ if (*p == '\n' || *p == '\r')
+ break;
+ if (p[0] == '\\' && (p[1] == '\n' || p[1] == '\r'))
+ break;
+ if (!blank) /* No blank character. */
+ return (-1);
+
+ if (unset) {
+ l = bid_keycmp(p, "all", len);
+ if (l > 0)
+ return (1);
+ }
+ /* Test whether there is a correct key in the line. */
+ l = bid_keyword(p, len);
+ if (l == 0)
+ return (-1);/* Unknown keyword was found. */
+ p += l;
+ len -= l;
+ keycnt++;
+
+ /* Skip value */
+ if (*p == '=') {
+ int value = 0;
+ ++p;
+ --len;
+ while (len > 0 && *p != ' ' && *p != '\t') {
+ ++p;
+ --len;
+ value = 1;
+ }
+ /* A keyword should have a its value unless
+ * "/unset" operation. */
+ if (!unset && value == 0)
+ return (-1);
+ }
+ }
+ return (keycnt);
+}
+
+static int
+bid_entry(const char *p, ssize_t len)
+{
+ int f = 0;
+ static const unsigned char safe_char[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 00 - 0F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 1F */
+ /* !"$%&'()*+,-./ EXCLUSION:( )(#) */
+ 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 - 2F */
+ /* 0123456789:;<>? EXCLUSION:(=) */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, /* 30 - 3F */
+ /* @ABCDEFGHIJKLMNO */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 - 4F */
+ /* PQRSTUVWXYZ[\]^_ */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 50 - 5F */
+ /* `abcdefghijklmno */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60 - 6F */
+ /* pqrstuvwxyz{|}~ */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* 70 - 7F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 8F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 - 9F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A0 - AF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0 - BF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* C0 - CF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* D0 - DF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* E0 - EF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F0 - FF */
+ };
+
+ /*
+ * Skip the path-name which is quoted.
+ */
+ while (len > 0 && *p != ' ' && *p != '\t') {
+ if (!safe_char[*(const unsigned char *)p])
+ return (-1);
+ ++p;
+ --len;
+ ++f;
+ }
+ /* If a path-name was not found, returns error. */
+ if (f == 0)
+ return (-1);
+
+ return (bid_keyword_list(p, len, 0));
+}
+
+#define MAX_BID_ENTRY 3
+
+static int
+mtree_bid(struct archive_read *a, int best_bid)
{
const char *signature = "#mtree";
const char *p;
+ ssize_t avail, ravail;
+ ssize_t len, nl;
+ int detected_bytes = 0, entry_cnt = 0, multiline = 0;
+
+ (void)best_bid; /* UNUSED */
/* Now let's look at the actual header and see if it matches. */
- p = __archive_read_ahead(a, strlen(signature), NULL);
+ p = __archive_read_ahead(a, strlen(signature), &avail);
if (p == NULL)
return (-1);
- if (strncmp(p, signature, strlen(signature)) == 0)
+ if (memcmp(p, signature, strlen(signature)) == 0)
return (8 * (int)strlen(signature));
+
+ /*
+ * There is not a mtree signature. Let's try to detect mtree format.
+ */
+ ravail = avail;
+ for (;;) {
+ len = next_line(a, &p, &avail, &ravail, &nl);
+ /* The terminal character of the line should be
+ * a new line character, '\r\n' or '\n'. */
+ if (len <= 0 || nl == 0)
+ break;
+ if (!multiline) {
+ /* Leading whitespace is never significant,
+ * ignore it. */
+ while (len > 0 && (*p == ' ' || *p == '\t')) {
+ ++p;
+ --avail;
+ --len;
+ }
+ /* Skip comment or empty line. */
+ if (p[0] == '#' || p[0] == '\n' || p[0] == '\r') {
+ p += len;
+ avail -= len;
+ continue;
+ }
+ } else {
+ /* A continuance line; the terminal
+ * character of previous line was '\' character. */
+ if (bid_keyword_list(p, len, 0) <= 0)
+ break;
+ if (multiline == 1)
+ detected_bytes += len;
+ if (p[len-nl-1] != '\\') {
+ if (multiline == 1 &&
+ ++entry_cnt >= MAX_BID_ENTRY)
+ break;
+ multiline = 0;
+ }
+ p += len;
+ avail -= len;
+ continue;
+ }
+ if (p[0] != '/') {
+ if (bid_entry(p, len) >= 0) {
+ detected_bytes += len;
+ if (p[len-nl-1] == '\\')
+ /* This line continues. */
+ multiline = 1;
+ else {
+ /* We've got plenty of correct lines
+ * to assume that this file is a mtree
+ * format. */
+ if (++entry_cnt >= MAX_BID_ENTRY)
+ break;
+ }
+ } else
+ break;
+ } else if (strncmp(p, "/set", 4) == 0) {
+ if (bid_keyword_list(p+4, len-4, 0) <= 0)
+ break;
+ /* This line continues. */
+ if (p[len-nl-1] == '\\')
+ multiline = 2;
+ } else if (strncmp(p, "/unset", 6) == 0) {
+ if (bid_keyword_list(p+6, len-6, 1) <= 0)
+ break;
+ /* This line continues. */
+ if (p[len-nl-1] == '\\')
+ multiline = 2;
+ } else
+ break;
+
+ /* Test next line. */
+ p += len;
+ avail -= len;
+ }
+ if (entry_cnt >= MAX_BID_ENTRY || (entry_cnt > 0 && len == 0))
+ return (32);
+
return (0);
}
@@ -215,21 +634,21 @@ static int
add_option(struct archive_read *a, struct mtree_option **global,
const char *value, size_t len)
{
- struct mtree_option *option;
+ struct mtree_option *opt;
- if ((option = malloc(sizeof(*option))) == NULL) {
+ if ((opt = malloc(sizeof(*opt))) == NULL) {
archive_set_error(&a->archive, errno, "Can't allocate memory");
return (ARCHIVE_FATAL);
}
- if ((option->value = malloc(len + 1)) == NULL) {
- free(option);
+ if ((opt->value = malloc(len + 1)) == NULL) {
+ free(opt);
archive_set_error(&a->archive, errno, "Can't allocate memory");
return (ARCHIVE_FATAL);
}
- memcpy(option->value, value, len);
- option->value[len] = '\0';
- option->next = *global;
- *global = option;
+ memcpy(opt->value, value, len);
+ opt->value[len] = '\0';
+ opt->next = *global;
+ *global = opt;
return (ARCHIVE_OK);
}
@@ -400,7 +819,7 @@ read_mtree(struct archive_read *a, struct mtree *mtree)
last_entry = NULL;
for (counter = 1; ; ++counter) {
- len = readline(a, mtree, &p, 256);
+ len = readline(a, mtree, &p, 65536);
if (len == 0) {
mtree->this_entry = mtree->entries;
free_options(global);
@@ -518,12 +937,12 @@ parse_file(struct archive_read *a, struct archive_entry *entry,
struct stat st_storage, *st;
struct mtree_entry *mp;
struct archive_entry *sparse_entry;
- int r = ARCHIVE_OK, r1, parsed_kws, mismatched_type;
+ int r = ARCHIVE_OK, r1, parsed_kws;
mentry->used = 1;
/* Initialize reasonable defaults. */
- mtree->filetype = AE_IFREG;
+ archive_entry_set_filetype(entry, AE_IFREG);
archive_entry_set_size(entry, 0);
archive_string_empty(&mtree->contents_name);
@@ -618,44 +1037,49 @@ parse_file(struct archive_read *a, struct archive_entry *entry,
* the type of the contents object on disk.
*/
if (st != NULL) {
- mismatched_type = 0;
- if ((st->st_mode & S_IFMT) == S_IFREG &&
- archive_entry_filetype(entry) != AE_IFREG)
- mismatched_type = 1;
- if ((st->st_mode & S_IFMT) == S_IFLNK &&
- archive_entry_filetype(entry) != AE_IFLNK)
- mismatched_type = 1;
- if ((st->st_mode & S_IFSOCK) == S_IFSOCK &&
- archive_entry_filetype(entry) != AE_IFSOCK)
- mismatched_type = 1;
- if ((st->st_mode & S_IFMT) == S_IFCHR &&
- archive_entry_filetype(entry) != AE_IFCHR)
- mismatched_type = 1;
- if ((st->st_mode & S_IFMT) == S_IFBLK &&
- archive_entry_filetype(entry) != AE_IFBLK)
- mismatched_type = 1;
- if ((st->st_mode & S_IFMT) == S_IFDIR &&
- archive_entry_filetype(entry) != AE_IFDIR)
- mismatched_type = 1;
- if ((st->st_mode & S_IFMT) == S_IFIFO &&
- archive_entry_filetype(entry) != AE_IFIFO)
- mismatched_type = 1;
-
- if (mismatched_type) {
- if ((parsed_kws & MTREE_HAS_OPTIONAL) == 0) {
+ if (
+ ((st->st_mode & S_IFMT) == S_IFREG &&
+ archive_entry_filetype(entry) == AE_IFREG)
+#ifdef S_IFLNK
+ || ((st->st_mode & S_IFMT) == S_IFLNK &&
+ archive_entry_filetype(entry) == AE_IFLNK)
+#endif
+#ifdef S_IFSOCK
+ || ((st->st_mode & S_IFSOCK) == S_IFSOCK &&
+ archive_entry_filetype(entry) == AE_IFSOCK)
+#endif
+#ifdef S_IFCHR
+ || ((st->st_mode & S_IFMT) == S_IFCHR &&
+ archive_entry_filetype(entry) == AE_IFCHR)
+#endif
+#ifdef S_IFBLK
+ || ((st->st_mode & S_IFMT) == S_IFBLK &&
+ archive_entry_filetype(entry) == AE_IFBLK)
+#endif
+ || ((st->st_mode & S_IFMT) == S_IFDIR &&
+ archive_entry_filetype(entry) == AE_IFDIR)
+#ifdef S_IFIFO
+ || ((st->st_mode & S_IFMT) == S_IFIFO &&
+ archive_entry_filetype(entry) == AE_IFIFO)
+#endif
+ ) {
+ /* Types match. */
+ } else {
+ /* Types don't match; bail out gracefully. */
+ if (mtree->fd >= 0)
+ close(mtree->fd);
+ mtree->fd = -1;
+ if (parsed_kws & MTREE_HAS_OPTIONAL) {
+ /* It's not an error for an optional entry
+ to not match disk. */
+ *use_next = 1;
+ } else if (r == ARCHIVE_OK) {
archive_set_error(&a->archive,
ARCHIVE_ERRNO_MISC,
"mtree specification has different type for %s",
archive_entry_pathname(entry));
r = ARCHIVE_WARN;
- } else {
- *use_next = 1;
}
- /* Don't hold a non-regular file open. */
- if (mtree->fd >= 0)
- close(mtree->fd);
- mtree->fd = -1;
- st = NULL;
return r;
}
}
@@ -735,7 +1159,7 @@ parse_line(struct archive_read *a, struct archive_entry *entry,
if (r1 < r)
r = r1;
}
- if ((*parsed_kws & MTREE_HAS_TYPE) == 0) {
+ if (r == ARCHIVE_OK && (*parsed_kws & MTREE_HAS_TYPE) == 0) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Missing type keyword in mtree specification");
return (ARCHIVE_WARN);
@@ -779,11 +1203,11 @@ parse_device(struct archive *a, struct archive_entry *entry, char *val)
*/
static int
parse_keyword(struct archive_read *a, struct mtree *mtree,
- struct archive_entry *entry, struct mtree_option *option, int *parsed_kws)
+ struct archive_entry *entry, struct mtree_option *opt, int *parsed_kws)
{
char *val, *key;
- key = option->value;
+ key = opt->value;
if (*key == '\0')
return (ARCHIVE_OK);
@@ -900,58 +1324,67 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
break;
}
if (strcmp(key, "time") == 0) {
- time_t m;
+ int64_t m;
+ int64_t my_time_t_max = get_time_t_max();
+ int64_t my_time_t_min = get_time_t_min();
long ns;
*parsed_kws |= MTREE_HAS_MTIME;
- m = (time_t)mtree_atol10(&val);
+ m = mtree_atol10(&val);
+ /* Replicate an old mtree bug:
+ * 123456789.1 represents 123456789
+ * seconds and 1 nanosecond. */
if (*val == '.') {
++val;
ns = (long)mtree_atol10(&val);
} else
ns = 0;
- archive_entry_set_mtime(entry, m, ns);
+ if (m > my_time_t_max)
+ m = my_time_t_max;
+ else if (m < my_time_t_min)
+ m = my_time_t_min;
+ archive_entry_set_mtime(entry, (time_t)m, ns);
break;
}
if (strcmp(key, "type") == 0) {
- *parsed_kws |= MTREE_HAS_TYPE;
switch (val[0]) {
case 'b':
if (strcmp(val, "block") == 0) {
- mtree->filetype = AE_IFBLK;
+ archive_entry_set_filetype(entry, AE_IFBLK);
break;
}
case 'c':
if (strcmp(val, "char") == 0) {
- mtree->filetype = AE_IFCHR;
+ archive_entry_set_filetype(entry, AE_IFCHR);
break;
}
case 'd':
if (strcmp(val, "dir") == 0) {
- mtree->filetype = AE_IFDIR;
+ archive_entry_set_filetype(entry, AE_IFDIR);
break;
}
case 'f':
if (strcmp(val, "fifo") == 0) {
- mtree->filetype = AE_IFIFO;
+ archive_entry_set_filetype(entry, AE_IFIFO);
break;
}
if (strcmp(val, "file") == 0) {
- mtree->filetype = AE_IFREG;
+ archive_entry_set_filetype(entry, AE_IFREG);
break;
}
case 'l':
if (strcmp(val, "link") == 0) {
- mtree->filetype = AE_IFLNK;
+ archive_entry_set_filetype(entry, AE_IFLNK);
break;
}
default:
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
- "Unrecognized file type \"%s\"", val);
+ "Unrecognized file type \"%s\"; assuming \"file\"", val);
+ archive_entry_set_filetype(entry, AE_IFREG);
return (ARCHIVE_WARN);
}
- archive_entry_set_filetype(entry, mtree->filetype);
+ *parsed_kws |= MTREE_HAS_TYPE;
break;
}
case 'u':
@@ -974,7 +1407,7 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
}
static int
-read_data(struct archive_read *a, const void **buff, size_t *size, off_t *offset)
+read_data(struct archive_read *a, const void **buff, size_t *size, int64_t *offset)
{
size_t bytes_to_read;
ssize_t bytes_read;
@@ -999,7 +1432,7 @@ read_data(struct archive_read *a, const void **buff, size_t *size, off_t *offset
*buff = mtree->buff;
*offset = mtree->offset;
- if ((off_t)mtree->buffsize > mtree->cur_size - mtree->offset)
+ if ((int64_t)mtree->buffsize > mtree->cur_size - mtree->offset)
bytes_to_read = mtree->cur_size - mtree->offset;
else
bytes_to_read = mtree->buffsize;
@@ -1147,28 +1580,43 @@ mtree_atol10(char **p)
int base, digit, sign;
base = 10;
- limit = INT64_MAX / base;
- last_digit_limit = INT64_MAX % base;
if (**p == '-') {
sign = -1;
+ limit = ((uint64_t)(INT64_MAX) + 1) / base;
+ last_digit_limit = ((uint64_t)(INT64_MAX) + 1) % base;
++(*p);
- } else
+ } else {
sign = 1;
+ limit = INT64_MAX / base;
+ last_digit_limit = INT64_MAX % base;
+ }
l = 0;
digit = **p - '0';
while (digit >= 0 && digit < base) {
- if (l > limit || (l == limit && digit > last_digit_limit)) {
- l = INT64_MAX; /* Truncate on overflow. */
- break;
- }
+ if (l > limit || (l == limit && digit > last_digit_limit))
+ return (sign < 0) ? INT64_MIN : INT64_MAX;
l = (l * base) + digit;
digit = *++(*p) - '0';
}
return (sign < 0) ? -l : l;
}
+/* Parse a hex digit. */
+static int
+parsehex(char c)
+{
+ if (c >= '0' && c <= '9')
+ return c - '0';
+ else if (c >= 'a' && c <= 'f')
+ return c - 'a';
+ else if (c >= 'A' && c <= 'F')
+ return c - 'A';
+ else
+ return -1;
+}
+
/*
* Note that this implementation does not (and should not!) obey
* locale settings; you cannot simply substitute strtol here, since
@@ -1181,38 +1629,25 @@ mtree_atol16(char **p)
int base, digit, sign;
base = 16;
- limit = INT64_MAX / base;
- last_digit_limit = INT64_MAX % base;
if (**p == '-') {
sign = -1;
+ limit = ((uint64_t)(INT64_MAX) + 1) / base;
+ last_digit_limit = ((uint64_t)(INT64_MAX) + 1) % base;
++(*p);
- } else
+ } else {
sign = 1;
+ limit = INT64_MAX / base;
+ last_digit_limit = INT64_MAX % base;
+ }
l = 0;
- if (**p >= '0' && **p <= '9')
- digit = **p - '0';
- else if (**p >= 'a' && **p <= 'f')
- digit = **p - 'a' + 10;
- else if (**p >= 'A' && **p <= 'F')
- digit = **p - 'A' + 10;
- else
- digit = -1;
+ digit = parsehex(**p);
while (digit >= 0 && digit < base) {
- if (l > limit || (l == limit && digit > last_digit_limit)) {
- l = INT64_MAX; /* Truncate on overflow. */
- break;
- }
+ if (l > limit || (l == limit && digit > last_digit_limit))
+ return (sign < 0) ? INT64_MIN : INT64_MAX;
l = (l * base) + digit;
- if (**p >= '0' && **p <= '9')
- digit = **p - '0';
- else if (**p >= 'a' && **p <= 'f')
- digit = **p - 'a' + 10;
- else if (**p >= 'A' && **p <= 'F')
- digit = **p - 'A' + 10;
- else
- digit = -1;
+ digit = parsehex(*++(*p));
}
return (sign < 0) ? -l : l;
}
diff --git a/libarchive/archive_read_support_format_rar.c b/libarchive/archive_read_support_format_rar.c
new file mode 100644
index 000000000000..c70e0e5b3374
--- /dev/null
+++ b/libarchive/archive_read_support_format_rar.c
@@ -0,0 +1,2574 @@
+/*-
+* Copyright (c) 2003-2007 Tim Kientzle
+* Copyright (c) 2011 Andres Mejia
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "archive_platform.h"
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include <time.h>
+#include <limits.h>
+#ifdef HAVE_ZLIB_H
+#include <zlib.h> /* crc32 */
+#endif
+
+#include "archive.h"
+#ifndef HAVE_ZLIB_H
+#include "archive_crc32.h"
+#endif
+#include "archive_endian.h"
+#include "archive_entry.h"
+#include "archive_entry_locale.h"
+#include "archive_ppmd7_private.h"
+#include "archive_private.h"
+#include "archive_read_private.h"
+
+/* RAR signature, also known as the mark header */
+#define RAR_SIGNATURE "\x52\x61\x72\x21\x1A\x07\x00"
+
+/* Header types */
+#define MARK_HEAD 0x72
+#define MAIN_HEAD 0x73
+#define FILE_HEAD 0x74
+#define COMM_HEAD 0x75
+#define AV_HEAD 0x76
+#define SUB_HEAD 0x77
+#define PROTECT_HEAD 0x78
+#define SIGN_HEAD 0x79
+#define NEWSUB_HEAD 0x7a
+#define ENDARC_HEAD 0x7b
+
+/* Main Header Flags */
+#define MHD_VOLUME 0x0001
+#define MHD_COMMENT 0x0002
+#define MHD_LOCK 0x0004
+#define MHD_SOLID 0x0008
+#define MHD_NEWNUMBERING 0x0010
+#define MHD_AV 0x0020
+#define MHD_PROTECT 0x0040
+#define MHD_PASSWORD 0x0080
+#define MHD_FIRSTVOLUME 0x0100
+#define MHD_ENCRYPTVER 0x0200
+
+/* Flags common to all headers */
+#define HD_MARKDELETION 0x4000
+#define HD_ADD_SIZE_PRESENT 0x8000
+
+/* File Header Flags */
+#define FHD_SPLIT_BEFORE 0x0001
+#define FHD_SPLIT_AFTER 0x0002
+#define FHD_PASSWORD 0x0004
+#define FHD_COMMENT 0x0008
+#define FHD_SOLID 0x0010
+#define FHD_LARGE 0x0100
+#define FHD_UNICODE 0x0200
+#define FHD_SALT 0x0400
+#define FHD_VERSION 0x0800
+#define FHD_EXTTIME 0x1000
+#define FHD_EXTFLAGS 0x2000
+
+/* File dictionary sizes */
+#define DICTIONARY_SIZE_64 0x00
+#define DICTIONARY_SIZE_128 0x20
+#define DICTIONARY_SIZE_256 0x40
+#define DICTIONARY_SIZE_512 0x60
+#define DICTIONARY_SIZE_1024 0x80
+#define DICTIONARY_SIZE_2048 0xA0
+#define DICTIONARY_SIZE_4096 0xC0
+#define FILE_IS_DIRECTORY 0xE0
+#define DICTIONARY_MASK FILE_IS_DIRECTORY
+
+/* OS Flags */
+#define OS_MSDOS 0
+#define OS_OS2 1
+#define OS_WIN32 2
+#define OS_UNIX 3
+#define OS_MAC_OS 4
+#define OS_BEOS 5
+
+/* Compression Methods */
+#define COMPRESS_METHOD_STORE 0x30
+/* LZSS */
+#define COMPRESS_METHOD_FASTEST 0x31
+#define COMPRESS_METHOD_FAST 0x32
+#define COMPRESS_METHOD_NORMAL 0x33
+/* PPMd Variant H */
+#define COMPRESS_METHOD_GOOD 0x34
+#define COMPRESS_METHOD_BEST 0x35
+
+#define CRC_POLYNOMIAL 0xEDB88320
+
+#define NS_UNIT 10000000
+
+#define DICTIONARY_MAX_SIZE 0x400000
+
+#define MAINCODE_SIZE 299
+#define OFFSETCODE_SIZE 60
+#define LOWOFFSETCODE_SIZE 17
+#define LENGTHCODE_SIZE 28
+#define HUFFMAN_TABLE_SIZE \
+ MAINCODE_SIZE + OFFSETCODE_SIZE + LOWOFFSETCODE_SIZE + LENGTHCODE_SIZE
+
+#define MAX_SYMBOL_LENGTH 0xF
+#define MAX_SYMBOLS 20
+
+/*
+ * Considering L1,L2 cache miss and a calling of write system-call,
+ * the best size of the output buffer(uncompressed buffer) is 128K.
+ * If the structure of extracting process is changed, this value
+ * might be researched again.
+ */
+#define UNP_BUFFER_SIZE (128 * 1024)
+
+/* Define this here for non-Windows platforms */
+#if !((defined(__WIN32__) || defined(_WIN32) || defined(__WIN32)) && !defined(__CYGWIN__))
+#define FILE_ATTRIBUTE_DIRECTORY 0x10
+#endif
+
+/* Fields common to all headers */
+struct rar_header
+{
+ char crc[2];
+ char type;
+ char flags[2];
+ char size[2];
+};
+
+/* Fields common to all file headers */
+struct rar_file_header
+{
+ char pack_size[4];
+ char unp_size[4];
+ char host_os;
+ char file_crc[4];
+ char file_time[4];
+ char unp_ver;
+ char method;
+ char name_size[2];
+ char file_attr[4];
+};
+
+struct huffman_tree_node
+{
+ int branches[2];
+};
+
+struct huffman_table_entry
+{
+ unsigned int length;
+ int value;
+};
+
+struct huffman_code
+{
+ struct huffman_tree_node *tree;
+ int numentries;
+ int minlength;
+ int maxlength;
+ int tablesize;
+ struct huffman_table_entry *table;
+};
+
+struct lzss
+{
+ unsigned char *window;
+ int mask;
+ int64_t position;
+};
+
+struct rar
+{
+ /* Entries from main RAR header */
+ unsigned main_flags;
+ unsigned long file_crc;
+ char reserved1[2];
+ char reserved2[4];
+ char encryptver;
+
+ /* File header entries */
+ char compression_method;
+ unsigned file_flags;
+ int64_t packed_size;
+ int64_t unp_size;
+ time_t mtime;
+ long mnsec;
+ mode_t mode;
+ char *filename;
+ size_t filename_allocated;
+
+ /* File header optional entries */
+ char salt[8];
+ time_t atime;
+ long ansec;
+ time_t ctime;
+ long cnsec;
+ time_t arctime;
+ long arcnsec;
+
+ /* Fields to help with tracking decompression of files. */
+ int64_t bytes_unconsumed;
+ int64_t bytes_remaining;
+ int64_t bytes_uncopied;
+ int64_t offset;
+ int64_t offset_outgoing;
+ char valid;
+ unsigned int unp_offset;
+ unsigned int unp_buffer_size;
+ unsigned char *unp_buffer;
+ unsigned int dictionary_size;
+ char start_new_block;
+ char entry_eof;
+ unsigned long crc_calculated;
+ int found_first_header;
+
+ /* LZSS members */
+ struct huffman_code maincode;
+ struct huffman_code offsetcode;
+ struct huffman_code lowoffsetcode;
+ struct huffman_code lengthcode;
+ unsigned char lengthtable[HUFFMAN_TABLE_SIZE];
+ struct lzss lzss;
+ char output_last_match;
+ unsigned int lastlength;
+ unsigned int lastoffset;
+ unsigned int oldoffset[4];
+ unsigned int lastlowoffset;
+ unsigned int numlowoffsetrepeats;
+ int64_t filterstart;
+ char start_new_table;
+
+ /* PPMd Variant H members */
+ char ppmd_valid;
+ char ppmd_eod;
+ char is_ppmd_block;
+ int ppmd_escape;
+ CPpmd7 ppmd7_context;
+ CPpmd7z_RangeDec range_dec;
+ IByteIn bytein;
+
+ /*
+ * String conversion object.
+ */
+ int init_default_conversion;
+ struct archive_string_conv *sconv_default;
+ struct archive_string_conv *opt_sconv;
+ struct archive_string_conv *sconv_utf8;
+ struct archive_string_conv *sconv_utf16be;
+
+ /*
+ * Bit stream reader.
+ */
+ struct rar_br {
+#define CACHE_TYPE uint64_t
+#define CACHE_BITS (8 * sizeof(CACHE_TYPE))
+ /* Cache buffer. */
+ CACHE_TYPE cache_buffer;
+ /* Indicates how many bits avail in cache_buffer. */
+ int cache_avail;
+ ssize_t avail_in;
+ const unsigned char *next_in;
+ } br;
+};
+
+static int archive_read_format_rar_bid(struct archive_read *, int);
+static int archive_read_format_rar_options(struct archive_read *,
+ const char *, const char *);
+static int archive_read_format_rar_read_header(struct archive_read *,
+ struct archive_entry *);
+static int archive_read_format_rar_read_data(struct archive_read *,
+ const void **, size_t *, int64_t *);
+static int archive_read_format_rar_read_data_skip(struct archive_read *a);
+static int archive_read_format_rar_cleanup(struct archive_read *);
+
+/* Support functions */
+static int read_header(struct archive_read *, struct archive_entry *, char);
+static time_t get_time(int time);
+static int read_exttime(const char *, struct rar *, const char *);
+static int read_symlink_stored(struct archive_read *, struct archive_entry *,
+ struct archive_string_conv *);
+static int read_data_stored(struct archive_read *, const void **, size_t *,
+ int64_t *);
+static int read_data_compressed(struct archive_read *, const void **, size_t *,
+ int64_t *);
+static int rar_br_preparation(struct archive_read *, struct rar_br *);
+static int parse_codes(struct archive_read *);
+static void free_codes(struct archive_read *);
+static int read_next_symbol(struct archive_read *, struct huffman_code *);
+static int create_code(struct archive_read *, struct huffman_code *,
+ unsigned char *, int, char);
+static int add_value(struct archive_read *, struct huffman_code *, int, int,
+ int);
+static int new_node(struct huffman_code *);
+static int make_table(struct archive_read *, struct huffman_code *);
+static int make_table_recurse(struct archive_read *, struct huffman_code *, int,
+ struct huffman_table_entry *, int, int);
+static int64_t expand(struct archive_read *, int64_t);
+static int copy_from_lzss_window(struct archive_read *, const void **,
+ int64_t, int);
+
+/*
+ * Bit stream reader.
+ */
+/* Check that the cache buffer has enough bits. */
+#define rar_br_has(br, n) ((br)->cache_avail >= n)
+/* Get compressed data by bit. */
+#define rar_br_bits(br, n) \
+ (((uint32_t)((br)->cache_buffer >> \
+ ((br)->cache_avail - (n)))) & cache_masks[n])
+#define rar_br_bits_forced(br, n) \
+ (((uint32_t)((br)->cache_buffer << \
+ ((n) - (br)->cache_avail))) & cache_masks[n])
+/* Read ahead to make sure the cache buffer has enough compressed data we
+ * will use.
+ * True : completed, there is enough data in the cache buffer.
+ * False : there is no data in the stream. */
+#define rar_br_read_ahead(a, br, n) \
+ ((rar_br_has(br, (n)) || rar_br_fillup(a, br)) || rar_br_has(br, (n)))
+/* Notify how many bits we consumed. */
+#define rar_br_consume(br, n) ((br)->cache_avail -= (n))
+#define rar_br_consume_unalined_bits(br) ((br)->cache_avail &= ~7)
+
+static const uint32_t cache_masks[] = {
+ 0x00000000, 0x00000001, 0x00000003, 0x00000007,
+ 0x0000000F, 0x0000001F, 0x0000003F, 0x0000007F,
+ 0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF,
+ 0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF,
+ 0x0000FFFF, 0x0001FFFF, 0x0003FFFF, 0x0007FFFF,
+ 0x000FFFFF, 0x001FFFFF, 0x003FFFFF, 0x007FFFFF,
+ 0x00FFFFFF, 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF,
+ 0x0FFFFFFF, 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
+};
+
+/*
+ * Shift away used bits in the cache data and fill it up with following bits.
+ * Call this when cache buffer does not have enough bits you need.
+ *
+ * Returns 1 if the cache buffer is full.
+ * Returns 0 if the cache buffer is not full; input buffer is empty.
+ */
+static int
+rar_br_fillup(struct archive_read *a, struct rar_br *br)
+{
+ struct rar *rar = (struct rar *)(a->format->data);
+ int n = CACHE_BITS - br->cache_avail;
+
+ for (;;) {
+ switch (n >> 3) {
+ case 8:
+ if (br->avail_in >= 8) {
+ br->cache_buffer =
+ ((uint64_t)br->next_in[0]) << 56 |
+ ((uint64_t)br->next_in[1]) << 48 |
+ ((uint64_t)br->next_in[2]) << 40 |
+ ((uint64_t)br->next_in[3]) << 32 |
+ ((uint32_t)br->next_in[4]) << 24 |
+ ((uint32_t)br->next_in[5]) << 16 |
+ ((uint32_t)br->next_in[6]) << 8 |
+ (uint32_t)br->next_in[7];
+ br->next_in += 8;
+ br->avail_in -= 8;
+ br->cache_avail += 8 * 8;
+ rar->bytes_unconsumed += 8;
+ rar->bytes_remaining -= 8;
+ return (1);
+ }
+ break;
+ case 7:
+ if (br->avail_in >= 7) {
+ br->cache_buffer =
+ (br->cache_buffer << 56) |
+ ((uint64_t)br->next_in[0]) << 48 |
+ ((uint64_t)br->next_in[1]) << 40 |
+ ((uint64_t)br->next_in[2]) << 32 |
+ ((uint32_t)br->next_in[3]) << 24 |
+ ((uint32_t)br->next_in[4]) << 16 |
+ ((uint32_t)br->next_in[5]) << 8 |
+ (uint32_t)br->next_in[6];
+ br->next_in += 7;
+ br->avail_in -= 7;
+ br->cache_avail += 7 * 8;
+ rar->bytes_unconsumed += 7;
+ rar->bytes_remaining -= 7;
+ return (1);
+ }
+ break;
+ case 6:
+ if (br->avail_in >= 6) {
+ br->cache_buffer =
+ (br->cache_buffer << 48) |
+ ((uint64_t)br->next_in[0]) << 40 |
+ ((uint64_t)br->next_in[1]) << 32 |
+ ((uint32_t)br->next_in[2]) << 24 |
+ ((uint32_t)br->next_in[3]) << 16 |
+ ((uint32_t)br->next_in[4]) << 8 |
+ (uint32_t)br->next_in[5];
+ br->next_in += 6;
+ br->avail_in -= 6;
+ br->cache_avail += 6 * 8;
+ rar->bytes_unconsumed += 6;
+ rar->bytes_remaining -= 6;
+ return (1);
+ }
+ break;
+ case 0:
+ /* We have enough compressed data in
+ * the cache buffer.*/
+ return (1);
+ default:
+ break;
+ }
+ if (br->avail_in <= 0) {
+
+ if (rar->bytes_unconsumed > 0) {
+ /* Consume as much as the decompressor
+ * actually used. */
+ __archive_read_consume(a, rar->bytes_unconsumed);
+ rar->bytes_unconsumed = 0;
+ }
+ br->next_in = __archive_read_ahead(a, 1, &(br->avail_in));
+ if (br->next_in == NULL)
+ return (0);
+ if (br->avail_in > rar->bytes_remaining)
+ br->avail_in = rar->bytes_remaining;
+ if (br->avail_in == 0)
+ return (0);
+ }
+ br->cache_buffer =
+ (br->cache_buffer << 8) | *br->next_in++;
+ br->avail_in--;
+ br->cache_avail += 8;
+ n -= 8;
+ rar->bytes_unconsumed++;
+ rar->bytes_remaining--;
+ }
+}
+
+static int
+rar_br_preparation(struct archive_read *a, struct rar_br *br)
+{
+ struct rar *rar = (struct rar *)(a->format->data);
+
+ if (rar->bytes_remaining > 0) {
+ br->next_in = __archive_read_ahead(a, 1, &(br->avail_in));
+ if (br->next_in == NULL) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated RAR file data");
+ return (ARCHIVE_FATAL);
+ }
+ if (br->avail_in > rar->bytes_remaining)
+ br->avail_in = rar->bytes_remaining;
+ if (br->cache_avail == 0)
+ (void)rar_br_fillup(a, br);
+ }
+ return (ARCHIVE_OK);
+}
+
+/* Find last bit set */
+static inline int
+rar_fls(unsigned int word)
+{
+ word |= (word >> 1);
+ word |= (word >> 2);
+ word |= (word >> 4);
+ word |= (word >> 8);
+ word |= (word >> 16);
+ return word - (word >> 1);
+}
+
+/* LZSS functions */
+static inline int64_t
+lzss_position(struct lzss *lzss)
+{
+ return lzss->position;
+}
+
+static inline int
+lzss_mask(struct lzss *lzss)
+{
+ return lzss->mask;
+}
+
+static inline int
+lzss_size(struct lzss *lzss)
+{
+ return lzss->mask + 1;
+}
+
+static inline int
+lzss_offset_for_position(struct lzss *lzss, int64_t pos)
+{
+ return pos & lzss->mask;
+}
+
+static inline unsigned char *
+lzss_pointer_for_position(struct lzss *lzss, int64_t pos)
+{
+ return &lzss->window[lzss_offset_for_position(lzss, pos)];
+}
+
+static inline int
+lzss_current_offset(struct lzss *lzss)
+{
+ return lzss_offset_for_position(lzss, lzss->position);
+}
+
+static inline uint8_t *
+lzss_current_pointer(struct lzss *lzss)
+{
+ return lzss_pointer_for_position(lzss, lzss->position);
+}
+
+static inline void
+lzss_emit_literal(struct rar *rar, uint8_t literal)
+{
+ *lzss_current_pointer(&rar->lzss) = literal;
+ rar->lzss.position++;
+}
+
+static inline void
+lzss_emit_match(struct rar *rar, int offset, int length)
+{
+ int dstoffs = lzss_current_offset(&rar->lzss);
+ int srcoffs = (dstoffs - offset) & lzss_mask(&rar->lzss);
+ int l, li, remaining;
+ unsigned char *d, *s;
+
+ remaining = length;
+ while (remaining > 0) {
+ l = remaining;
+ if (dstoffs > srcoffs) {
+ if (l > lzss_size(&rar->lzss) - dstoffs)
+ l = lzss_size(&rar->lzss) - dstoffs;
+ } else {
+ if (l > lzss_size(&rar->lzss) - srcoffs)
+ l = lzss_size(&rar->lzss) - srcoffs;
+ }
+ d = &(rar->lzss.window[dstoffs]);
+ s = &(rar->lzss.window[srcoffs]);
+ if ((dstoffs + l < srcoffs) || (srcoffs + l < dstoffs))
+ memcpy(d, s, l);
+ else {
+ for (li = 0; li < l; li++)
+ d[li] = s[li];
+ }
+ remaining -= l;
+ dstoffs = (dstoffs + l) & lzss_mask(&(rar->lzss));
+ srcoffs = (srcoffs + l) & lzss_mask(&(rar->lzss));
+ }
+ rar->lzss.position += length;
+}
+
+static void *
+ppmd_alloc(void *p, size_t size)
+{
+ (void)p;
+ return malloc(size);
+}
+static void
+ppmd_free(void *p, void *address)
+{
+ (void)p;
+ free(address);
+}
+static ISzAlloc g_szalloc = { ppmd_alloc, ppmd_free };
+
+static Byte
+ppmd_read(void *p)
+{
+ struct archive_read *a = ((IByteIn*)p)->a;
+ struct rar *rar = (struct rar *)(a->format->data);
+ struct rar_br *br = &(rar->br);
+ Byte b;
+ if (!rar_br_read_ahead(a, br, 8))
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated RAR file data");
+ rar->valid = 0;
+ return 0;
+ }
+ b = rar_br_bits(br, 8);
+ rar_br_consume(br, 8);
+ return b;
+}
+
+int
+archive_read_support_format_rar(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct rar *rar;
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
+ "archive_read_support_format_rar");
+
+ rar = (struct rar *)malloc(sizeof(*rar));
+ if (rar == NULL)
+ {
+ archive_set_error(&a->archive, ENOMEM, "Can't allocate rar data");
+ return (ARCHIVE_FATAL);
+ }
+ memset(rar, 0, sizeof(*rar));
+
+ r = __archive_read_register_format(a,
+ rar,
+ "rar",
+ archive_read_format_rar_bid,
+ archive_read_format_rar_options,
+ archive_read_format_rar_read_header,
+ archive_read_format_rar_read_data,
+ archive_read_format_rar_read_data_skip,
+ archive_read_format_rar_cleanup);
+
+ if (r != ARCHIVE_OK)
+ free(rar);
+ return (r);
+}
+
+static int
+archive_read_format_rar_bid(struct archive_read *a, int best_bid)
+{
+ const char *p;
+
+ /* If there's already a bid > 30, we'll never win. */
+ if (best_bid > 30)
+ return (-1);
+
+ if ((p = __archive_read_ahead(a, 7, NULL)) == NULL)
+ return (-1);
+
+ if (memcmp(p, RAR_SIGNATURE, 7) == 0)
+ return (30);
+
+ if ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0) {
+ /* This is a PE file */
+ ssize_t offset = 0x10000;
+ ssize_t window = 4096;
+ ssize_t bytes_avail;
+ while (offset + window <= (1024 * 128)) {
+ const char *buff = __archive_read_ahead(a, offset + window, &bytes_avail);
+ if (buff == NULL) {
+ /* Remaining bytes are less than window. */
+ window >>= 1;
+ if (window < 0x40)
+ return (0);
+ continue;
+ }
+ p = buff + offset;
+ while (p + 7 < buff + bytes_avail) {
+ if (memcmp(p, RAR_SIGNATURE, 7) == 0)
+ return (30);
+ p += 0x10;
+ }
+ offset = p - buff;
+ }
+ }
+ return (0);
+}
+
+static int
+skip_sfx(struct archive_read *a)
+{
+ const void *h;
+ const char *p, *q;
+ size_t skip, total;
+ ssize_t bytes, window;
+
+ total = 0;
+ window = 4096;
+ while (total + window <= (1024 * 128)) {
+ h = __archive_read_ahead(a, window, &bytes);
+ if (h == NULL) {
+ /* Remaining bytes are less than window. */
+ window >>= 1;
+ if (window < 0x40)
+ goto fatal;
+ continue;
+ }
+ if (bytes < 0x40)
+ goto fatal;
+ p = h;
+ q = p + bytes;
+
+ /*
+ * Scan ahead until we find something that looks
+ * like the RAR header.
+ */
+ while (p + 7 < q) {
+ if (memcmp(p, RAR_SIGNATURE, 7) == 0) {
+ skip = p - (const char *)h;
+ __archive_read_consume(a, skip);
+ return (ARCHIVE_OK);
+ }
+ p += 0x10;
+ }
+ skip = p - (const char *)h;
+ __archive_read_consume(a, skip);
+ total += skip;
+ }
+fatal:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Couldn't find out RAR header");
+ return (ARCHIVE_FATAL);
+}
+
+static int
+archive_read_format_rar_options(struct archive_read *a,
+ const char *key, const char *val)
+{
+ struct rar *rar;
+ int ret = ARCHIVE_FAILED;
+
+ rar = (struct rar *)(a->format->data);
+ if (strcmp(key, "hdrcharset") == 0) {
+ if (val == NULL || val[0] == 0)
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "rar: hdrcharset option needs a character-set name");
+ else {
+ rar->opt_sconv =
+ archive_string_conversion_from_charset(
+ &a->archive, val, 0);
+ if (rar->opt_sconv != NULL)
+ ret = ARCHIVE_OK;
+ else
+ ret = ARCHIVE_FATAL;
+ }
+ } else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "rar: unknown keyword ``%s''", key);
+
+ return (ret);
+}
+
+static int
+archive_read_format_rar_read_header(struct archive_read *a,
+ struct archive_entry *entry)
+{
+ const void *h;
+ const char *p;
+ struct rar *rar;
+ size_t skip;
+ char head_type;
+ int ret;
+ unsigned flags;
+
+ a->archive.archive_format = ARCHIVE_FORMAT_RAR;
+ if (a->archive.archive_format_name == NULL)
+ a->archive.archive_format_name = "RAR";
+
+ rar = (struct rar *)(a->format->data);
+
+ /* RAR files can be generated without EOF headers, so return ARCHIVE_EOF if
+ * this fails.
+ */
+ if ((h = __archive_read_ahead(a, 7, NULL)) == NULL)
+ return (ARCHIVE_EOF);
+
+ p = h;
+ if (rar->found_first_header == 0 &&
+ ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0)) {
+ /* This is an executable ? Must be self-extracting... */
+ ret = skip_sfx(a);
+ if (ret < ARCHIVE_WARN)
+ return (ret);
+ }
+ rar->found_first_header = 1;
+
+ while (1)
+ {
+ unsigned long crc32_val;
+
+ if ((h = __archive_read_ahead(a, 7, NULL)) == NULL)
+ return (ARCHIVE_FATAL);
+ p = h;
+
+ head_type = p[2];
+ switch(head_type)
+ {
+ case MARK_HEAD:
+ if (memcmp(p, RAR_SIGNATURE, 7) != 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid marker header");
+ return (ARCHIVE_FATAL);
+ }
+ __archive_read_consume(a, 7);
+ break;
+
+ case MAIN_HEAD:
+ rar->main_flags = archive_le16dec(p + 3);
+ skip = archive_le16dec(p + 5);
+ if (skip < 7 + sizeof(rar->reserved1) + sizeof(rar->reserved2)) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid header size");
+ return (ARCHIVE_FATAL);
+ }
+ if ((h = __archive_read_ahead(a, skip, NULL)) == NULL)
+ return (ARCHIVE_FATAL);
+ p = h;
+ memcpy(rar->reserved1, p + 7, sizeof(rar->reserved1));
+ memcpy(rar->reserved2, p + 7 + sizeof(rar->reserved1),
+ sizeof(rar->reserved2));
+ if (rar->main_flags & MHD_ENCRYPTVER) {
+ if (skip < 7 + sizeof(rar->reserved1) + sizeof(rar->reserved2)+1) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid header size");
+ return (ARCHIVE_FATAL);
+ }
+ rar->encryptver = *(p + 7 + sizeof(rar->reserved1) +
+ sizeof(rar->reserved2));
+ }
+
+ if (rar->main_flags & MHD_VOLUME ||
+ rar->main_flags & MHD_FIRSTVOLUME)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "RAR volume support unavailable.");
+ return (ARCHIVE_FATAL);
+ }
+ if (rar->main_flags & MHD_PASSWORD)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "RAR encryption support unavailable.");
+ return (ARCHIVE_FATAL);
+ }
+
+ crc32_val = crc32(0, (const unsigned char *)p + 2, skip - 2);
+ if ((crc32_val & 0xffff) != archive_le16dec(p)) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Header CRC error");
+ return (ARCHIVE_FATAL);
+ }
+ __archive_read_consume(a, skip);
+ break;
+
+ case FILE_HEAD:
+ return read_header(a, entry, head_type);
+
+ case COMM_HEAD:
+ case AV_HEAD:
+ case SUB_HEAD:
+ case PROTECT_HEAD:
+ case SIGN_HEAD:
+ flags = archive_le16dec(p + 3);
+ skip = archive_le16dec(p + 5);
+ if (skip < 7) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid header size");
+ return (ARCHIVE_FATAL);
+ }
+ if (skip > 7) {
+ if ((h = __archive_read_ahead(a, skip, NULL)) == NULL)
+ return (ARCHIVE_FATAL);
+ p = h;
+ }
+ if (flags & HD_ADD_SIZE_PRESENT)
+ {
+ if (skip < 7 + 4) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid header size");
+ return (ARCHIVE_FATAL);
+ }
+ skip += archive_le32dec(p + 7);
+ if ((h = __archive_read_ahead(a, skip, NULL)) == NULL)
+ return (ARCHIVE_FATAL);
+ p = h;
+ }
+
+ crc32_val = crc32(0, (const unsigned char *)p + 2, skip - 2);
+ if ((crc32_val & 0xffff) != archive_le16dec(p)) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Header CRC error");
+ return (ARCHIVE_FATAL);
+ }
+ __archive_read_consume(a, skip);
+ break;
+
+ case NEWSUB_HEAD:
+ if ((ret = read_header(a, entry, head_type)) < ARCHIVE_WARN)
+ return ret;
+ break;
+
+ case ENDARC_HEAD:
+ return (ARCHIVE_EOF);
+
+ default:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Bad RAR file");
+ return (ARCHIVE_FATAL);
+ }
+ }
+}
+
+static int
+archive_read_format_rar_read_data(struct archive_read *a, const void **buff,
+ size_t *size, int64_t *offset)
+{
+ struct rar *rar = (struct rar *)(a->format->data);
+ int ret;
+
+ if (rar->bytes_unconsumed > 0) {
+ /* Consume as much as the decompressor actually used. */
+ __archive_read_consume(a, rar->bytes_unconsumed);
+ rar->bytes_unconsumed = 0;
+ }
+
+ if (rar->entry_eof) {
+ *buff = NULL;
+ *size = 0;
+ *offset = rar->offset;
+ return (ARCHIVE_EOF);
+ }
+
+ switch (rar->compression_method)
+ {
+ case COMPRESS_METHOD_STORE:
+ ret = read_data_stored(a, buff, size, offset);
+ break;
+
+ case COMPRESS_METHOD_FASTEST:
+ case COMPRESS_METHOD_FAST:
+ case COMPRESS_METHOD_NORMAL:
+ case COMPRESS_METHOD_GOOD:
+ case COMPRESS_METHOD_BEST:
+ ret = read_data_compressed(a, buff, size, offset);
+ if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN)
+ __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
+ break;
+
+ default:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Unsupported compression method for RAR file.");
+ ret = ARCHIVE_FATAL;
+ break;
+ }
+ return (ret);
+}
+
+static int
+archive_read_format_rar_read_data_skip(struct archive_read *a)
+{
+ struct rar *rar;
+ int64_t bytes_skipped;
+
+ rar = (struct rar *)(a->format->data);
+
+ if (rar->bytes_unconsumed > 0) {
+ /* Consume as much as the decompressor actually used. */
+ __archive_read_consume(a, rar->bytes_unconsumed);
+ rar->bytes_unconsumed = 0;
+ }
+
+ if (rar->bytes_remaining > 0) {
+ bytes_skipped = __archive_read_consume(a, rar->bytes_remaining);
+ if (bytes_skipped < 0)
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_read_format_rar_cleanup(struct archive_read *a)
+{
+ struct rar *rar;
+
+ rar = (struct rar *)(a->format->data);
+ free_codes(a);
+ free(rar->filename);
+ free(rar->unp_buffer);
+ free(rar->lzss.window);
+ __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
+ free(rar);
+ (a->format->data) = NULL;
+ return (ARCHIVE_OK);
+}
+
+static int
+read_header(struct archive_read *a, struct archive_entry *entry,
+ char head_type)
+{
+ const void *h;
+ const char *p, *endp;
+ struct rar *rar;
+ struct rar_header rar_header;
+ struct rar_file_header file_header;
+ int64_t header_size;
+ unsigned filename_size, end;
+ char *filename;
+ char *strp;
+ char packed_size[8];
+ char unp_size[8];
+ int time;
+ struct archive_string_conv *sconv, *fn_sconv;
+ unsigned long crc32_val;
+ int ret = (ARCHIVE_OK), ret2;
+
+ rar = (struct rar *)(a->format->data);
+
+ /* Setup a string conversion object for non-rar-unicode filenames. */
+ sconv = rar->opt_sconv;
+ if (sconv == NULL) {
+ if (!rar->init_default_conversion) {
+ rar->sconv_default =
+ archive_string_default_conversion_for_read(
+ &(a->archive));
+ rar->init_default_conversion = 1;
+ }
+ sconv = rar->sconv_default;
+ }
+
+
+ if ((h = __archive_read_ahead(a, 7, NULL)) == NULL)
+ return (ARCHIVE_FATAL);
+ p = h;
+ memcpy(&rar_header, p, sizeof(rar_header));
+ rar->file_flags = archive_le16dec(rar_header.flags);
+ header_size = archive_le16dec(rar_header.size);
+ if (header_size < sizeof(file_header) + 7) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid header size");
+ return (ARCHIVE_FATAL);
+ }
+ crc32_val = crc32(0, (const unsigned char *)p + 2, 7 - 2);
+ __archive_read_consume(a, 7);
+
+ if (!(rar->file_flags & FHD_SOLID))
+ {
+ rar->compression_method = 0;
+ rar->packed_size = 0;
+ rar->unp_size = 0;
+ rar->mtime = 0;
+ rar->ctime = 0;
+ rar->atime = 0;
+ rar->arctime = 0;
+ rar->mode = 0;
+ memset(&rar->salt, 0, sizeof(rar->salt));
+ rar->atime = 0;
+ rar->ansec = 0;
+ rar->ctime = 0;
+ rar->cnsec = 0;
+ rar->mtime = 0;
+ rar->mnsec = 0;
+ rar->arctime = 0;
+ rar->arcnsec = 0;
+ }
+ else
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "RAR solid archive support unavailable.");
+ return (ARCHIVE_FATAL);
+ }
+
+ if ((h = __archive_read_ahead(a, header_size - 7, NULL)) == NULL)
+ return (ARCHIVE_FATAL);
+
+ /* File Header CRC check. */
+ crc32_val = crc32(crc32_val, h, header_size - 7);
+ if ((crc32_val & 0xffff) != archive_le16dec(rar_header.crc)) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Header CRC error");
+ return (ARCHIVE_FATAL);
+ }
+ /* If no CRC error, Go on parsing File Header. */
+ p = h;
+ endp = p + header_size - 7;
+ memcpy(&file_header, p, sizeof(file_header));
+ p += sizeof(file_header);
+
+ rar->compression_method = file_header.method;
+
+ time = archive_le32dec(file_header.file_time);
+ rar->mtime = get_time(time);
+
+ rar->file_crc = archive_le32dec(file_header.file_crc);
+
+ if (rar->file_flags & FHD_PASSWORD)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "RAR encryption support unavailable.");
+ return (ARCHIVE_FATAL);
+ }
+
+ if (rar->file_flags & FHD_LARGE)
+ {
+ memcpy(packed_size, file_header.pack_size, 4);
+ memcpy(packed_size + 4, p, 4); /* High pack size */
+ p += 4;
+ memcpy(unp_size, file_header.unp_size, 4);
+ memcpy(unp_size + 4, p, 4); /* High unpack size */
+ p += 4;
+ rar->packed_size = archive_le64dec(&packed_size);
+ rar->unp_size = archive_le64dec(&unp_size);
+ }
+ else
+ {
+ rar->packed_size = archive_le32dec(file_header.pack_size);
+ rar->unp_size = archive_le32dec(file_header.unp_size);
+ }
+
+ /* TODO: Need to use CRC check for these kind of cases.
+ * For now, check if sizes are not < 0.
+ */
+ if (rar->packed_size < 0 || rar->unp_size < 0)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid sizes specified.");
+ return (ARCHIVE_FATAL);
+ }
+
+ /* TODO: RARv3 subblocks contain comments. For now the complete block is
+ * consumed at the end.
+ */
+ if (head_type == NEWSUB_HEAD) {
+ size_t distance = p - (const char *)h;
+ header_size += rar->packed_size;
+ /* Make sure we have the extended data. */
+ if ((h = __archive_read_ahead(a, header_size - 7, NULL)) == NULL)
+ return (ARCHIVE_FATAL);
+ p = h;
+ endp = p + header_size - 7;
+ p += distance;
+ }
+
+ filename_size = archive_le16dec(file_header.name_size);
+ if (p + filename_size > endp) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid filename size");
+ return (ARCHIVE_FATAL);
+ }
+ if (rar->filename_allocated < filename_size+2) {
+ rar->filename = realloc(rar->filename, filename_size+2);
+ if (rar->filename == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Couldn't allocate memory.");
+ return (ARCHIVE_FATAL);
+ }
+ }
+ filename = rar->filename;
+ memcpy(filename, p, filename_size);
+ filename[filename_size] = '\0';
+ if (rar->file_flags & FHD_UNICODE)
+ {
+ if (filename_size != strlen(filename))
+ {
+ unsigned char highbyte, flagbits, flagbyte, length, offset;
+
+ end = filename_size;
+ filename_size = 0;
+ offset = strlen(filename) + 1;
+ highbyte = *(p + offset++);
+ flagbits = 0;
+ flagbyte = 0;
+ while (offset < end && filename_size < end)
+ {
+ if (!flagbits)
+ {
+ flagbyte = *(p + offset++);
+ flagbits = 8;
+ }
+
+ flagbits -= 2;
+ switch((flagbyte >> flagbits) & 3)
+ {
+ case 0:
+ filename[filename_size++] = '\0';
+ filename[filename_size++] = *(p + offset++);
+ break;
+ case 1:
+ filename[filename_size++] = highbyte;
+ filename[filename_size++] = *(p + offset++);
+ break;
+ case 2:
+ filename[filename_size++] = *(p + offset + 1);
+ filename[filename_size++] = *(p + offset);
+ offset += 2;
+ break;
+ case 3:
+ {
+ length = *(p + offset++);
+ while (length)
+ {
+ if (filename_size >= end)
+ break;
+ filename[filename_size++] = *(p + offset);
+ length--;
+ }
+ }
+ break;
+ }
+ }
+ if (filename_size >= end) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid filename");
+ return (ARCHIVE_FATAL);
+ }
+ filename[filename_size++] = '\0';
+ filename[filename_size++] = '\0';
+
+ /* Decoded unicode form is UTF-16BE, so we have to update a string
+ * conversion object for it. */
+ if (rar->sconv_utf16be == NULL) {
+ rar->sconv_utf16be = archive_string_conversion_from_charset(
+ &a->archive, "UTF-16BE", 1);
+ if (rar->sconv_utf16be == NULL)
+ return (ARCHIVE_FATAL);
+ }
+ fn_sconv = rar->sconv_utf16be;
+
+ strp = filename;
+ while (memcmp(strp, "\x00\x00", 2))
+ {
+ if (!memcmp(strp, "\x00\\", 2))
+ *(strp + 1) = '/';
+ strp += 2;
+ }
+ p += offset;
+ } else {
+ /*
+ * If FHD_UNICODE is set but no unicode data, this file name form
+ * is UTF-8, so we have to update a string conversion object for
+ * it accordingly.
+ */
+ if (rar->sconv_utf8 == NULL) {
+ rar->sconv_utf8 = archive_string_conversion_from_charset(
+ &a->archive, "UTF-8", 1);
+ if (rar->sconv_utf8 == NULL)
+ return (ARCHIVE_FATAL);
+ }
+ fn_sconv = rar->sconv_utf8;
+ while ((strp = strchr(filename, '\\')) != NULL)
+ *strp = '/';
+ p += filename_size;
+ }
+ }
+ else
+ {
+ fn_sconv = sconv;
+ while ((strp = strchr(filename, '\\')) != NULL)
+ *strp = '/';
+ p += filename_size;
+ }
+
+ if (rar->file_flags & FHD_SALT)
+ {
+ if (p + 8 > endp) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid header size");
+ return (ARCHIVE_FATAL);
+ }
+ memcpy(rar->salt, p, 8);
+ p += 8;
+ }
+
+ if (rar->file_flags & FHD_EXTTIME) {
+ if (read_exttime(p, rar, endp) < 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid header size");
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ __archive_read_consume(a, header_size - 7);
+
+ switch(file_header.host_os)
+ {
+ case OS_MSDOS:
+ case OS_OS2:
+ case OS_WIN32:
+ rar->mode = archive_le32dec(file_header.file_attr);
+ if (rar->mode & FILE_ATTRIBUTE_DIRECTORY)
+ rar->mode = AE_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
+ else
+ rar->mode = AE_IFREG;
+ rar->mode |= S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
+ break;
+
+ case OS_UNIX:
+ case OS_MAC_OS:
+ case OS_BEOS:
+ rar->mode = archive_le32dec(file_header.file_attr);
+ break;
+
+ default:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Unknown file attributes from RAR file's host OS");
+ return (ARCHIVE_FATAL);
+ }
+
+ rar->bytes_remaining = rar->packed_size;
+ rar->bytes_uncopied = rar->bytes_unconsumed = 0;
+ rar->lzss.position = rar->dictionary_size = rar->offset = 0;
+ rar->offset_outgoing = 0;
+ rar->br.cache_avail = 0;
+ rar->br.avail_in = 0;
+ rar->crc_calculated = 0;
+ rar->entry_eof = 0;
+ rar->valid = 1;
+ rar->is_ppmd_block = 0;
+ rar->start_new_table = 1;
+ free(rar->unp_buffer);
+ rar->unp_buffer = NULL;
+ rar->unp_offset = 0;
+ rar->unp_buffer_size = UNP_BUFFER_SIZE;
+ memset(rar->lengthtable, 0, sizeof(rar->lengthtable));
+ __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
+ rar->ppmd_valid = rar->ppmd_eod = 0;
+
+ /* Don't set any archive entries for non-file header types */
+ if (head_type == NEWSUB_HEAD)
+ return ret;
+
+ archive_entry_set_mtime(entry, rar->mtime, rar->mnsec);
+ archive_entry_set_ctime(entry, rar->ctime, rar->cnsec);
+ archive_entry_set_atime(entry, rar->atime, rar->ansec);
+ archive_entry_set_size(entry, rar->unp_size);
+ archive_entry_set_mode(entry, rar->mode);
+
+ if (archive_entry_copy_pathname_l(entry, filename, filename_size, fn_sconv))
+ {
+ if (errno == ENOMEM)
+ {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Pathname cannot be converted from %s to current locale.",
+ archive_string_conversion_charset_name(fn_sconv));
+ ret = (ARCHIVE_WARN);
+ }
+
+ if (((rar->mode) & AE_IFMT) == AE_IFLNK)
+ {
+ /* Make sure a symbolic-link file does not have its body. */
+ rar->bytes_remaining = 0;
+ archive_entry_set_size(entry, 0);
+
+ /* Read a symbolic-link name. */
+ if ((ret2 = read_symlink_stored(a, entry, sconv)) < (ARCHIVE_WARN))
+ return ret2;
+ if (ret > ret2)
+ ret = ret2;
+ }
+
+ if (rar->bytes_remaining == 0)
+ rar->entry_eof = 1;
+
+ return ret;
+}
+
+static time_t
+get_time(int time)
+{
+ struct tm tm;
+ tm.tm_sec = 2 * (time & 0x1f);
+ tm.tm_min = (time >> 5) & 0x3f;
+ tm.tm_hour = (time >> 11) & 0x1f;
+ tm.tm_mday = (time >> 16) & 0x1f;
+ tm.tm_mon = ((time >> 21) & 0x0f) - 1;
+ tm.tm_year = ((time >> 25) & 0x7f) + 80;
+ tm.tm_isdst = -1;
+ return mktime(&tm);
+}
+
+static int
+read_exttime(const char *p, struct rar *rar, const char *endp)
+{
+ unsigned rmode, flags, rem, j, count;
+ int time, i;
+ struct tm *tm;
+ time_t t;
+ long nsec;
+
+ if (p + 2 > endp)
+ return (-1);
+ flags = archive_le16dec(p);
+ p += 2;
+
+ for (i = 3; i >= 0; i--)
+ {
+ t = 0;
+ if (i == 3)
+ t = rar->mtime;
+ rmode = flags >> i * 4;
+ if (rmode & 8)
+ {
+ if (!t)
+ {
+ if (p + 4 > endp)
+ return (-1);
+ time = archive_le32dec(p);
+ t = get_time(time);
+ p += 4;
+ }
+ rem = 0;
+ count = rmode & 3;
+ if (p + count > endp)
+ return (-1);
+ for (j = 0; j < count; j++)
+ {
+ rem = ((*p) << 16) | (rem >> 8);
+ p++;
+ }
+ tm = localtime(&t);
+ nsec = tm->tm_sec + rem / NS_UNIT;
+ if (rmode & 4)
+ {
+ tm->tm_sec++;
+ t = mktime(tm);
+ }
+ if (i == 3)
+ {
+ rar->mtime = t;
+ rar->mnsec = nsec;
+ }
+ else if (i == 2)
+ {
+ rar->ctime = t;
+ rar->cnsec = nsec;
+ }
+ else if (i == 1)
+ {
+ rar->atime = t;
+ rar->ansec = nsec;
+ }
+ else
+ {
+ rar->arctime = t;
+ rar->arcnsec = nsec;
+ }
+ }
+ }
+ return (0);
+}
+
+static int
+read_symlink_stored(struct archive_read *a, struct archive_entry *entry,
+ struct archive_string_conv *sconv)
+{
+ const void *h;
+ const char *p;
+ struct rar *rar;
+ int ret = (ARCHIVE_OK);
+
+ rar = (struct rar *)(a->format->data);
+ if ((h = __archive_read_ahead(a, rar->packed_size, NULL)) == NULL)
+ return (ARCHIVE_FATAL);
+ p = h;
+
+ if (archive_entry_copy_symlink_l(entry, p, rar->packed_size, sconv))
+ {
+ if (errno == ENOMEM)
+ {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for link");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "link cannot be converted from %s to current locale.",
+ archive_string_conversion_charset_name(sconv));
+ ret = (ARCHIVE_WARN);
+ }
+ __archive_read_consume(a, rar->packed_size);
+ return ret;
+}
+
+static int
+read_data_stored(struct archive_read *a, const void **buff, size_t *size,
+ int64_t *offset)
+{
+ struct rar *rar;
+ ssize_t bytes_avail;
+
+ rar = (struct rar *)(a->format->data);
+ if (rar->bytes_remaining == 0)
+ {
+ *buff = NULL;
+ *size = 0;
+ *offset = rar->offset;
+ if (rar->file_crc != rar->crc_calculated) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "File CRC error");
+ return (ARCHIVE_FATAL);
+ }
+ rar->entry_eof = 1;
+ return (ARCHIVE_EOF);
+ }
+
+ *buff = __archive_read_ahead(a, 1, &bytes_avail);
+ if (bytes_avail <= 0)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated RAR file data");
+ return (ARCHIVE_FATAL);
+ }
+ if (bytes_avail > rar->bytes_remaining)
+ bytes_avail = rar->bytes_remaining;
+
+ *size = bytes_avail;
+ *offset = rar->offset;
+ rar->offset += bytes_avail;
+ rar->bytes_remaining -= bytes_avail;
+ rar->bytes_unconsumed = bytes_avail;
+ /* Calculate File CRC. */
+ rar->crc_calculated = crc32(rar->crc_calculated, *buff, bytes_avail);
+ return (ARCHIVE_OK);
+}
+
+static int
+read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
+ int64_t *offset)
+{
+ struct rar *rar;
+ int64_t start, end, actualend;
+ size_t bs;
+ int ret = (ARCHIVE_OK), sym, code, lzss_offset, length, i;
+
+ rar = (struct rar *)(a->format->data);
+
+ do {
+ if (!rar->valid)
+ return (ARCHIVE_FATAL);
+ if (rar->ppmd_eod ||
+ (rar->dictionary_size && rar->offset >= rar->unp_size))
+ {
+ if (rar->unp_offset > 0) {
+ /*
+ * We have unprocessed extracted data. write it out.
+ */
+ *buff = rar->unp_buffer;
+ *size = rar->unp_offset;
+ *offset = rar->offset_outgoing;
+ rar->offset_outgoing += *size;
+ /* Calculate File CRC. */
+ rar->crc_calculated = crc32(rar->crc_calculated, *buff, *size);
+ rar->unp_offset = 0;
+ return (ARCHIVE_OK);
+ }
+ *buff = NULL;
+ *size = 0;
+ *offset = rar->offset;
+ if (rar->file_crc != rar->crc_calculated) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "File CRC error");
+ return (ARCHIVE_FATAL);
+ }
+ rar->entry_eof = 1;
+ return (ARCHIVE_EOF);
+ }
+
+ if (!rar->is_ppmd_block && rar->dictionary_size && rar->bytes_uncopied > 0)
+ {
+ if (rar->bytes_uncopied > (rar->unp_buffer_size - rar->unp_offset))
+ bs = rar->unp_buffer_size - rar->unp_offset;
+ else
+ bs = rar->bytes_uncopied;
+ ret = copy_from_lzss_window(a, buff, rar->offset, bs);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ rar->offset += bs;
+ rar->bytes_uncopied -= bs;
+ if (*buff != NULL) {
+ rar->unp_offset = 0;
+ *size = rar->unp_buffer_size;
+ *offset = rar->offset_outgoing;
+ rar->offset_outgoing += *size;
+ /* Calculate File CRC. */
+ rar->crc_calculated = crc32(rar->crc_calculated, *buff, *size);
+ return (ret);
+ }
+ continue;
+ }
+
+ if (!rar->br.next_in &&
+ (ret = rar_br_preparation(a, &(rar->br))) < ARCHIVE_WARN)
+ return (ret);
+ if (rar->start_new_table && ((ret = parse_codes(a)) < (ARCHIVE_WARN)))
+ return (ret);
+
+ if (rar->is_ppmd_block)
+ {
+ if ((sym = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
+ &rar->ppmd7_context, &rar->range_dec.p)) < 0)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid symbol");
+ return (ARCHIVE_FATAL);
+ }
+ if(sym != rar->ppmd_escape)
+ {
+ lzss_emit_literal(rar, sym);
+ rar->bytes_uncopied++;
+ }
+ else
+ {
+ if ((code = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
+ &rar->ppmd7_context, &rar->range_dec.p)) < 0)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid symbol");
+ return (ARCHIVE_FATAL);
+ }
+
+ switch(code)
+ {
+ case 0:
+ rar->start_new_table = 1;
+ return read_data_compressed(a, buff, size, offset);
+
+ case 2:
+ rar->ppmd_eod = 1;/* End Of ppmd Data. */
+ continue;
+
+ case 3:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Parsing filters is unsupported.");
+ return (ARCHIVE_FAILED);
+
+ case 4:
+ lzss_offset = 0;
+ for (i = 2; i >= 0; i--)
+ {
+ if ((code = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
+ &rar->ppmd7_context, &rar->range_dec.p)) < 0)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid symbol");
+ return (ARCHIVE_FATAL);
+ }
+ lzss_offset |= code << (i * 8);
+ }
+ if ((length = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
+ &rar->ppmd7_context, &rar->range_dec.p)) < 0)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid symbol");
+ return (ARCHIVE_FATAL);
+ }
+ lzss_emit_match(rar, lzss_offset + 2, length + 32);
+ rar->bytes_uncopied += length + 32;
+ break;
+
+ case 5:
+ if ((length = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
+ &rar->ppmd7_context, &rar->range_dec.p)) < 0)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid symbol");
+ return (ARCHIVE_FATAL);
+ }
+ lzss_emit_match(rar, 1, length + 4);
+ rar->bytes_uncopied += length + 4;
+ break;
+
+ default:
+ lzss_emit_literal(rar, sym);
+ rar->bytes_uncopied++;
+ }
+ }
+ }
+ else
+ {
+ start = rar->offset;
+ end = start + rar->dictionary_size;
+ rar->filterstart = INT64_MAX;
+
+ if ((actualend = expand(a, end)) < 0)
+ return ((int)actualend);
+
+ rar->bytes_uncopied = actualend - start;
+ if (rar->bytes_uncopied == 0) {
+ /* Broken RAR files cause this case.
+ * NOTE: If this case were possible on a normal RAR file
+ * we would find out where it was actually bad and
+ * what we would do to solve it. */
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Internal error extracting RAR file");
+ return (ARCHIVE_FATAL);
+ }
+ }
+ if (rar->bytes_uncopied > (rar->unp_buffer_size - rar->unp_offset))
+ bs = rar->unp_buffer_size - rar->unp_offset;
+ else
+ bs = rar->bytes_uncopied;
+ ret = copy_from_lzss_window(a, buff, rar->offset, bs);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ rar->offset += bs;
+ rar->bytes_uncopied -= bs;
+ /*
+ * If *buff is NULL, it means unp_buffer is not full.
+ * So we have to continue extracting a RAR file.
+ */
+ } while (*buff == NULL);
+
+ rar->unp_offset = 0;
+ *size = rar->unp_buffer_size;
+ *offset = rar->offset_outgoing;
+ rar->offset_outgoing += *size;
+ /* Calculate File CRC. */
+ rar->crc_calculated = crc32(rar->crc_calculated, *buff, *size);
+ return ret;
+}
+
+static int
+parse_codes(struct archive_read *a)
+{
+ int i, j, val, n, r;
+ unsigned char bitlengths[MAX_SYMBOLS], zerocount, ppmd_flags;
+ unsigned int maxorder;
+ struct huffman_code precode;
+ struct rar *rar = (struct rar *)(a->format->data);
+ struct rar_br *br = &(rar->br);
+
+ free_codes(a);
+
+ /* Skip to the next byte */
+ rar_br_consume_unalined_bits(br);
+
+ /* PPMd block flag */
+ if (!rar_br_read_ahead(a, br, 1))
+ goto truncated_data;
+ if ((rar->is_ppmd_block = rar_br_bits(br, 1)) != 0)
+ {
+ rar_br_consume(br, 1);
+ if (!rar_br_read_ahead(a, br, 7))
+ goto truncated_data;
+ ppmd_flags = rar_br_bits(br, 7);
+ rar_br_consume(br, 7);
+
+ /* Memory is allocated in MB */
+ if (ppmd_flags & 0x20)
+ {
+ if (!rar_br_read_ahead(a, br, 8))
+ goto truncated_data;
+ rar->dictionary_size = (rar_br_bits(br, 8) + 1) << 20;
+ rar_br_consume(br, 8);
+ }
+
+ if (ppmd_flags & 0x40)
+ {
+ if (!rar_br_read_ahead(a, br, 8))
+ goto truncated_data;
+ rar->ppmd_escape = rar->ppmd7_context.InitEsc = rar_br_bits(br, 8);
+ rar_br_consume(br, 8);
+ }
+ else
+ rar->ppmd_escape = 2;
+
+ if (ppmd_flags & 0x20)
+ {
+ maxorder = (ppmd_flags & 0x1F) + 1;
+ if(maxorder > 16)
+ maxorder = 16 + (maxorder - 16) * 3;
+
+ if (maxorder == 1)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated RAR file data");
+ return (ARCHIVE_FATAL);
+ }
+
+ /* Make sure ppmd7_contest is freed before Ppmd7_Construct
+ * because reading a broken file cause this abnormal sequence. */
+ __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
+
+ rar->bytein.a = a;
+ rar->bytein.Read = &ppmd_read;
+ __archive_ppmd7_functions.PpmdRAR_RangeDec_CreateVTable(&rar->range_dec);
+ rar->range_dec.Stream = &rar->bytein;
+ __archive_ppmd7_functions.Ppmd7_Construct(&rar->ppmd7_context);
+
+ if (!__archive_ppmd7_functions.Ppmd7_Alloc(&rar->ppmd7_context,
+ rar->dictionary_size, &g_szalloc))
+ {
+ archive_set_error(&a->archive, ENOMEM,
+ "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+ if (!__archive_ppmd7_functions.PpmdRAR_RangeDec_Init(&rar->range_dec))
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Unable to initialize PPMd range decoder");
+ return (ARCHIVE_FATAL);
+ }
+ __archive_ppmd7_functions.Ppmd7_Init(&rar->ppmd7_context, maxorder);
+ rar->ppmd_valid = 1;
+ }
+ else
+ {
+ if (!rar->ppmd_valid) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid PPMd sequence");
+ return (ARCHIVE_FATAL);
+ }
+ if (!__archive_ppmd7_functions.PpmdRAR_RangeDec_Init(&rar->range_dec))
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Unable to initialize PPMd range decoder");
+ return (ARCHIVE_FATAL);
+ }
+ }
+ }
+ else
+ {
+ rar_br_consume(br, 1);
+
+ /* Keep existing table flag */
+ if (!rar_br_read_ahead(a, br, 1))
+ goto truncated_data;
+ if (!rar_br_bits(br, 1))
+ memset(rar->lengthtable, 0, sizeof(rar->lengthtable));
+ rar_br_consume(br, 1);
+
+ memset(&bitlengths, 0, sizeof(bitlengths));
+ for (i = 0; i < MAX_SYMBOLS;)
+ {
+ if (!rar_br_read_ahead(a, br, 4))
+ goto truncated_data;
+ bitlengths[i++] = rar_br_bits(br, 4);
+ rar_br_consume(br, 4);
+ if (bitlengths[i-1] == 0xF)
+ {
+ if (!rar_br_read_ahead(a, br, 4))
+ goto truncated_data;
+ zerocount = rar_br_bits(br, 4);
+ rar_br_consume(br, 4);
+ if (zerocount)
+ {
+ i--;
+ for (j = 0; j < zerocount + 2 && i < MAX_SYMBOLS; j++)
+ bitlengths[i++] = 0;
+ }
+ }
+ }
+
+ memset(&precode, 0, sizeof(precode));
+ r = create_code(a, &precode, bitlengths, MAX_SYMBOLS, MAX_SYMBOL_LENGTH);
+ if (r != ARCHIVE_OK) {
+ free(precode.tree);
+ free(precode.table);
+ return (r);
+ }
+
+ for (i = 0; i < HUFFMAN_TABLE_SIZE;)
+ {
+ if ((val = read_next_symbol(a, &precode)) < 0) {
+ free(precode.tree);
+ free(precode.table);
+ return (ARCHIVE_FATAL);
+ }
+ if (val < 16)
+ {
+ rar->lengthtable[i] = (rar->lengthtable[i] + val) & 0xF;
+ i++;
+ }
+ else if (val < 18)
+ {
+ if (i == 0)
+ {
+ free(precode.tree);
+ free(precode.table);
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Internal error extracting RAR file.");
+ return (ARCHIVE_FATAL);
+ }
+
+ if(val == 16) {
+ if (!rar_br_read_ahead(a, br, 3)) {
+ free(precode.tree);
+ free(precode.table);
+ goto truncated_data;
+ }
+ n = rar_br_bits(br, 3) + 3;
+ rar_br_consume(br, 3);
+ } else {
+ if (!rar_br_read_ahead(a, br, 7)) {
+ free(precode.tree);
+ free(precode.table);
+ goto truncated_data;
+ }
+ n = rar_br_bits(br, 7) + 11;
+ rar_br_consume(br, 7);
+ }
+
+ for (j = 0; j < n && i < HUFFMAN_TABLE_SIZE; j++)
+ {
+ rar->lengthtable[i] = rar->lengthtable[i-1];
+ i++;
+ }
+ }
+ else
+ {
+ if(val == 18) {
+ if (!rar_br_read_ahead(a, br, 3)) {
+ free(precode.tree);
+ free(precode.table);
+ goto truncated_data;
+ }
+ n = rar_br_bits(br, 3) + 3;
+ rar_br_consume(br, 3);
+ } else {
+ if (!rar_br_read_ahead(a, br, 7)) {
+ free(precode.tree);
+ free(precode.table);
+ goto truncated_data;
+ }
+ n = rar_br_bits(br, 7) + 11;
+ rar_br_consume(br, 7);
+ }
+
+ for(j = 0; j < n && i < HUFFMAN_TABLE_SIZE; j++)
+ rar->lengthtable[i++] = 0;
+ }
+ }
+ free(precode.tree);
+ free(precode.table);
+
+ r = create_code(a, &rar->maincode, &rar->lengthtable[0], MAINCODE_SIZE,
+ MAX_SYMBOL_LENGTH);
+ if (r != ARCHIVE_OK)
+ return (r);
+ r = create_code(a, &rar->offsetcode, &rar->lengthtable[MAINCODE_SIZE],
+ OFFSETCODE_SIZE, MAX_SYMBOL_LENGTH);
+ if (r != ARCHIVE_OK)
+ return (r);
+ r = create_code(a, &rar->lowoffsetcode,
+ &rar->lengthtable[MAINCODE_SIZE + OFFSETCODE_SIZE],
+ LOWOFFSETCODE_SIZE, MAX_SYMBOL_LENGTH);
+ if (r != ARCHIVE_OK)
+ return (r);
+ r = create_code(a, &rar->lengthcode,
+ &rar->lengthtable[MAINCODE_SIZE + OFFSETCODE_SIZE +
+ LOWOFFSETCODE_SIZE], LENGTHCODE_SIZE, MAX_SYMBOL_LENGTH);
+ if (r != ARCHIVE_OK)
+ return (r);
+ }
+
+ if (!rar->dictionary_size || !rar->lzss.window)
+ {
+ /* Seems as though dictionary sizes are not used. Even so, minimize
+ * memory usage as much as possible.
+ */
+ if (rar->unp_size >= DICTIONARY_MAX_SIZE)
+ rar->dictionary_size = DICTIONARY_MAX_SIZE;
+ else
+ rar->dictionary_size = rar_fls(rar->unp_size) << 1;
+ rar->lzss.window = (unsigned char *)realloc(rar->lzss.window,
+ rar->dictionary_size);
+ if (rar->lzss.window == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Unable to allocate memory for uncompressed data.");
+ return (ARCHIVE_FATAL);
+ }
+ memset(rar->lzss.window, 0, rar->dictionary_size);
+ rar->lzss.mask = rar->dictionary_size - 1;
+ }
+
+ rar->start_new_table = 0;
+ return (ARCHIVE_OK);
+truncated_data:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated RAR file data");
+ rar->valid = 0;
+ return (ARCHIVE_FATAL);
+}
+
+static void
+free_codes(struct archive_read *a)
+{
+ struct rar *rar = (struct rar *)(a->format->data);
+ free(rar->maincode.tree);
+ free(rar->offsetcode.tree);
+ free(rar->lowoffsetcode.tree);
+ free(rar->lengthcode.tree);
+ free(rar->maincode.table);
+ free(rar->offsetcode.table);
+ free(rar->lowoffsetcode.table);
+ free(rar->lengthcode.table);
+ memset(&rar->maincode, 0, sizeof(rar->maincode));
+ memset(&rar->offsetcode, 0, sizeof(rar->offsetcode));
+ memset(&rar->lowoffsetcode, 0, sizeof(rar->lowoffsetcode));
+ memset(&rar->lengthcode, 0, sizeof(rar->lengthcode));
+}
+
+
+static int
+read_next_symbol(struct archive_read *a, struct huffman_code *code)
+{
+ unsigned char bit;
+ unsigned int bits;
+ int length, value, node;
+ struct rar *rar;
+ struct rar_br *br;
+
+ if (!code->table)
+ {
+ if (make_table(a, code) != (ARCHIVE_OK))
+ return -1;
+ }
+
+ rar = (struct rar *)(a->format->data);
+ br = &(rar->br);
+
+ /* Look ahead (peek) at bits */
+ if (!rar_br_read_ahead(a, br, code->tablesize)) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated RAR file data");
+ rar->valid = 0;
+ return -1;
+ }
+ bits = rar_br_bits(br, code->tablesize);
+
+ length = code->table[bits].length;
+ value = code->table[bits].value;
+
+ if (length < 0)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid prefix code in bitstream");
+ return -1;
+ }
+
+ if (length <= code->tablesize)
+ {
+ /* Skip length bits */
+ rar_br_consume(br, length);
+ return value;
+ }
+
+ /* Skip tablesize bits */
+ rar_br_consume(br, code->tablesize);
+
+ node = value;
+ while (!(code->tree[node].branches[0] ==
+ code->tree[node].branches[1]))
+ {
+ if (!rar_br_read_ahead(a, br, 1)) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated RAR file data");
+ rar->valid = 0;
+ return -1;
+ }
+ bit = rar_br_bits(br, 1);
+ rar_br_consume(br, 1);
+
+ if (code->tree[node].branches[bit] < 0)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid prefix code in bitstream");
+ return -1;
+ }
+ node = code->tree[node].branches[bit];
+ }
+
+ return code->tree[node].branches[0];
+}
+
+static int
+create_code(struct archive_read *a, struct huffman_code *code,
+ unsigned char *lengths, int numsymbols, char maxlength)
+{
+ int i, j, codebits = 0, symbolsleft = numsymbols;
+
+ if (new_node(code) < 0) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Unable to allocate memory for node data.");
+ return (ARCHIVE_FATAL);
+ }
+ code->numentries = 1;
+ code->minlength = INT_MAX;
+ code->maxlength = INT_MIN;
+ codebits = 0;
+ for(i = 1; i <= maxlength; i++)
+ {
+ for(j = 0; j < numsymbols; j++)
+ {
+ if (lengths[j] != i) continue;
+ if (add_value(a, code, j, codebits, i) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ codebits++;
+ if (--symbolsleft <= 0) { break; break; }
+ }
+ codebits <<= 1;
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+add_value(struct archive_read *a, struct huffman_code *code, int value,
+ int codebits, int length)
+{
+ int repeatpos, lastnode, bitpos, bit, repeatnode, nextnode;
+
+ free(code->table);
+ code->table = NULL;
+
+ if(length > code->maxlength)
+ code->maxlength = length;
+ if(length < code->minlength)
+ code->minlength = length;
+
+ repeatpos = -1;
+ if (repeatpos == 0 || (repeatpos >= 0
+ && (((codebits >> (repeatpos - 1)) & 3) == 0
+ || ((codebits >> (repeatpos - 1)) & 3) == 3)))
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid repeat position");
+ return (ARCHIVE_FATAL);
+ }
+
+ lastnode = 0;
+ for (bitpos = length - 1; bitpos >= 0; bitpos--)
+ {
+ bit = (codebits >> bitpos) & 1;
+
+ /* Leaf node check */
+ if (code->tree[lastnode].branches[0] ==
+ code->tree[lastnode].branches[1])
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Prefix found");
+ return (ARCHIVE_FATAL);
+ }
+
+ if (bitpos == repeatpos)
+ {
+ /* Open branch check */
+ if (!(code->tree[lastnode].branches[bit] < 0))
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid repeating code");
+ return (ARCHIVE_FATAL);
+ }
+
+ if ((repeatnode = new_node(code)) < 0) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Unable to allocate memory for node data.");
+ return (ARCHIVE_FATAL);
+ }
+ if ((nextnode = new_node(code)) < 0) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Unable to allocate memory for node data.");
+ return (ARCHIVE_FATAL);
+ }
+
+ /* Set branches */
+ code->tree[lastnode].branches[bit] = repeatnode;
+ code->tree[repeatnode].branches[bit] = repeatnode;
+ code->tree[repeatnode].branches[bit^1] = nextnode;
+ lastnode = nextnode;
+
+ bitpos++; /* terminating bit already handled, skip it */
+ }
+ else
+ {
+ /* Open branch check */
+ if (code->tree[lastnode].branches[bit] < 0)
+ {
+ if (new_node(code) < 0) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Unable to allocate memory for node data.");
+ return (ARCHIVE_FATAL);
+ }
+ code->tree[lastnode].branches[bit] = code->numentries++;
+ }
+
+ /* set to branch */
+ lastnode = code->tree[lastnode].branches[bit];
+ }
+ }
+
+ if (!(code->tree[lastnode].branches[0] == -1
+ && code->tree[lastnode].branches[1] == -2))
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Prefix found");
+ return (ARCHIVE_FATAL);
+ }
+
+ /* Set leaf value */
+ code->tree[lastnode].branches[0] = value;
+ code->tree[lastnode].branches[1] = value;
+
+ return (ARCHIVE_OK);
+}
+
+static int
+new_node(struct huffman_code *code)
+{
+ code->tree = (struct huffman_tree_node *)realloc(code->tree,
+ (code->numentries + 1) * sizeof(*code->tree));
+ if (code->tree == NULL)
+ return (-1);
+ code->tree[code->numentries].branches[0] = -1;
+ code->tree[code->numentries].branches[1] = -2;
+ return 1;
+}
+
+static int
+make_table(struct archive_read *a, struct huffman_code *code)
+{
+ if (code->maxlength < code->minlength || code->maxlength > 10)
+ code->tablesize = 10;
+ else
+ code->tablesize = code->maxlength;
+
+ code->table =
+ (struct huffman_table_entry *)malloc(sizeof(*code->table)
+ * (1 << code->tablesize));
+
+ return make_table_recurse(a, code, 0, code->table, 0, code->tablesize);
+}
+
+static int
+make_table_recurse(struct archive_read *a, struct huffman_code *code, int node,
+ struct huffman_table_entry *table, int depth,
+ int maxdepth)
+{
+ int currtablesize, i, ret = (ARCHIVE_OK);
+
+ if (!code->tree)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Huffman tree was not created.");
+ return (ARCHIVE_FATAL);
+ }
+ if (node < 0 || node >= code->numentries)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid location to Huffman tree specified.");
+ return (ARCHIVE_FATAL);
+ }
+
+ currtablesize = 1 << (maxdepth - depth);
+
+ if (code->tree[node].branches[0] ==
+ code->tree[node].branches[1])
+ {
+ for(i = 0; i < currtablesize; i++)
+ {
+ table[i].length = depth;
+ table[i].value = code->tree[node].branches[0];
+ }
+ }
+ else if (node < 0)
+ {
+ for(i = 0; i < currtablesize; i++)
+ table[i].length = -1;
+ }
+ else
+ {
+ if(depth == maxdepth)
+ {
+ table[0].length = maxdepth + 1;
+ table[0].value = node;
+ }
+ else
+ {
+ ret |= make_table_recurse(a, code, code->tree[node].branches[0], table,
+ depth + 1, maxdepth);
+ ret |= make_table_recurse(a, code, code->tree[node].branches[1],
+ table + currtablesize / 2, depth + 1, maxdepth);
+ }
+ }
+ return ret;
+}
+
+static int64_t
+expand(struct archive_read *a, int64_t end)
+{
+ static const unsigned char lengthbases[] =
+ { 0, 1, 2, 3, 4, 5, 6,
+ 7, 8, 10, 12, 14, 16, 20,
+ 24, 28, 32, 40, 48, 56, 64,
+ 80, 96, 112, 128, 160, 192, 224 };
+ static const unsigned char lengthbits[] =
+ { 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 1, 1, 1, 2, 2,
+ 2, 2, 3, 3, 3, 3, 4,
+ 4, 4, 4, 5, 5, 5, 5 };
+ static const unsigned int offsetbases[] =
+ { 0, 1, 2, 3, 4, 6,
+ 8, 12, 16, 24, 32, 48,
+ 64, 96, 128, 192, 256, 384,
+ 512, 768, 1024, 1536, 2048, 3072,
+ 4096, 6144, 8192, 12288, 16384, 24576,
+ 32768, 49152, 65536, 98304, 131072, 196608,
+ 262144, 327680, 393216, 458752, 524288, 589824,
+ 655360, 720896, 786432, 851968, 917504, 983040,
+ 1048576, 1310720, 1572864, 1835008, 2097152, 2359296,
+ 2621440, 2883584, 3145728, 3407872, 3670016, 3932160 };
+ static const unsigned char offsetbits[] =
+ { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4,
+ 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10,
+ 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18 };
+ static const unsigned char shortbases[] =
+ { 0, 4, 8, 16, 32, 64, 128, 192 };
+ static const unsigned char shortbits[] =
+ { 2, 2, 3, 4, 5, 6, 6, 6 };
+
+ int symbol, offs, len, offsindex, lensymbol, i, offssymbol, lowoffsetsymbol;
+ unsigned char newfile;
+ struct rar *rar = (struct rar *)(a->format->data);
+ struct rar_br *br = &(rar->br);
+
+ if (rar->filterstart < end)
+ end = rar->filterstart;
+
+ while (1)
+ {
+ if (rar->output_last_match &&
+ lzss_position(&rar->lzss) + rar->lastlength <= end)
+ {
+ lzss_emit_match(rar, rar->lastoffset, rar->lastlength);
+ rar->output_last_match = 0;
+ }
+
+ if(rar->is_ppmd_block || rar->output_last_match ||
+ lzss_position(&rar->lzss) >= end)
+ return lzss_position(&rar->lzss);
+
+ if ((symbol = read_next_symbol(a, &rar->maincode)) < 0)
+ return (ARCHIVE_FATAL);
+ rar->output_last_match = 0;
+
+ if (symbol < 256)
+ {
+ lzss_emit_literal(rar, symbol);
+ continue;
+ }
+ else if (symbol == 256)
+ {
+ if (!rar_br_read_ahead(a, br, 1))
+ goto truncated_data;
+ newfile = !rar_br_bits(br, 1);
+ rar_br_consume(br, 1);
+
+ if(newfile)
+ {
+ rar->start_new_block = 1;
+ if (!rar_br_read_ahead(a, br, 1))
+ goto truncated_data;
+ rar->start_new_table = rar_br_bits(br, 1);
+ rar_br_consume(br, 1);
+ return lzss_position(&rar->lzss);
+ }
+ else
+ {
+ if (parse_codes(a) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ continue;
+ }
+ }
+ else if(symbol==257)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Parsing filters is unsupported.");
+ return (ARCHIVE_FAILED);
+ }
+ else if(symbol==258)
+ {
+ if(rar->lastlength == 0)
+ continue;
+
+ offs = rar->lastoffset;
+ len = rar->lastlength;
+ }
+ else if (symbol <= 262)
+ {
+ offsindex = symbol - 259;
+ offs = rar->oldoffset[offsindex];
+
+ if ((lensymbol = read_next_symbol(a, &rar->lengthcode)) < 0)
+ goto bad_data;
+ if (lensymbol > sizeof(lengthbases)/sizeof(lengthbases[0]))
+ goto bad_data;
+ if (lensymbol > sizeof(lengthbits)/sizeof(lengthbits[0]))
+ goto bad_data;
+ len = lengthbases[lensymbol] + 2;
+ if (lengthbits[lensymbol] > 0) {
+ if (!rar_br_read_ahead(a, br, lengthbits[lensymbol]))
+ goto truncated_data;
+ len += rar_br_bits(br, lengthbits[lensymbol]);
+ rar_br_consume(br, lengthbits[lensymbol]);
+ }
+
+ for (i = offsindex; i > 0; i--)
+ rar->oldoffset[i] = rar->oldoffset[i-1];
+ rar->oldoffset[0] = offs;
+ }
+ else if(symbol<=270)
+ {
+ offs = shortbases[symbol-263] + 1;
+ if(shortbits[symbol-263] > 0) {
+ if (!rar_br_read_ahead(a, br, shortbits[symbol-263]))
+ goto truncated_data;
+ offs += rar_br_bits(br, shortbits[symbol-263]);
+ rar_br_consume(br, shortbits[symbol-263]);
+ }
+
+ len = 2;
+
+ for(i = 3; i > 0; i--)
+ rar->oldoffset[i] = rar->oldoffset[i-1];
+ rar->oldoffset[0] = offs;
+ }
+ else
+ {
+ if (symbol-271 > sizeof(lengthbases)/sizeof(lengthbases[0]))
+ goto bad_data;
+ if (symbol-271 > sizeof(lengthbits)/sizeof(lengthbits[0]))
+ goto bad_data;
+ len = lengthbases[symbol-271]+3;
+ if(lengthbits[symbol-271] > 0) {
+ if (!rar_br_read_ahead(a, br, lengthbits[symbol-271]))
+ goto truncated_data;
+ len += rar_br_bits(br, lengthbits[symbol-271]);
+ rar_br_consume(br, lengthbits[symbol-271]);
+ }
+
+ if ((offssymbol = read_next_symbol(a, &rar->offsetcode)) < 0)
+ goto bad_data;
+ if (offssymbol > sizeof(offsetbases)/sizeof(offsetbases[0]))
+ goto bad_data;
+ if (offssymbol > sizeof(offsetbits)/sizeof(offsetbits[0]))
+ goto bad_data;
+ offs = offsetbases[offssymbol]+1;
+ if(offsetbits[offssymbol] > 0)
+ {
+ if(offssymbol > 9)
+ {
+ if(offsetbits[offssymbol] > 4) {
+ if (!rar_br_read_ahead(a, br, offsetbits[offssymbol] - 4))
+ goto truncated_data;
+ offs += rar_br_bits(br, offsetbits[offssymbol] - 4) << 4;
+ rar_br_consume(br, offsetbits[offssymbol] - 4);
+ }
+
+ if(rar->numlowoffsetrepeats > 0)
+ {
+ rar->numlowoffsetrepeats--;
+ offs += rar->lastlowoffset;
+ }
+ else
+ {
+ if ((lowoffsetsymbol =
+ read_next_symbol(a, &rar->lowoffsetcode)) < 0)
+ return (ARCHIVE_FATAL);
+ if(lowoffsetsymbol == 16)
+ {
+ rar->numlowoffsetrepeats = 15;
+ offs += rar->lastlowoffset;
+ }
+ else
+ {
+ offs += lowoffsetsymbol;
+ rar->lastlowoffset = lowoffsetsymbol;
+ }
+ }
+ }
+ else {
+ if (!rar_br_read_ahead(a, br, offsetbits[offssymbol]))
+ goto truncated_data;
+ offs += rar_br_bits(br, offsetbits[offssymbol]);
+ rar_br_consume(br, offsetbits[offssymbol]);
+ }
+ }
+
+ if (offs >= 0x40000)
+ len++;
+ if (offs >= 0x2000)
+ len++;
+
+ for(i = 3; i > 0; i--)
+ rar->oldoffset[i] = rar->oldoffset[i-1];
+ rar->oldoffset[0] = offs;
+ }
+
+ rar->lastoffset = offs;
+ rar->lastlength = len;
+ rar->output_last_match = 1;
+ }
+truncated_data:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated RAR file data");
+ rar->valid = 0;
+ return (ARCHIVE_FATAL);
+bad_data:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Bad RAR file data");
+ return (ARCHIVE_FATAL);
+}
+
+static int
+copy_from_lzss_window(struct archive_read *a, const void **buffer,
+ int64_t startpos, int length)
+{
+ int windowoffs, firstpart;
+ struct rar *rar = (struct rar *)(a->format->data);
+
+ if (!rar->unp_buffer)
+ {
+ if ((rar->unp_buffer = malloc(rar->unp_buffer_size)) == NULL)
+ {
+ archive_set_error(&a->archive, ENOMEM,
+ "Unable to allocate memory for uncompressed data.");
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ windowoffs = lzss_offset_for_position(&rar->lzss, startpos);
+ if(windowoffs + length <= lzss_size(&rar->lzss))
+ memcpy(&rar->unp_buffer[rar->unp_offset], &rar->lzss.window[windowoffs],
+ length);
+ else
+ {
+ firstpart = lzss_size(&rar->lzss) - windowoffs;
+ if (firstpart < 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Bad RAR file data");
+ return (ARCHIVE_FATAL);
+ }
+ if (firstpart < length) {
+ memcpy(&rar->unp_buffer[rar->unp_offset],
+ &rar->lzss.window[windowoffs], firstpart);
+ memcpy(&rar->unp_buffer[rar->unp_offset + firstpart],
+ &rar->lzss.window[0], length - firstpart);
+ } else
+ memcpy(&rar->unp_buffer[rar->unp_offset],
+ &rar->lzss.window[windowoffs], length);
+ }
+ rar->unp_offset += length;
+ if (rar->unp_offset >= rar->unp_buffer_size)
+ *buffer = rar->unp_buffer;
+ else
+ *buffer = NULL;
+ return (ARCHIVE_OK);
+}
diff --git a/libarchive/archive_read_support_format_raw.c b/libarchive/archive_read_support_format_raw.c
index 7a8481bf221f..df2c00c96c32 100644
--- a/libarchive/archive_read_support_format_raw.c
+++ b/libarchive/archive_read_support_format_raw.c
@@ -40,13 +40,14 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_raw.c 201107
struct raw_info {
int64_t offset; /* Current position in the file. */
+ int64_t unconsumed;
int end_of_file;
};
-static int archive_read_format_raw_bid(struct archive_read *);
+static int archive_read_format_raw_bid(struct archive_read *, int);
static int archive_read_format_raw_cleanup(struct archive_read *);
static int archive_read_format_raw_read_data(struct archive_read *,
- const void **, size_t *, off_t *);
+ const void **, size_t *, int64_t *);
static int archive_read_format_raw_read_data_skip(struct archive_read *);
static int archive_read_format_raw_read_header(struct archive_read *,
struct archive_entry *);
@@ -58,6 +59,9 @@ archive_read_support_format_raw(struct archive *_a)
struct archive_read *a = (struct archive_read *)_a;
int r;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_raw");
+
info = (struct raw_info *)calloc(1, sizeof(*info));
if (info == NULL) {
archive_set_error(&a->archive, ENOMEM,
@@ -87,12 +91,11 @@ archive_read_support_format_raw(struct archive *_a)
* include "raw" as part of support_format_all().
*/
static int
-archive_read_format_raw_bid(struct archive_read *a)
+archive_read_format_raw_bid(struct archive_read *a, int best_bid)
{
-
- if (__archive_read_ahead(a, 1, NULL) == NULL)
- return (-1);
- return (1);
+ if (best_bid < 1 && __archive_read_ahead(a, 1, NULL) != NULL)
+ return (1);
+ return (-1);
}
/*
@@ -109,32 +112,40 @@ archive_read_format_raw_read_header(struct archive_read *a,
return (ARCHIVE_EOF);
a->archive.archive_format = ARCHIVE_FORMAT_RAW;
- a->archive.archive_format_name = "Raw data";
+ a->archive.archive_format_name = "raw";
archive_entry_set_pathname(entry, "data");
- /* XXX should we set mode to mimic a regular file? XXX */
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_perm(entry, 0644);
/* I'm deliberately leaving most fields unset here. */
return (ARCHIVE_OK);
}
static int
archive_read_format_raw_read_data(struct archive_read *a,
- const void **buff, size_t *size, off_t *offset)
+ const void **buff, size_t *size, int64_t *offset)
{
struct raw_info *info;
ssize_t avail;
info = (struct raw_info *)(a->format->data);
+
+ /* Consume the bytes we read last time. */
+ if (info->unconsumed) {
+ __archive_read_consume(a, info->unconsumed);
+ info->unconsumed = 0;
+ }
+
if (info->end_of_file)
return (ARCHIVE_EOF);
/* Get whatever bytes are immediately available. */
*buff = __archive_read_ahead(a, 1, &avail);
if (avail > 0) {
- /* Consume and return the bytes we just read */
- __archive_read_consume(a, avail);
+ /* Return the bytes we just read */
*size = avail;
*offset = info->offset;
info->offset += *size;
+ info->unconsumed = avail;
return (ARCHIVE_OK);
} else if (0 == avail) {
/* Record and return end-of-file. */
@@ -153,24 +164,15 @@ archive_read_format_raw_read_data(struct archive_read *a,
static int
archive_read_format_raw_read_data_skip(struct archive_read *a)
{
- struct raw_info *info;
- off_t bytes_skipped;
- int64_t request = 1024 * 1024 * 1024UL; /* Skip 1 GB at a time. */
+ struct raw_info *info = (struct raw_info *)(a->format->data);
- info = (struct raw_info *)(a->format->data);
- if (info->end_of_file)
- return (ARCHIVE_EOF);
- info->end_of_file = 1;
-
- for (;;) {
- bytes_skipped = __archive_read_skip_lenient(a, request);
- if (bytes_skipped < 0)
- return (ARCHIVE_FATAL);
- if (bytes_skipped < request)
- return (ARCHIVE_OK);
- /* We skipped all the bytes we asked for. There might
- * be more, so try again. */
+ /* Consume the bytes we read last time. */
+ if (info->unconsumed) {
+ __archive_read_consume(a, info->unconsumed);
+ info->unconsumed = 0;
}
+ info->end_of_file = 1;
+ return (ARCHIVE_OK);
}
static int
diff --git a/libarchive/archive_read_support_format_tar.c b/libarchive/archive_read_support_format_tar.c
index 8ddc779aae69..42412880f29d 100644
--- a/libarchive/archive_read_support_format_tar.c
+++ b/libarchive/archive_read_support_format_tar.c
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2011 Michihiro NAKAJIMA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,7 +31,6 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_tar.c 201161
#include <errno.h>
#endif
#include <stddef.h>
-/* #include <stdint.h> */ /* See archive_platform.h */
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
@@ -38,37 +38,10 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_tar.c 201161
#include <string.h>
#endif
-/* Obtain suitable wide-character manipulation functions. */
-#ifdef HAVE_WCHAR_H
-#include <wchar.h>
-#else
-/* Good enough for equality testing, which is all we need. */
-static int wcscmp(const wchar_t *s1, const wchar_t *s2)
-{
- int diff = *s1 - *s2;
- while (*s1 && diff == 0)
- diff = (int)*++s1 - (int)*++s2;
- return diff;
-}
-/* Good enough for equality testing, which is all we need. */
-static int wcsncmp(const wchar_t *s1, const wchar_t *s2, size_t n)
-{
- int diff = *s1 - *s2;
- while (*s1 && diff == 0 && n-- > 0)
- diff = (int)*++s1 - (int)*++s2;
- return diff;
-}
-static size_t wcslen(const wchar_t *s)
-{
- const wchar_t *p = s;
- while (*p)
- p++;
- return p - s;
-}
-#endif
-
#include "archive.h"
+#include "archive_acl_private.h" /* For ACL parsing routines. */
#include "archive_entry.h"
+#include "archive_entry_locale.h"
#include "archive_private.h"
#include "archive_read_private.h"
@@ -138,8 +111,9 @@ struct archive_entry_header_gnutar {
*/
struct sparse_block {
struct sparse_block *next;
- off_t offset;
- off_t remaining;
+ int64_t offset;
+ int64_t remaining;
+ int hole;
};
struct tar {
@@ -156,12 +130,11 @@ struct tar {
struct archive_string pax_global;
struct archive_string line;
int pax_hdrcharset_binary;
- wchar_t *pax_entry;
- size_t pax_entry_length;
int header_recursion_depth;
int64_t entry_bytes_remaining;
int64_t entry_offset;
int64_t entry_padding;
+ int64_t entry_bytes_unconsumed;
int64_t realsize;
struct sparse_block *sparse_list;
struct sparse_block *sparse_last;
@@ -170,70 +143,89 @@ struct tar {
int sparse_gnu_major;
int sparse_gnu_minor;
char sparse_gnu_pending;
+
+ struct archive_string localname;
+ struct archive_string_conv *opt_sconv;
+ struct archive_string_conv *sconv;
+ struct archive_string_conv *sconv_acl;
+ struct archive_string_conv *sconv_default;
+ int init_default_conversion;
+ int compat_2x;
};
-static ssize_t UTF8_mbrtowc(wchar_t *pwc, const char *s, size_t n);
-static int archive_block_is_null(const unsigned char *p);
+static int archive_block_is_null(const char *p);
static char *base64_decode(const char *, size_t, size_t *);
-static void gnu_add_sparse_entry(struct tar *,
- off_t offset, off_t remaining);
+static int gnu_add_sparse_entry(struct archive_read *, struct tar *,
+ int64_t offset, int64_t remaining);
+
static void gnu_clear_sparse_list(struct tar *);
static int gnu_sparse_old_read(struct archive_read *, struct tar *,
- const struct archive_entry_header_gnutar *header);
-static void gnu_sparse_old_parse(struct tar *,
+ const struct archive_entry_header_gnutar *header, size_t *);
+static int gnu_sparse_old_parse(struct archive_read *, struct tar *,
const struct gnu_sparse *sparse, int length);
-static int gnu_sparse_01_parse(struct tar *, const char *);
-static ssize_t gnu_sparse_10_read(struct archive_read *, struct tar *);
+static int gnu_sparse_01_parse(struct archive_read *, struct tar *,
+ const char *);
+static ssize_t gnu_sparse_10_read(struct archive_read *, struct tar *,
+ size_t *);
static int header_Solaris_ACL(struct archive_read *, struct tar *,
- struct archive_entry *, const void *);
+ struct archive_entry *, const void *, size_t *);
static int header_common(struct archive_read *, struct tar *,
struct archive_entry *, const void *);
static int header_old_tar(struct archive_read *, struct tar *,
struct archive_entry *, const void *);
static int header_pax_extensions(struct archive_read *, struct tar *,
- struct archive_entry *, const void *);
+ struct archive_entry *, const void *, size_t *);
static int header_pax_global(struct archive_read *, struct tar *,
- struct archive_entry *, const void *h);
+ struct archive_entry *, const void *h, size_t *);
static int header_longlink(struct archive_read *, struct tar *,
- struct archive_entry *, const void *h);
+ struct archive_entry *, const void *h, size_t *);
static int header_longname(struct archive_read *, struct tar *,
- struct archive_entry *, const void *h);
+ struct archive_entry *, const void *h, size_t *);
+static int read_mac_metadata_blob(struct archive_read *, struct tar *,
+ struct archive_entry *, const void *h, size_t *);
static int header_volume(struct archive_read *, struct tar *,
- struct archive_entry *, const void *h);
+ struct archive_entry *, const void *h, size_t *);
static int header_ustar(struct archive_read *, struct tar *,
struct archive_entry *, const void *h);
static int header_gnutar(struct archive_read *, struct tar *,
- struct archive_entry *, const void *h);
-static int archive_read_format_tar_bid(struct archive_read *);
+ struct archive_entry *, const void *h, size_t *);
+static int archive_read_format_tar_bid(struct archive_read *, int);
+static int archive_read_format_tar_options(struct archive_read *,
+ const char *, const char *);
static int archive_read_format_tar_cleanup(struct archive_read *);
static int archive_read_format_tar_read_data(struct archive_read *a,
- const void **buff, size_t *size, off_t *offset);
+ const void **buff, size_t *size, int64_t *offset);
static int archive_read_format_tar_skip(struct archive_read *a);
static int archive_read_format_tar_read_header(struct archive_read *,
struct archive_entry *);
static int checksum(struct archive_read *, const void *);
-static int pax_attribute(struct tar *, struct archive_entry *,
- char *key, char *value);
+static int pax_attribute(struct archive_read *, struct tar *,
+ struct archive_entry *, char *key, char *value);
static int pax_header(struct archive_read *, struct tar *,
struct archive_entry *, char *attr);
static void pax_time(const char *, int64_t *sec, long *nanos);
static ssize_t readline(struct archive_read *, struct tar *, const char **,
- ssize_t limit);
+ ssize_t limit, size_t *);
static int read_body_to_string(struct archive_read *, struct tar *,
- struct archive_string *, const void *h);
+ struct archive_string *, const void *h, size_t *);
+static int solaris_sparse_parse(struct archive_read *, struct tar *,
+ struct archive_entry *, const char *);
static int64_t tar_atol(const char *, unsigned);
static int64_t tar_atol10(const char *, unsigned);
static int64_t tar_atol256(const char *, unsigned);
static int64_t tar_atol8(const char *, unsigned);
static int tar_read_header(struct archive_read *, struct tar *,
- struct archive_entry *);
+ struct archive_entry *, size_t *);
static int tohex(int c);
static char *url_decode(const char *);
-static wchar_t *utf8_decode(struct tar *, const char *, size_t length);
+static void tar_flush_unconsumed(struct archive_read *, size_t *);
+
int
archive_read_support_format_gnutar(struct archive *a)
{
+ archive_check_magic(a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_gnutar");
return (archive_read_support_format_tar(a));
}
@@ -245,17 +237,19 @@ archive_read_support_format_tar(struct archive *_a)
struct tar *tar;
int r;
- tar = (struct tar *)malloc(sizeof(*tar));
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_tar");
+
+ tar = (struct tar *)calloc(1, sizeof(*tar));
if (tar == NULL) {
archive_set_error(&a->archive, ENOMEM,
"Can't allocate tar data");
return (ARCHIVE_FATAL);
}
- memset(tar, 0, sizeof(*tar));
r = __archive_read_register_format(a, tar, "tar",
archive_read_format_tar_bid,
- NULL,
+ archive_read_format_tar_options,
archive_read_format_tar_read_header,
archive_read_format_tar_read_data,
archive_read_format_tar_skip,
@@ -284,7 +278,7 @@ archive_read_format_tar_cleanup(struct archive_read *a)
archive_string_free(&tar->pax_header);
archive_string_free(&tar->longname);
archive_string_free(&tar->longlink);
- free(tar->pax_entry);
+ archive_string_free(&tar->localname);
free(tar);
(a->format->data) = NULL;
return (ARCHIVE_OK);
@@ -292,12 +286,14 @@ archive_read_format_tar_cleanup(struct archive_read *a)
static int
-archive_read_format_tar_bid(struct archive_read *a)
+archive_read_format_tar_bid(struct archive_read *a, int best_bid)
{
int bid;
- const void *h;
+ const char *h;
const struct archive_entry_header_ustar *header;
+ (void)best_bid; /* UNUSED */
+
bid = 0;
/* Now let's look at the actual header and see if it matches. */
@@ -306,8 +302,7 @@ archive_read_format_tar_bid(struct archive_read *a)
return (-1);
/* If it's an end-of-archive mark, we can handle it. */
- if ((*(const char *)h) == 0
- && archive_block_is_null((const unsigned char *)h)) {
+ if (h[0] == 0 && archive_block_is_null(h)) {
/*
* Usually, I bid the number of bits verified, but
* in this case, 4096 seems excessive so I picked 10 as
@@ -325,12 +320,12 @@ archive_read_format_tar_bid(struct archive_read *a)
/* Recognize POSIX formats. */
if ((memcmp(header->magic, "ustar\0", 6) == 0)
- &&(memcmp(header->version, "00", 2)==0))
+ && (memcmp(header->version, "00", 2) == 0))
bid += 56;
/* Recognize GNU tar format. */
if ((memcmp(header->magic, "ustar ", 6) == 0)
- &&(memcmp(header->version, " \0", 2)==0))
+ && (memcmp(header->version, " \0", 2) == 0))
bid += 56;
/* Type flag must be null, digit or A-Z, a-z. */
@@ -362,8 +357,63 @@ archive_read_format_tar_bid(struct archive_read *a)
return (bid);
}
+static int
+archive_read_format_tar_options(struct archive_read *a,
+ const char *key, const char *val)
+{
+ struct tar *tar;
+ int ret = ARCHIVE_FAILED;
+
+ tar = (struct tar *)(a->format->data);
+ if (strcmp(key, "compat-2x") == 0) {
+ /* Handle UTF-8 filnames as libarchive 2.x */
+ tar->compat_2x = (val != NULL)?1:0;
+ tar->init_default_conversion = tar->compat_2x;
+ ret = ARCHIVE_OK;
+ } else if (strcmp(key, "hdrcharset") == 0) {
+ if (val == NULL || val[0] == 0)
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "tar: hdrcharset option needs a character-set name");
+ else {
+ tar->opt_sconv =
+ archive_string_conversion_from_charset(
+ &a->archive, val, 0);
+ if (tar->opt_sconv != NULL)
+ ret = ARCHIVE_OK;
+ else
+ ret = ARCHIVE_FATAL;
+ }
+ } else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "tar: unknown keyword ``%s''", key);
+
+ return (ret);
+}
+
+/* utility function- this exists to centralize the logic of tracking
+ * how much unconsumed data we have floating around, and to consume
+ * anything outstanding since we're going to do read_aheads
+ */
+static void
+tar_flush_unconsumed(struct archive_read *a, size_t *unconsumed)
+{
+ if (*unconsumed) {
+/*
+ void *data = (void *)__archive_read_ahead(a, *unconsumed, NULL);
+ * this block of code is to poison claimed unconsumed space, ensuring
+ * things break if it is in use still.
+ * currently it WILL break things, so enable it only for debugging this issue
+ if (data) {
+ memset(data, 0xff, *unconsumed);
+ }
+*/
+ __archive_read_consume(a, *unconsumed);
+ *unconsumed = 0;
+ }
+}
+
/*
- * The function invoked by archive_read_header(). This
+ * The function invoked by archive_read_next_header(). This
* just sets up a few things and then calls the internal
* tar_read_header() function below.
*/
@@ -388,10 +438,9 @@ archive_read_format_tar_read_header(struct archive_read *a,
static int default_inode;
static int default_dev;
struct tar *tar;
- struct sparse_block *sp;
const char *p;
int r;
- size_t l;
+ size_t l, unconsumed = 0;
/* Assign default device/inode values. */
archive_entry_set_dev(entry, 1 + default_dev); /* Don't use zero. */
@@ -404,22 +453,41 @@ archive_read_format_tar_read_header(struct archive_read *a,
tar = (struct tar *)(a->format->data);
tar->entry_offset = 0;
- while (tar->sparse_list != NULL) {
- sp = tar->sparse_list;
- tar->sparse_list = sp->next;
- free(sp);
- }
- tar->sparse_last = NULL;
+ gnu_clear_sparse_list(tar);
tar->realsize = -1; /* Mark this as "unset" */
- r = tar_read_header(a, tar, entry);
+ /* Setup default string conversion. */
+ tar->sconv = tar->opt_sconv;
+ if (tar->sconv == NULL) {
+ if (!tar->init_default_conversion) {
+ tar->sconv_default =
+ archive_string_default_conversion_for_read(&(a->archive));
+ tar->init_default_conversion = 1;
+ }
+ tar->sconv = tar->sconv_default;
+ }
+
+ r = tar_read_header(a, tar, entry, &unconsumed);
+
+ tar_flush_unconsumed(a, &unconsumed);
/*
* "non-sparse" files are really just sparse files with
* a single block.
*/
- if (tar->sparse_list == NULL)
- gnu_add_sparse_entry(tar, 0, tar->entry_bytes_remaining);
+ if (tar->sparse_list == NULL) {
+ if (gnu_add_sparse_entry(a, tar, 0, tar->entry_bytes_remaining)
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ } else {
+ struct sparse_block *sb;
+
+ for (sb = tar->sparse_list; sb != NULL; sb = sb->next) {
+ if (!sb->hole)
+ archive_entry_sparse_add_entry(entry,
+ sb->offset, sb->remaining);
+ }
+ }
if (r == ARCHIVE_OK) {
/*
@@ -427,18 +495,29 @@ archive_read_format_tar_read_header(struct archive_read *a,
* directory: This is needed for certain old tar
* variants and even for some broken newer ones.
*/
- p = archive_entry_pathname(entry);
- l = strlen(p);
- if (archive_entry_filetype(entry) == AE_IFREG
- && p[l-1] == '/')
- archive_entry_set_filetype(entry, AE_IFDIR);
+ const wchar_t *wp;
+ wp = archive_entry_pathname_w(entry);
+ if (wp != NULL) {
+ l = wcslen(wp);
+ if (archive_entry_filetype(entry) == AE_IFREG
+ && wp[l-1] == L'/')
+ archive_entry_set_filetype(entry, AE_IFDIR);
+ } else {
+ p = archive_entry_pathname(entry);
+ if (p == NULL)
+ return (ARCHIVE_FAILED);
+ l = strlen(p);
+ if (archive_entry_filetype(entry) == AE_IFREG
+ && p[l-1] == '/')
+ archive_entry_set_filetype(entry, AE_IFDIR);
+ }
}
return (r);
}
static int
archive_read_format_tar_read_data(struct archive_read *a,
- const void **buff, size_t *size, off_t *offset)
+ const void **buff, size_t *size, int64_t *offset)
{
ssize_t bytes_read;
struct tar *tar;
@@ -446,24 +525,7 @@ archive_read_format_tar_read_data(struct archive_read *a,
tar = (struct tar *)(a->format->data);
- if (tar->sparse_gnu_pending) {
- if (tar->sparse_gnu_major == 1 && tar->sparse_gnu_minor == 0) {
- tar->sparse_gnu_pending = 0;
- /* Read initial sparse map. */
- bytes_read = gnu_sparse_10_read(a, tar);
- tar->entry_bytes_remaining -= bytes_read;
- if (bytes_read < 0)
- return (bytes_read);
- } else {
- *size = 0;
- *offset = 0;
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Unrecognized GNU sparse file format");
- return (ARCHIVE_WARN);
- }
- tar->sparse_gnu_pending = 0;
- }
-
+skip_hole:
/* Remove exhausted entries from sparse list. */
while (tar->sparse_list != NULL &&
tar->sparse_list->remaining == 0) {
@@ -472,9 +534,14 @@ archive_read_format_tar_read_data(struct archive_read *a,
free(p);
}
+ if (tar->entry_bytes_unconsumed) {
+ __archive_read_consume(a, tar->entry_bytes_unconsumed);
+ tar->entry_bytes_unconsumed = 0;
+ }
+
/* If we're at end of file, return EOF. */
if (tar->sparse_list == NULL || tar->entry_bytes_remaining == 0) {
- if (__archive_read_skip(a, tar->entry_padding) < 0)
+ if (__archive_read_consume(a, tar->entry_padding) < 0)
return (ARCHIVE_FATAL);
tar->entry_padding = 0;
*buff = NULL;
@@ -502,7 +569,11 @@ archive_read_format_tar_read_data(struct archive_read *a,
tar->sparse_list->remaining -= bytes_read;
tar->sparse_list->offset += bytes_read;
tar->entry_bytes_remaining -= bytes_read;
- __archive_read_consume(a, bytes_read);
+ tar->entry_bytes_unconsumed = bytes_read;
+
+ if (tar->sparse_list->hole)
+ goto skip_hole;
+
return (ARCHIVE_OK);
}
@@ -514,17 +585,14 @@ archive_read_format_tar_skip(struct archive_read *a)
tar = (struct tar *)(a->format->data);
- /*
- * Compression layer skip functions are required to either skip the
- * length requested or fail, so we can rely upon the entire entry
- * plus padding being skipped.
- */
- bytes_skipped = __archive_read_skip(a,
- tar->entry_bytes_remaining + tar->entry_padding);
+ bytes_skipped = __archive_read_consume(a,
+ tar->entry_bytes_remaining + tar->entry_padding +
+ tar->entry_bytes_unconsumed);
if (bytes_skipped < 0)
return (ARCHIVE_FATAL);
tar->entry_bytes_remaining = 0;
+ tar->entry_bytes_unconsumed = 0;
tar->entry_padding = 0;
/* Free the sparse list. */
@@ -539,40 +607,34 @@ archive_read_format_tar_skip(struct archive_read *a)
*/
static int
tar_read_header(struct archive_read *a, struct tar *tar,
- struct archive_entry *entry)
+ struct archive_entry *entry, size_t *unconsumed)
{
ssize_t bytes;
int err;
- const void *h;
+ const char *h;
const struct archive_entry_header_ustar *header;
+ tar_flush_unconsumed(a, unconsumed);
+
/* Read 512-byte header record */
h = __archive_read_ahead(a, 512, &bytes);
if (bytes < 0)
return (bytes);
- if (bytes < 512) { /* Short read or EOF. */
- /* Try requesting just one byte and see what happens. */
- (void)__archive_read_ahead(a, 1, &bytes);
- if (bytes == 0) {
- /*
- * The archive ends at a 512-byte boundary but
- * without a proper end-of-archive marker.
- * Yes, there are tar writers that do this;
- * hold our nose and accept it.
- */
- return (ARCHIVE_EOF);
- }
- /* Archive ends with a partial block; this is bad. */
+ if (bytes == 0) { /* EOF at a block boundary. */
+ /* Some writers do omit the block of nulls. <sigh> */
+ return (ARCHIVE_EOF);
+ }
+ if (bytes < 512) { /* Short block at EOF; this is bad. */
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Truncated tar archive");
return (ARCHIVE_FATAL);
}
- __archive_read_consume(a, 512);
-
+ *unconsumed = 512;
/* Check for end-of-archive mark. */
- if (((*(const char *)h)==0) && archive_block_is_null((const unsigned char *)h)) {
+ if (h[0] == 0 && archive_block_is_null(h)) {
/* Try to consume a second all-null record, as well. */
+ tar_flush_unconsumed(a, unconsumed);
h = __archive_read_ahead(a, 512, NULL);
if (h != NULL)
__archive_read_consume(a, 512);
@@ -592,53 +654,56 @@ tar_read_header(struct archive_read *a, struct tar *tar,
* TODO: Improve this by implementing a real header scan.
*/
if (!checksum(a, h)) {
+ tar_flush_unconsumed(a, unconsumed);
archive_set_error(&a->archive, EINVAL, "Damaged tar archive");
return (ARCHIVE_RETRY); /* Retryable: Invalid header */
}
if (++tar->header_recursion_depth > 32) {
+ tar_flush_unconsumed(a, unconsumed);
archive_set_error(&a->archive, EINVAL, "Too many special headers");
return (ARCHIVE_WARN);
}
/* Determine the format variant. */
header = (const struct archive_entry_header_ustar *)h;
+
switch(header->typeflag[0]) {
case 'A': /* Solaris tar ACL */
a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
a->archive.archive_format_name = "Solaris tar";
- err = header_Solaris_ACL(a, tar, entry, h);
+ err = header_Solaris_ACL(a, tar, entry, h, unconsumed);
break;
case 'g': /* POSIX-standard 'g' header. */
a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
a->archive.archive_format_name = "POSIX pax interchange format";
- err = header_pax_global(a, tar, entry, h);
+ err = header_pax_global(a, tar, entry, h, unconsumed);
break;
case 'K': /* Long link name (GNU tar, others) */
- err = header_longlink(a, tar, entry, h);
+ err = header_longlink(a, tar, entry, h, unconsumed);
break;
case 'L': /* Long filename (GNU tar, others) */
- err = header_longname(a, tar, entry, h);
+ err = header_longname(a, tar, entry, h, unconsumed);
break;
case 'V': /* GNU volume header */
- err = header_volume(a, tar, entry, h);
+ err = header_volume(a, tar, entry, h, unconsumed);
break;
case 'X': /* Used by SUN tar; same as 'x'. */
a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
a->archive.archive_format_name =
"POSIX pax interchange format (Sun variant)";
- err = header_pax_extensions(a, tar, entry, h);
+ err = header_pax_extensions(a, tar, entry, h, unconsumed);
break;
case 'x': /* POSIX-standard 'x' header. */
a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
a->archive.archive_format_name = "POSIX pax interchange format";
- err = header_pax_extensions(a, tar, entry, h);
+ err = header_pax_extensions(a, tar, entry, h, unconsumed);
break;
default:
if (memcmp(header->magic, "ustar \0", 8) == 0) {
a->archive.archive_format = ARCHIVE_FORMAT_TAR_GNUTAR;
a->archive.archive_format_name = "GNU tar format";
- err = header_gnutar(a, tar, entry, h);
+ err = header_gnutar(a, tar, entry, h, unconsumed);
} else if (memcmp(header->magic, "ustar", 5) == 0) {
if (a->archive.archive_format != ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE) {
a->archive.archive_format = ARCHIVE_FORMAT_TAR_USTAR;
@@ -651,10 +716,50 @@ tar_read_header(struct archive_read *a, struct tar *tar,
err = header_old_tar(a, tar, entry, h);
}
}
+ if (err == ARCHIVE_FATAL)
+ return (err);
+
+ tar_flush_unconsumed(a, unconsumed);
+
+ h = NULL;
+ header = NULL;
+
--tar->header_recursion_depth;
+ /* Yuck. Apple's design here ends up storing long pathname
+ * extensions for both the AppleDouble extension entry and the
+ * regular entry.
+ */
+ /* TODO: Should this be disabled on non-Mac platforms? */
+ if ((err == ARCHIVE_WARN || err == ARCHIVE_OK) &&
+ tar->header_recursion_depth == 0) {
+ int err2 = read_mac_metadata_blob(a, tar, entry, h, unconsumed);
+ if (err2 < err)
+ err = err2;
+ }
+
/* We return warnings or success as-is. Anything else is fatal. */
- if (err == ARCHIVE_WARN || err == ARCHIVE_OK)
+ if (err == ARCHIVE_WARN || err == ARCHIVE_OK) {
+ if (tar->sparse_gnu_pending) {
+ if (tar->sparse_gnu_major == 1 &&
+ tar->sparse_gnu_minor == 0) {
+ ssize_t bytes_read;
+
+ tar->sparse_gnu_pending = 0;
+ /* Read initial sparse map. */
+ bytes_read = gnu_sparse_10_read(a, tar, unconsumed);
+ tar->entry_bytes_remaining -= bytes_read;
+ if (bytes_read < 0)
+ return (bytes_read);
+ } else {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Unrecognized GNU sparse file format");
+ return (ARCHIVE_WARN);
+ }
+ tar->sparse_gnu_pending = 0;
+ }
return (err);
+ }
if (err == ARCHIVE_EOF)
/* EOF when recursively reading a header is bad. */
archive_set_error(&a->archive, EINVAL, "Damaged tar archive");
@@ -712,7 +817,7 @@ checksum(struct archive_read *a, const void *h)
* Return true if this block contains only nulls.
*/
static int
-archive_block_is_null(const unsigned char *p)
+archive_block_is_null(const char *p)
{
unsigned i;
@@ -727,14 +832,13 @@ archive_block_is_null(const unsigned char *p)
*/
static int
header_Solaris_ACL(struct archive_read *a, struct tar *tar,
- struct archive_entry *entry, const void *h)
+ struct archive_entry *entry, const void *h, size_t *unconsumed)
{
const struct archive_entry_header_ustar *header;
size_t size;
int err;
int64_t type;
char *acl, *p;
- wchar_t *wp;
/*
* read_body_to_string adds a NUL terminator, but we need a little
@@ -742,11 +846,12 @@ header_Solaris_ACL(struct archive_read *a, struct tar *tar,
*/
header = (const struct archive_entry_header_ustar *)h;
size = tar_atol(header->size, sizeof(header->size));
- err = read_body_to_string(a, tar, &(tar->acl_text), h);
+ err = read_body_to_string(a, tar, &(tar->acl_text), h, unconsumed);
if (err != ARCHIVE_OK)
return (err);
+
/* Recursively read next header */
- err = tar_read_header(a, tar, entry);
+ err = tar_read_header(a, tar, entry, unconsumed);
if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN))
return (err);
@@ -802,12 +907,23 @@ header_Solaris_ACL(struct archive_read *a, struct tar *tar,
while (*p != '\0' && p < acl + size)
p++;
- wp = utf8_decode(tar, acl, p - acl);
- err = __archive_entry_acl_parse_w(entry, wp,
- ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
- if (err != ARCHIVE_OK)
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Malformed Solaris ACL attribute (unparsable)");
+ if (tar->sconv_acl == NULL) {
+ tar->sconv_acl = archive_string_conversion_from_charset(
+ &(a->archive), "UTF-8", 1);
+ if (tar->sconv_acl == NULL)
+ return (ARCHIVE_FATAL);
+ }
+ archive_strncpy(&(tar->localname), acl, p - acl);
+ err = archive_acl_parse_l(archive_entry_acl(entry),
+ tar->localname.s, ARCHIVE_ENTRY_ACL_TYPE_ACCESS, tar->sconv_acl);
+ if (err != ARCHIVE_OK) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for ACL");
+ } else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Malformed Solaris ACL attribute (unparsable)");
+ }
return (err);
}
@@ -816,14 +932,14 @@ header_Solaris_ACL(struct archive_read *a, struct tar *tar,
*/
static int
header_longlink(struct archive_read *a, struct tar *tar,
- struct archive_entry *entry, const void *h)
+ struct archive_entry *entry, const void *h, size_t *unconsumed)
{
int err;
- err = read_body_to_string(a, tar, &(tar->longlink), h);
+ err = read_body_to_string(a, tar, &(tar->longlink), h, unconsumed);
if (err != ARCHIVE_OK)
return (err);
- err = tar_read_header(a, tar, entry);
+ err = tar_read_header(a, tar, entry, unconsumed);
if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN))
return (err);
/* Set symlink if symlink already set, else hardlink. */
@@ -831,24 +947,41 @@ header_longlink(struct archive_read *a, struct tar *tar,
return (ARCHIVE_OK);
}
+static int
+set_conversion_failed_error(struct archive_read *a,
+ struct archive_string_conv *sconv, const char *name)
+{
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for %s", name);
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "%s can't be converted from %s to current locale.",
+ name, archive_string_conversion_charset_name(sconv));
+ return (ARCHIVE_WARN);
+}
+
/*
* Interpret 'L' long filename header.
*/
static int
header_longname(struct archive_read *a, struct tar *tar,
- struct archive_entry *entry, const void *h)
+ struct archive_entry *entry, const void *h, size_t *unconsumed)
{
int err;
- err = read_body_to_string(a, tar, &(tar->longname), h);
+ err = read_body_to_string(a, tar, &(tar->longname), h, unconsumed);
if (err != ARCHIVE_OK)
return (err);
/* Read and parse "real" header, then override name. */
- err = tar_read_header(a, tar, entry);
+ err = tar_read_header(a, tar, entry, unconsumed);
if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN))
return (err);
- archive_entry_copy_pathname(entry, tar->longname.s);
- return (ARCHIVE_OK);
+ if (archive_entry_copy_pathname_l(entry, tar->longname.s,
+ archive_strlen(&(tar->longname)), tar->sconv) != 0)
+ err = set_conversion_failed_error(a, tar->sconv, "Pathname");
+ return (err);
}
@@ -857,12 +990,12 @@ header_longname(struct archive_read *a, struct tar *tar,
*/
static int
header_volume(struct archive_read *a, struct tar *tar,
- struct archive_entry *entry, const void *h)
+ struct archive_entry *entry, const void *h, size_t *unconsumed)
{
(void)h;
/* Just skip this and read the next header. */
- return (tar_read_header(a, tar, entry));
+ return (tar_read_header(a, tar, entry, unconsumed));
}
/*
@@ -870,9 +1003,9 @@ header_volume(struct archive_read *a, struct tar *tar,
*/
static int
read_body_to_string(struct archive_read *a, struct tar *tar,
- struct archive_string *as, const void *h)
+ struct archive_string *as, const void *h, size_t *unconsumed)
{
- off_t size, padded_size;
+ int64_t size;
const struct archive_entry_header_ustar *header;
const void *src;
@@ -892,14 +1025,18 @@ read_body_to_string(struct archive_read *a, struct tar *tar,
return (ARCHIVE_FATAL);
}
- /* Read the body into the string. */
- padded_size = (size + 511) & ~ 511;
- src = __archive_read_ahead(a, padded_size, NULL);
- if (src == NULL)
+ tar_flush_unconsumed(a, unconsumed);
+
+ /* Read the body into the string. */
+ *unconsumed = (size + 511) & ~ 511;
+ src = __archive_read_ahead(a, *unconsumed, NULL);
+ if (src == NULL) {
+ *unconsumed = 0;
return (ARCHIVE_FATAL);
+ }
memcpy(as->s, src, size);
- __archive_read_consume(a, padded_size);
as->s[size] = '\0';
+ as->length = size;
return (ARCHIVE_OK);
}
@@ -919,13 +1056,12 @@ header_common(struct archive_read *a, struct tar *tar,
{
const struct archive_entry_header_ustar *header;
char tartype;
-
- (void)a; /* UNUSED */
+ int err = ARCHIVE_OK;
header = (const struct archive_entry_header_ustar *)h;
if (header->linkname[0])
- archive_strncpy(&(tar->entry_linkpath), header->linkname,
- sizeof(header->linkname));
+ archive_strncpy(&(tar->entry_linkpath),
+ header->linkname, sizeof(header->linkname));
else
archive_string_empty(&(tar->entry_linkpath));
@@ -934,6 +1070,12 @@ header_common(struct archive_read *a, struct tar *tar,
archive_entry_set_uid(entry, tar_atol(header->uid, sizeof(header->uid)));
archive_entry_set_gid(entry, tar_atol(header->gid, sizeof(header->gid)));
tar->entry_bytes_remaining = tar_atol(header->size, sizeof(header->size));
+ if (tar->entry_bytes_remaining < 0) {
+ tar->entry_bytes_remaining = 0;
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Tar entry has negative size?");
+ err = ARCHIVE_WARN;
+ }
tar->realsize = tar->entry_bytes_remaining;
archive_entry_set_size(entry, tar->entry_bytes_remaining);
archive_entry_set_mtime(entry, tar_atol(header->mtime, sizeof(header->mtime)), 0);
@@ -943,7 +1085,13 @@ header_common(struct archive_read *a, struct tar *tar,
switch (tartype) {
case '1': /* Hard link */
- archive_entry_copy_hardlink(entry, tar->entry_linkpath.s);
+ if (archive_entry_copy_hardlink_l(entry, tar->entry_linkpath.s,
+ archive_strlen(&(tar->entry_linkpath)), tar->sconv) != 0) {
+ err = set_conversion_failed_error(a, tar->sconv,
+ "Linkname");
+ if (err == ARCHIVE_FATAL)
+ return (err);
+ }
/*
* The following may seem odd, but: Technically, tar
* does not store the file type for a "hard link"
@@ -980,7 +1128,7 @@ header_common(struct archive_read *a, struct tar *tar,
/* Old-style or GNU tar: we must ignore the size. */
archive_entry_set_size(entry, 0);
tar->entry_bytes_remaining = 0;
- } else if (archive_read_format_tar_bid(a) > 50) {
+ } else if (archive_read_format_tar_bid(a, 50) > 50) {
/*
* We don't know if it's pax: If the bid
* function sees a valid ustar header
@@ -1005,7 +1153,13 @@ header_common(struct archive_read *a, struct tar *tar,
archive_entry_set_filetype(entry, AE_IFLNK);
archive_entry_set_size(entry, 0);
tar->entry_bytes_remaining = 0;
- archive_entry_copy_symlink(entry, tar->entry_linkpath.s);
+ if (archive_entry_copy_symlink_l(entry, tar->entry_linkpath.s,
+ archive_strlen(&(tar->entry_linkpath)), tar->sconv) != 0) {
+ err = set_conversion_failed_error(a, tar->sconv,
+ "Linkname");
+ if (err == ARCHIVE_FATAL)
+ return (err);
+ }
break;
case '3': /* Character device */
archive_entry_set_filetype(entry, AE_IFCHR);
@@ -1063,7 +1217,7 @@ header_common(struct archive_read *a, struct tar *tar,
archive_entry_set_filetype(entry, AE_IFREG);
break;
}
- return (0);
+ return (err);
}
/*
@@ -1074,17 +1228,95 @@ header_old_tar(struct archive_read *a, struct tar *tar,
struct archive_entry *entry, const void *h)
{
const struct archive_entry_header_ustar *header;
+ int err = ARCHIVE_OK, err2;
/* Copy filename over (to ensure null termination). */
header = (const struct archive_entry_header_ustar *)h;
- archive_strncpy(&(tar->entry_pathname), header->name, sizeof(header->name));
- archive_entry_copy_pathname(entry, tar->entry_pathname.s);
+ if (archive_entry_copy_pathname_l(entry,
+ header->name, sizeof(header->name), tar->sconv) != 0) {
+ err = set_conversion_failed_error(a, tar->sconv, "Pathname");
+ if (err == ARCHIVE_FATAL)
+ return (err);
+ }
/* Grab rest of common fields */
- header_common(a, tar, entry, h);
+ err2 = header_common(a, tar, entry, h);
+ if (err > err2)
+ err = err2;
tar->entry_padding = 0x1ff & (-tar->entry_bytes_remaining);
- return (0);
+ return (err);
+}
+
+/*
+ * Read a Mac AppleDouble-encoded blob of file metadata,
+ * if there is one.
+ */
+static int
+read_mac_metadata_blob(struct archive_read *a, struct tar *tar,
+ struct archive_entry *entry, const void *h, size_t *unconsumed)
+{
+ int64_t size;
+ const void *data;
+ const char *p, *name;
+ const wchar_t *wp, *wname;
+
+ (void)h; /* UNUSED */
+
+ wname = wp = archive_entry_pathname_w(entry);
+ if (wp != NULL) {
+ /* Find the last path element. */
+ for (; *wp != L'\0'; ++wp) {
+ if (wp[0] == '/' && wp[1] != L'\0')
+ wname = wp + 1;
+ }
+ /*
+ * If last path element starts with "._", then
+ * this is a Mac extension.
+ */
+ if (wname[0] != L'.' || wname[1] != L'_' || wname[2] == L'\0')
+ return ARCHIVE_OK;
+ } else {
+ /* Find the last path element. */
+ name = p = archive_entry_pathname(entry);
+ if (p == NULL)
+ return (ARCHIVE_FAILED);
+ for (; *p != '\0'; ++p) {
+ if (p[0] == '/' && p[1] != '\0')
+ name = p + 1;
+ }
+ /*
+ * If last path element starts with "._", then
+ * this is a Mac extension.
+ */
+ if (name[0] != '.' || name[1] != '_' || name[2] == '\0')
+ return ARCHIVE_OK;
+ }
+
+ /* Read the body as a Mac OS metadata blob. */
+ size = archive_entry_size(entry);
+
+ /*
+ * TODO: Look beyond the body here to peek at the next header.
+ * If it's a regular header (not an extension header)
+ * that has the wrong name, just return the current
+ * entry as-is, without consuming the body here.
+ * That would reduce the risk of us mis-identifying
+ * an ordinary file that just happened to have
+ * a name starting with "._".
+ *
+ * Q: Is the above idea really possible? Even
+ * when there are GNU or pax extension entries?
+ */
+ data = __archive_read_ahead(a, size, NULL);
+ if (data == NULL) {
+ *unconsumed = 0;
+ return (ARCHIVE_FATAL);
+ }
+ archive_entry_copy_mac_metadata(entry, data, size);
+ *unconsumed = (size + 511) & ~ 511;
+ tar_flush_unconsumed(a, unconsumed);
+ return (tar_read_header(a, tar, entry, unconsumed));
}
/*
@@ -1092,29 +1324,29 @@ header_old_tar(struct archive_read *a, struct tar *tar,
*/
static int
header_pax_global(struct archive_read *a, struct tar *tar,
- struct archive_entry *entry, const void *h)
+ struct archive_entry *entry, const void *h, size_t *unconsumed)
{
int err;
- err = read_body_to_string(a, tar, &(tar->pax_global), h);
+ err = read_body_to_string(a, tar, &(tar->pax_global), h, unconsumed);
if (err != ARCHIVE_OK)
return (err);
- err = tar_read_header(a, tar, entry);
+ err = tar_read_header(a, tar, entry, unconsumed);
return (err);
}
static int
header_pax_extensions(struct archive_read *a, struct tar *tar,
- struct archive_entry *entry, const void *h)
+ struct archive_entry *entry, const void *h, size_t *unconsumed)
{
int err, err2;
- err = read_body_to_string(a, tar, &(tar->pax_header), h);
+ err = read_body_to_string(a, tar, &(tar->pax_header), h, unconsumed);
if (err != ARCHIVE_OK)
return (err);
/* Parse the next header. */
- err = tar_read_header(a, tar, entry);
+ err = tar_read_header(a, tar, entry, unconsumed);
if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN))
return (err);
@@ -1145,6 +1377,7 @@ header_ustar(struct archive_read *a, struct tar *tar,
{
const struct archive_entry_header_ustar *header;
struct archive_string *as;
+ int err = ARCHIVE_OK, r;
header = (const struct archive_entry_header_ustar *)h;
@@ -1155,22 +1388,37 @@ header_ustar(struct archive_read *a, struct tar *tar,
if (as->s[archive_strlen(as) - 1] != '/')
archive_strappend_char(as, '/');
archive_strncat(as, header->name, sizeof(header->name));
- } else
+ } else {
archive_strncpy(as, header->name, sizeof(header->name));
-
- archive_entry_copy_pathname(entry, as->s);
+ }
+ if (archive_entry_copy_pathname_l(entry, as->s, archive_strlen(as),
+ tar->sconv) != 0) {
+ err = set_conversion_failed_error(a, tar->sconv, "Pathname");
+ if (err == ARCHIVE_FATAL)
+ return (err);
+ }
/* Handle rest of common fields. */
- header_common(a, tar, entry, h);
+ r = header_common(a, tar, entry, h);
+ if (r == ARCHIVE_FATAL)
+ return (r);
+ if (r < err)
+ err = r;
/* Handle POSIX ustar fields. */
- archive_strncpy(&(tar->entry_uname), header->uname,
- sizeof(header->uname));
- archive_entry_copy_uname(entry, tar->entry_uname.s);
+ if (archive_entry_copy_uname_l(entry,
+ header->uname, sizeof(header->uname), tar->sconv) != 0) {
+ err = set_conversion_failed_error(a, tar->sconv, "Uname");
+ if (err == ARCHIVE_FATAL)
+ return (err);
+ }
- archive_strncpy(&(tar->entry_gname), header->gname,
- sizeof(header->gname));
- archive_entry_copy_gname(entry, tar->entry_gname.s);
+ if (archive_entry_copy_gname_l(entry,
+ header->gname, sizeof(header->gname), tar->sconv) != 0) {
+ err = set_conversion_failed_error(a, tar->sconv, "Gname");
+ if (err == ARCHIVE_FATAL)
+ return (err);
+ }
/* Parse out device numbers only for char and block specials. */
if (header->typeflag[0] == '3' || header->typeflag[0] == '4') {
@@ -1182,7 +1430,7 @@ header_ustar(struct archive_read *a, struct tar *tar,
tar->entry_padding = 0x1ff & (-tar->entry_bytes_remaining);
- return (0);
+ return (err);
}
@@ -1198,6 +1446,8 @@ pax_header(struct archive_read *a, struct tar *tar,
size_t attr_length, l, line_length;
char *p;
char *key, *value;
+ struct archive_string *as;
+ struct archive_string_conv *sconv;
int err, err2;
attr_length = strlen(attr);
@@ -1269,39 +1519,55 @@ pax_header(struct archive_read *a, struct tar *tar,
value = p + 1;
/* Identify this attribute and set it in the entry. */
- err2 = pax_attribute(tar, entry, key, value);
+ err2 = pax_attribute(a, tar, entry, key, value);
+ if (err2 == ARCHIVE_FATAL)
+ return (err2);
err = err_combine(err, err2);
/* Skip to next line */
attr += line_length;
attr_length -= line_length;
}
+
+ /*
+ * PAX format uses UTF-8 as default charset for its metadata
+ * unless hdrcharset=BINARY is present in its header.
+ * We apply the charset specified by the hdrcharset option only
+ * when the hdrcharset attribute(in PAX header) is BINARY because
+ * we respect the charset described in PAX header and BINARY also
+ * means that metadata(filename,uname and gname) character-set
+ * is unknown.
+ */
+ if (tar->pax_hdrcharset_binary)
+ sconv = tar->opt_sconv;
+ else {
+ sconv = archive_string_conversion_from_charset(
+ &(a->archive), "UTF-8", 1);
+ if (sconv == NULL)
+ return (ARCHIVE_FATAL);
+ if (tar->compat_2x)
+ archive_string_conversion_set_opt(sconv,
+ SCONV_SET_OPT_UTF8_LIBARCHIVE2X);
+ }
+
if (archive_strlen(&(tar->entry_gname)) > 0) {
- value = tar->entry_gname.s;
- if (tar->pax_hdrcharset_binary)
- archive_entry_copy_gname(entry, value);
- else {
- if (!archive_entry_update_gname_utf8(entry, value)) {
- err = ARCHIVE_WARN;
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Gname in pax header can't "
- "be converted to current locale.");
- }
+ if (archive_entry_copy_gname_l(entry, tar->entry_gname.s,
+ archive_strlen(&(tar->entry_gname)), sconv) != 0) {
+ err = set_conversion_failed_error(a, sconv, "Gname");
+ if (err == ARCHIVE_FATAL)
+ return (err);
+ /* Use a converted an original name. */
+ archive_entry_copy_gname(entry, tar->entry_gname.s);
}
}
if (archive_strlen(&(tar->entry_linkpath)) > 0) {
- value = tar->entry_linkpath.s;
- if (tar->pax_hdrcharset_binary)
- archive_entry_copy_link(entry, value);
- else {
- if (!archive_entry_update_link_utf8(entry, value)) {
- err = ARCHIVE_WARN;
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Linkname in pax header can't "
- "be converted to current locale.");
- }
+ if (archive_entry_copy_link_l(entry, tar->entry_linkpath.s,
+ archive_strlen(&(tar->entry_linkpath)), sconv) != 0) {
+ err = set_conversion_failed_error(a, sconv, "Linkname");
+ if (err == ARCHIVE_FATAL)
+ return (err);
+ /* Use a converted an original name. */
+ archive_entry_copy_link(entry, tar->entry_linkpath.s);
}
}
/*
@@ -1313,36 +1579,29 @@ pax_header(struct archive_read *a, struct tar *tar,
* we find and figure it all out afterwards. This is the
* figuring out part.
*/
- value = NULL;
+ as = NULL;
if (archive_strlen(&(tar->entry_pathname_override)) > 0)
- value = tar->entry_pathname_override.s;
+ as = &(tar->entry_pathname_override);
else if (archive_strlen(&(tar->entry_pathname)) > 0)
- value = tar->entry_pathname.s;
- if (value != NULL) {
- if (tar->pax_hdrcharset_binary)
- archive_entry_copy_pathname(entry, value);
- else {
- if (!archive_entry_update_pathname_utf8(entry, value)) {
- err = ARCHIVE_WARN;
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Pathname in pax header can't be "
- "converted to current locale.");
- }
+ as = &(tar->entry_pathname);
+ if (as != NULL) {
+ if (archive_entry_copy_pathname_l(entry, as->s,
+ archive_strlen(as), sconv) != 0) {
+ err = set_conversion_failed_error(a, sconv, "Pathname");
+ if (err == ARCHIVE_FATAL)
+ return (err);
+ /* Use a converted an original name. */
+ archive_entry_copy_pathname(entry, as->s);
}
}
if (archive_strlen(&(tar->entry_uname)) > 0) {
- value = tar->entry_uname.s;
- if (tar->pax_hdrcharset_binary)
- archive_entry_copy_uname(entry, value);
- else {
- if (!archive_entry_update_uname_utf8(entry, value)) {
- err = ARCHIVE_WARN;
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Uname in pax header can't "
- "be converted to current locale.");
- }
+ if (archive_entry_copy_uname_l(entry, tar->entry_uname.s,
+ archive_strlen(&(tar->entry_uname)), sconv) != 0) {
+ err = set_conversion_failed_error(a, sconv, "Uname");
+ if (err == ARCHIVE_FATAL)
+ return (err);
+ /* Use a converted an original name. */
+ archive_entry_copy_uname(entry, tar->entry_uname.s);
}
}
return (err);
@@ -1356,7 +1615,7 @@ pax_attribute_xattr(struct archive_entry *entry,
void *value_decoded;
size_t value_len;
- if (strlen(name) < 18 || (strncmp(name, "LIBARCHIVE.xattr.", 17)) != 0)
+ if (strlen(name) < 18 || (memcmp(name, "LIBARCHIVE.xattr.", 17)) != 0)
return 3;
name += 17;
@@ -1395,12 +1654,12 @@ pax_attribute_xattr(struct archive_entry *entry,
* any of them look useful.
*/
static int
-pax_attribute(struct tar *tar, struct archive_entry *entry,
- char *key, char *value)
+pax_attribute(struct archive_read *a, struct tar *tar,
+ struct archive_entry *entry, char *key, char *value)
{
int64_t s;
long n;
- wchar_t *wp;
+ int err = ARCHIVE_OK, r;
switch (key[0]) {
case 'G':
@@ -1414,8 +1673,10 @@ pax_attribute(struct tar *tar, struct archive_entry *entry,
if (strcmp(key, "GNU.sparse.offset") == 0) {
tar->sparse_offset = tar_atol10(value, strlen(value));
if (tar->sparse_numbytes != -1) {
- gnu_add_sparse_entry(tar,
- tar->sparse_offset, tar->sparse_numbytes);
+ if (gnu_add_sparse_entry(a, tar,
+ tar->sparse_offset, tar->sparse_numbytes)
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
tar->sparse_offset = -1;
tar->sparse_numbytes = -1;
}
@@ -1423,8 +1684,10 @@ pax_attribute(struct tar *tar, struct archive_entry *entry,
if (strcmp(key, "GNU.sparse.numbytes") == 0) {
tar->sparse_numbytes = tar_atol10(value, strlen(value));
if (tar->sparse_numbytes != -1) {
- gnu_add_sparse_entry(tar,
- tar->sparse_offset, tar->sparse_numbytes);
+ if (gnu_add_sparse_entry(a, tar,
+ tar->sparse_offset, tar->sparse_numbytes)
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
tar->sparse_offset = -1;
tar->sparse_numbytes = -1;
}
@@ -1438,7 +1701,7 @@ pax_attribute(struct tar *tar, struct archive_entry *entry,
if (strcmp(key, "GNU.sparse.map") == 0) {
tar->sparse_gnu_major = 0;
tar->sparse_gnu_minor = 1;
- if (gnu_sparse_01_parse(tar, value) != ARCHIVE_OK)
+ if (gnu_sparse_01_parse(a, tar, value) != ARCHIVE_OK)
return (ARCHIVE_WARN);
}
@@ -1469,99 +1732,146 @@ pax_attribute(struct tar *tar, struct archive_entry *entry,
/* Our extensions */
/* TODO: Handle arbitrary extended attributes... */
/*
- if (strcmp(key, "LIBARCHIVE.xxxxxxx")==0)
+ if (strcmp(key, "LIBARCHIVE.xxxxxxx") == 0)
archive_entry_set_xxxxxx(entry, value);
*/
- if (strcmp(key, "LIBARCHIVE.creationtime")==0) {
+ if (strcmp(key, "LIBARCHIVE.creationtime") == 0) {
pax_time(value, &s, &n);
archive_entry_set_birthtime(entry, s, n);
}
- if (strncmp(key, "LIBARCHIVE.xattr.", 17)==0)
+ if (memcmp(key, "LIBARCHIVE.xattr.", 17) == 0)
pax_attribute_xattr(entry, key, value);
break;
case 'S':
/* We support some keys used by the "star" archiver */
- if (strcmp(key, "SCHILY.acl.access")==0) {
- wp = utf8_decode(tar, value, strlen(value));
- /* TODO: if (wp == NULL) */
- __archive_entry_acl_parse_w(entry, wp,
- ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
- } else if (strcmp(key, "SCHILY.acl.default")==0) {
- wp = utf8_decode(tar, value, strlen(value));
- /* TODO: if (wp == NULL) */
- __archive_entry_acl_parse_w(entry, wp,
- ARCHIVE_ENTRY_ACL_TYPE_DEFAULT);
- } else if (strcmp(key, "SCHILY.devmajor")==0) {
+ if (strcmp(key, "SCHILY.acl.access") == 0) {
+ if (tar->sconv_acl == NULL) {
+ tar->sconv_acl =
+ archive_string_conversion_from_charset(
+ &(a->archive), "UTF-8", 1);
+ if (tar->sconv_acl == NULL)
+ return (ARCHIVE_FATAL);
+ }
+
+ r = archive_acl_parse_l(archive_entry_acl(entry),
+ value, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
+ tar->sconv_acl);
+ if (r != ARCHIVE_OK) {
+ err = r;
+ if (err == ARCHIVE_FATAL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for "
+ "SCHILY.acl.access");
+ return (err);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Parse error: SCHILY.acl.access");
+ }
+ } else if (strcmp(key, "SCHILY.acl.default") == 0) {
+ if (tar->sconv_acl == NULL) {
+ tar->sconv_acl =
+ archive_string_conversion_from_charset(
+ &(a->archive), "UTF-8", 1);
+ if (tar->sconv_acl == NULL)
+ return (ARCHIVE_FATAL);
+ }
+
+ r = archive_acl_parse_l(archive_entry_acl(entry),
+ value, ARCHIVE_ENTRY_ACL_TYPE_DEFAULT,
+ tar->sconv_acl);
+ if (r != ARCHIVE_OK) {
+ err = r;
+ if (err == ARCHIVE_FATAL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for "
+ "SCHILY.acl.default");
+ return (err);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Parse error: SCHILY.acl.default");
+ }
+ } else if (strcmp(key, "SCHILY.devmajor") == 0) {
archive_entry_set_rdevmajor(entry,
tar_atol10(value, strlen(value)));
- } else if (strcmp(key, "SCHILY.devminor")==0) {
+ } else if (strcmp(key, "SCHILY.devminor") == 0) {
archive_entry_set_rdevminor(entry,
tar_atol10(value, strlen(value)));
- } else if (strcmp(key, "SCHILY.fflags")==0) {
+ } else if (strcmp(key, "SCHILY.fflags") == 0) {
archive_entry_copy_fflags_text(entry, value);
- } else if (strcmp(key, "SCHILY.dev")==0) {
+ } else if (strcmp(key, "SCHILY.dev") == 0) {
archive_entry_set_dev(entry,
tar_atol10(value, strlen(value)));
- } else if (strcmp(key, "SCHILY.ino")==0) {
+ } else if (strcmp(key, "SCHILY.ino") == 0) {
archive_entry_set_ino(entry,
tar_atol10(value, strlen(value)));
- } else if (strcmp(key, "SCHILY.nlink")==0) {
+ } else if (strcmp(key, "SCHILY.nlink") == 0) {
archive_entry_set_nlink(entry,
tar_atol10(value, strlen(value)));
- } else if (strcmp(key, "SCHILY.realsize")==0) {
+ } else if (strcmp(key, "SCHILY.realsize") == 0) {
tar->realsize = tar_atol10(value, strlen(value));
archive_entry_set_size(entry, tar->realsize);
+ } else if (strcmp(key, "SUN.holesdata") == 0) {
+ /* A Solaris extension for sparse. */
+ r = solaris_sparse_parse(a, tar, entry, value);
+ if (r < err) {
+ if (r == ARCHIVE_FATAL)
+ return (r);
+ err = r;
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Parse error: SUN.holesdata");
+ }
}
break;
case 'a':
- if (strcmp(key, "atime")==0) {
+ if (strcmp(key, "atime") == 0) {
pax_time(value, &s, &n);
archive_entry_set_atime(entry, s, n);
}
break;
case 'c':
- if (strcmp(key, "ctime")==0) {
+ if (strcmp(key, "ctime") == 0) {
pax_time(value, &s, &n);
archive_entry_set_ctime(entry, s, n);
- } else if (strcmp(key, "charset")==0) {
+ } else if (strcmp(key, "charset") == 0) {
/* TODO: Publish charset information in entry. */
- } else if (strcmp(key, "comment")==0) {
+ } else if (strcmp(key, "comment") == 0) {
/* TODO: Publish comment in entry. */
}
break;
case 'g':
- if (strcmp(key, "gid")==0) {
+ if (strcmp(key, "gid") == 0) {
archive_entry_set_gid(entry,
tar_atol10(value, strlen(value)));
- } else if (strcmp(key, "gname")==0) {
+ } else if (strcmp(key, "gname") == 0) {
archive_strcpy(&(tar->entry_gname), value);
}
break;
case 'h':
if (strcmp(key, "hdrcharset") == 0) {
if (strcmp(value, "BINARY") == 0)
+ /* Binary mode. */
tar->pax_hdrcharset_binary = 1;
else if (strcmp(value, "ISO-IR 10646 2000 UTF-8") == 0)
tar->pax_hdrcharset_binary = 0;
- else {
- /* TODO: Warn about unsupported hdrcharset */
- }
}
break;
case 'l':
/* pax interchange doesn't distinguish hardlink vs. symlink. */
- if (strcmp(key, "linkpath")==0) {
+ if (strcmp(key, "linkpath") == 0) {
archive_strcpy(&(tar->entry_linkpath), value);
}
break;
case 'm':
- if (strcmp(key, "mtime")==0) {
+ if (strcmp(key, "mtime") == 0) {
pax_time(value, &s, &n);
archive_entry_set_mtime(entry, s, n);
}
break;
case 'p':
- if (strcmp(key, "path")==0) {
+ if (strcmp(key, "path") == 0) {
archive_strcpy(&(tar->entry_pathname), value);
}
break;
@@ -1570,8 +1880,8 @@ pax_attribute(struct tar *tar, struct archive_entry *entry,
break;
case 's':
/* POSIX has reserved 'security.*' */
- /* Someday: if (strcmp(key, "security.acl")==0) { ... } */
- if (strcmp(key, "size")==0) {
+ /* Someday: if (strcmp(key, "security.acl") == 0) { ... } */
+ if (strcmp(key, "size") == 0) {
/* "size" is the size of the data in the entry. */
tar->entry_bytes_remaining
= tar_atol10(value, strlen(value));
@@ -1592,15 +1902,15 @@ pax_attribute(struct tar *tar, struct archive_entry *entry,
}
break;
case 'u':
- if (strcmp(key, "uid")==0) {
+ if (strcmp(key, "uid") == 0) {
archive_entry_set_uid(entry,
tar_atol10(value, strlen(value)));
- } else if (strcmp(key, "uname")==0) {
+ } else if (strcmp(key, "uname") == 0) {
archive_strcpy(&(tar->entry_uname), value);
}
break;
}
- return (0);
+ return (err);
}
@@ -1660,11 +1970,11 @@ pax_time(const char *p, int64_t *ps, long *pn)
*/
static int
header_gnutar(struct archive_read *a, struct tar *tar,
- struct archive_entry *entry, const void *h)
+ struct archive_entry *entry, const void *h, size_t *unconsumed)
{
const struct archive_entry_header_gnutar *header;
-
- (void)a;
+ int64_t t;
+ int err = ARCHIVE_OK;
/*
* GNU header is like POSIX ustar, except 'prefix' is
@@ -1673,25 +1983,36 @@ header_gnutar(struct archive_read *a, struct tar *tar,
*/
/* Grab fields common to all tar variants. */
- header_common(a, tar, entry, h);
+ err = header_common(a, tar, entry, h);
+ if (err == ARCHIVE_FATAL)
+ return (err);
/* Copy filename over (to ensure null termination). */
header = (const struct archive_entry_header_gnutar *)h;
- archive_strncpy(&(tar->entry_pathname), header->name,
- sizeof(header->name));
- archive_entry_copy_pathname(entry, tar->entry_pathname.s);
+ if (archive_entry_copy_pathname_l(entry,
+ header->name, sizeof(header->name), tar->sconv) != 0) {
+ err = set_conversion_failed_error(a, tar->sconv, "Pathname");
+ if (err == ARCHIVE_FATAL)
+ return (err);
+ }
/* Fields common to ustar and GNU */
/* XXX Can the following be factored out since it's common
* to ustar and gnu tar? Is it okay to move it down into
* header_common, perhaps? */
- archive_strncpy(&(tar->entry_uname),
- header->uname, sizeof(header->uname));
- archive_entry_copy_uname(entry, tar->entry_uname.s);
+ if (archive_entry_copy_uname_l(entry,
+ header->uname, sizeof(header->uname), tar->sconv) != 0) {
+ err = set_conversion_failed_error(a, tar->sconv, "Uname");
+ if (err == ARCHIVE_FATAL)
+ return (err);
+ }
- archive_strncpy(&(tar->entry_gname),
- header->gname, sizeof(header->gname));
- archive_entry_copy_gname(entry, tar->entry_gname.s);
+ if (archive_entry_copy_gname_l(entry,
+ header->gname, sizeof(header->gname), tar->sconv) != 0) {
+ err = set_conversion_failed_error(a, tar->sconv, "Gname");
+ if (err == ARCHIVE_FATAL)
+ return (err);
+ }
/* Parse out device numbers only for char and block specials */
if (header->typeflag[0] == '3' || header->typeflag[0] == '4') {
@@ -1705,10 +2026,13 @@ header_gnutar(struct archive_read *a, struct tar *tar,
tar->entry_padding = 0x1ff & (-tar->entry_bytes_remaining);
/* Grab GNU-specific fields. */
- archive_entry_set_atime(entry,
- tar_atol(header->atime, sizeof(header->atime)), 0);
- archive_entry_set_ctime(entry,
- tar_atol(header->ctime, sizeof(header->ctime)), 0);
+ t = tar_atol(header->atime, sizeof(header->atime));
+ if (t > 0)
+ archive_entry_set_atime(entry, t, 0);
+ t = tar_atol(header->ctime, sizeof(header->ctime));
+ if (t > 0)
+ archive_entry_set_ctime(entry, t, 0);
+
if (header->realsize[0] != 0) {
tar->realsize
= tar_atol(header->realsize, sizeof(header->realsize));
@@ -1716,24 +2040,29 @@ header_gnutar(struct archive_read *a, struct tar *tar,
}
if (header->sparse[0].offset[0] != 0) {
- gnu_sparse_old_read(a, tar, header);
+ if (gnu_sparse_old_read(a, tar, header, unconsumed)
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
} else {
if (header->isextended[0] != 0) {
/* XXX WTF? XXX */
}
}
- return (0);
+ return (err);
}
-static void
-gnu_add_sparse_entry(struct tar *tar, off_t offset, off_t remaining)
+static int
+gnu_add_sparse_entry(struct archive_read *a, struct tar *tar,
+ int64_t offset, int64_t remaining)
{
struct sparse_block *p;
p = (struct sparse_block *)malloc(sizeof(*p));
- if (p == NULL)
- __archive_errx(1, "Out of memory");
+ if (p == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
memset(p, 0, sizeof(*p));
if (tar->sparse_last != NULL)
tar->sparse_last->next = p;
@@ -1742,6 +2071,7 @@ gnu_add_sparse_entry(struct tar *tar, off_t offset, off_t remaining)
tar->sparse_last = p;
p->offset = offset;
p->remaining = remaining;
+ return (ARCHIVE_OK);
}
static void
@@ -1771,7 +2101,7 @@ gnu_clear_sparse_list(struct tar *tar)
static int
gnu_sparse_old_read(struct archive_read *a, struct tar *tar,
- const struct archive_entry_header_gnutar *header)
+ const struct archive_entry_header_gnutar *header, size_t *unconsumed)
{
ssize_t bytes_read;
const void *data;
@@ -1782,11 +2112,13 @@ gnu_sparse_old_read(struct archive_read *a, struct tar *tar,
};
const struct extended *ext;
- gnu_sparse_old_parse(tar, header->sparse, 4);
+ if (gnu_sparse_old_parse(a, tar, header->sparse, 4) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
if (header->isextended[0] == 0)
return (ARCHIVE_OK);
do {
+ tar_flush_unconsumed(a, unconsumed);
data = __archive_read_ahead(a, 512, &bytes_read);
if (bytes_read < 0)
return (ARCHIVE_FATAL);
@@ -1796,26 +2128,30 @@ gnu_sparse_old_read(struct archive_read *a, struct tar *tar,
"detected while reading sparse file data");
return (ARCHIVE_FATAL);
}
- __archive_read_consume(a, 512);
+ *unconsumed = 512;
ext = (const struct extended *)data;
- gnu_sparse_old_parse(tar, ext->sparse, 21);
+ if (gnu_sparse_old_parse(a, tar, ext->sparse, 21) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
} while (ext->isextended[0] != 0);
if (tar->sparse_list != NULL)
tar->entry_offset = tar->sparse_list->offset;
return (ARCHIVE_OK);
}
-static void
-gnu_sparse_old_parse(struct tar *tar,
+static int
+gnu_sparse_old_parse(struct archive_read *a, struct tar *tar,
const struct gnu_sparse *sparse, int length)
{
while (length > 0 && sparse->offset[0] != 0) {
- gnu_add_sparse_entry(tar,
+ if (gnu_add_sparse_entry(a, tar,
tar_atol(sparse->offset, sizeof(sparse->offset)),
- tar_atol(sparse->numbytes, sizeof(sparse->numbytes)));
+ tar_atol(sparse->numbytes, sizeof(sparse->numbytes)))
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
sparse++;
length--;
}
+ return (ARCHIVE_OK);
}
/*
@@ -1824,7 +2160,7 @@ gnu_sparse_old_parse(struct tar *tar,
* Beginning with GNU tar 1.15, sparse files are stored using
* information in the pax extended header. The GNU tar maintainers
* have gone through a number of variations in the process of working
- * out this scheme; furtunately, they're all numbered.
+ * out this scheme; fortunately, they're all numbered.
*
* Sparse format 0.0 uses attribute GNU.sparse.numblocks to store the
* number of blocks, and GNU.sparse.offset/GNU.sparse.numbytes to
@@ -1845,10 +2181,10 @@ gnu_sparse_old_parse(struct tar *tar,
*/
static int
-gnu_sparse_01_parse(struct tar *tar, const char *p)
+gnu_sparse_01_parse(struct archive_read *a, struct tar *tar, const char *p)
{
const char *e;
- off_t offset = -1, size = -1;
+ int64_t offset = -1, size = -1;
for (;;) {
e = p;
@@ -1865,7 +2201,9 @@ gnu_sparse_01_parse(struct tar *tar, const char *p)
size = tar_atol10(p, e - p);
if (size < 0)
return (ARCHIVE_WARN);
- gnu_add_sparse_entry(tar, offset, size);
+ if (gnu_add_sparse_entry(a, tar, offset, size)
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
offset = -1;
}
if (*e == '\0')
@@ -1899,7 +2237,7 @@ gnu_sparse_01_parse(struct tar *tar, const char *p)
*/
static int64_t
gnu_sparse_10_atol(struct archive_read *a, struct tar *tar,
- ssize_t *remaining)
+ int64_t *remaining, size_t *unconsumed)
{
int64_t l, limit, last_digit_limit;
const char *p;
@@ -1915,7 +2253,7 @@ gnu_sparse_10_atol(struct archive_read *a, struct tar *tar,
* don't require this, but they should.
*/
do {
- bytes_read = readline(a, tar, &p, tar_min(*remaining, 100));
+ bytes_read = readline(a, tar, &p, tar_min(*remaining, 100), unconsumed);
if (bytes_read <= 0)
return (ARCHIVE_FATAL);
*remaining -= bytes_read;
@@ -1944,11 +2282,11 @@ gnu_sparse_10_atol(struct archive_read *a, struct tar *tar,
* that was read.
*/
static ssize_t
-gnu_sparse_10_read(struct archive_read *a, struct tar *tar)
+gnu_sparse_10_read(struct archive_read *a, struct tar *tar, size_t *unconsumed)
{
- ssize_t remaining, bytes_read;
+ ssize_t bytes_read;
int entries;
- off_t offset, size, to_skip;
+ int64_t offset, size, to_skip, remaining;
/* Clear out the existing sparse list. */
gnu_clear_sparse_list(tar);
@@ -1956,29 +2294,74 @@ gnu_sparse_10_read(struct archive_read *a, struct tar *tar)
remaining = tar->entry_bytes_remaining;
/* Parse entries. */
- entries = gnu_sparse_10_atol(a, tar, &remaining);
+ entries = gnu_sparse_10_atol(a, tar, &remaining, unconsumed);
if (entries < 0)
return (ARCHIVE_FATAL);
/* Parse the individual entries. */
while (entries-- > 0) {
/* Parse offset/size */
- offset = gnu_sparse_10_atol(a, tar, &remaining);
+ offset = gnu_sparse_10_atol(a, tar, &remaining, unconsumed);
if (offset < 0)
return (ARCHIVE_FATAL);
- size = gnu_sparse_10_atol(a, tar, &remaining);
+ size = gnu_sparse_10_atol(a, tar, &remaining, unconsumed);
if (size < 0)
return (ARCHIVE_FATAL);
/* Add a new sparse entry. */
- gnu_add_sparse_entry(tar, offset, size);
+ if (gnu_add_sparse_entry(a, tar, offset, size) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
}
/* Skip rest of block... */
+ tar_flush_unconsumed(a, unconsumed);
bytes_read = tar->entry_bytes_remaining - remaining;
to_skip = 0x1ff & -bytes_read;
- if (to_skip != __archive_read_skip(a, to_skip))
+ if (to_skip != __archive_read_consume(a, to_skip))
return (ARCHIVE_FATAL);
return (bytes_read + to_skip);
}
+/*
+ * Solaris pax extension for a sparse file. This is recorded with the
+ * data and hole pairs. The way recording sparse information by Solaris'
+ * pax simply indicates where data and sparse are, so the stored contents
+ * consist of both data and hole.
+ */
+static int
+solaris_sparse_parse(struct archive_read *a, struct tar *tar,
+ struct archive_entry *entry, const char *p)
+{
+ const char *e;
+ int64_t start, end;
+ int hole = 1;
+
+ end = 0;
+ if (*p == ' ')
+ p++;
+ else
+ return (ARCHIVE_WARN);
+ for (;;) {
+ e = p;
+ while (*e != '\0' && *e != ' ') {
+ if (*e < '0' || *e > '9')
+ return (ARCHIVE_WARN);
+ e++;
+ }
+ start = end;
+ end = tar_atol10(p, e - p);
+ if (end < 0)
+ return (ARCHIVE_WARN);
+ if (start < end) {
+ if (gnu_add_sparse_entry(a, tar, start,
+ end - start) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ tar->sparse_last->hole = hole;
+ }
+ if (*e == '\0')
+ return (ARCHIVE_OK);
+ p = e + 1;
+ hole = hole == 0;
+ }
+}
+
/*-
* Convert text->integer.
*
@@ -2121,7 +2504,7 @@ tar_atol256(const char *_p, unsigned char_cnt)
*/
static ssize_t
readline(struct archive_read *a, struct tar *tar, const char **start,
- ssize_t limit)
+ ssize_t limit, size_t *unconsumed)
{
ssize_t bytes_read;
ssize_t total_size = 0;
@@ -2129,6 +2512,8 @@ readline(struct archive_read *a, struct tar *tar, const char **start,
const char *s;
void *p;
+ tar_flush_unconsumed(a, unconsumed);
+
t = __archive_read_ahead(a, 1, &bytes_read);
if (bytes_read <= 0)
return (ARCHIVE_FATAL);
@@ -2143,10 +2528,11 @@ readline(struct archive_read *a, struct tar *tar, const char **start,
"Line too long");
return (ARCHIVE_FATAL);
}
- __archive_read_consume(a, bytes_read);
+ *unconsumed = bytes_read;
*start = s;
return (bytes_read);
}
+ *unconsumed = bytes_read;
/* Otherwise, we need to accumulate in a line buffer. */
for (;;) {
if (total_size + bytes_read > limit) {
@@ -2161,7 +2547,7 @@ readline(struct archive_read *a, struct tar *tar, const char **start,
return (ARCHIVE_FATAL);
}
memcpy(tar->line.s + total_size, t, bytes_read);
- __archive_read_consume(a, bytes_read);
+ tar_flush_unconsumed(a, unconsumed);
total_size += bytes_read;
/* If we found '\n', clean up and return. */
if (p != NULL) {
@@ -2178,122 +2564,10 @@ readline(struct archive_read *a, struct tar *tar, const char **start,
if (p != NULL) {
bytes_read = 1 + ((const char *)p) - s;
}
+ *unconsumed = bytes_read;
}
}
-static wchar_t *
-utf8_decode(struct tar *tar, const char *src, size_t length)
-{
- wchar_t *dest;
- ssize_t n;
-
- /* Ensure pax_entry buffer is big enough. */
- if (tar->pax_entry_length <= length) {
- wchar_t *old_entry;
-
- if (tar->pax_entry_length <= 0)
- tar->pax_entry_length = 1024;
- while (tar->pax_entry_length <= length + 1)
- tar->pax_entry_length *= 2;
-
- old_entry = tar->pax_entry;
- tar->pax_entry = (wchar_t *)realloc(tar->pax_entry,
- tar->pax_entry_length * sizeof(wchar_t));
- if (tar->pax_entry == NULL) {
- free(old_entry);
- /* TODO: Handle this error. */
- return (NULL);
- }
- }
-
- dest = tar->pax_entry;
- while (length > 0) {
- n = UTF8_mbrtowc(dest, src, length);
- if (n < 0)
- return (NULL);
- if (n == 0)
- break;
- dest++;
- src += n;
- length -= n;
- }
- *dest = L'\0';
- return (tar->pax_entry);
-}
-
-/*
- * Copied and simplified from FreeBSD libc/locale.
- */
-static ssize_t
-UTF8_mbrtowc(wchar_t *pwc, const char *s, size_t n)
-{
- int ch, i, len, mask;
- unsigned long wch;
-
- if (s == NULL || n == 0 || pwc == NULL)
- return (0);
-
- /*
- * Determine the number of octets that make up this character from
- * the first octet, and a mask that extracts the interesting bits of
- * the first octet.
- */
- ch = (unsigned char)*s;
- if ((ch & 0x80) == 0) {
- mask = 0x7f;
- len = 1;
- } else if ((ch & 0xe0) == 0xc0) {
- mask = 0x1f;
- len = 2;
- } else if ((ch & 0xf0) == 0xe0) {
- mask = 0x0f;
- len = 3;
- } else if ((ch & 0xf8) == 0xf0) {
- mask = 0x07;
- len = 4;
- } else {
- /* Invalid first byte. */
- return (-1);
- }
-
- if (n < (size_t)len) {
- /* Valid first byte but truncated. */
- return (-2);
- }
-
- /*
- * Decode the octet sequence representing the character in chunks
- * of 6 bits, most significant first.
- */
- wch = (unsigned char)*s++ & mask;
- i = len;
- while (--i != 0) {
- if ((*s & 0xc0) != 0x80) {
- /* Invalid intermediate byte; consume one byte and
- * emit '?' */
- *pwc = '?';
- return (1);
- }
- wch <<= 6;
- wch |= *s++ & 0x3f;
- }
-
- /* Assign the value to the output; out-of-range values
- * just get truncated. */
- *pwc = (wchar_t)wch;
-#ifdef WCHAR_MAX
- /*
- * If platform has WCHAR_MAX, we can do something
- * more sensible with out-of-range values.
- */
- if (wch >= WCHAR_MAX)
- *pwc = '?';
-#endif
- /* Return number of bytes input consumed: 0 for end-of-string. */
- return (wch == L'\0' ? 0 : len);
-}
-
-
/*
* base64_decode - Base64 decode
*
diff --git a/libarchive/archive_read_support_format_xar.c b/libarchive/archive_read_support_format_xar.c
index e6ce6b516b09..3c01cbe4362b 100644
--- a/libarchive/archive_read_support_format_xar.c
+++ b/libarchive/archive_read_support_format_xar.c
@@ -28,7 +28,6 @@ __FBSDID("$FreeBSD$");
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
-#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
@@ -52,9 +51,10 @@ __FBSDID("$FreeBSD$");
#endif
#include "archive.h"
+#include "archive_crypto_private.h"
#include "archive_endian.h"
#include "archive_entry.h"
-#include "archive_hash.h"
+#include "archive_entry_locale.h"
#include "archive_private.h"
#include "archive_read_private.h"
@@ -74,6 +74,8 @@ int
archive_read_support_format_xar(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_xar");
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Xar not supported on this platform");
@@ -82,8 +84,8 @@ archive_read_support_format_xar(struct archive *_a)
#else /* Support xar format */
-//#define DEBUG 1
-//#define DEBUG_PRINT_TOC 1
+/* #define DEBUG 1 */
+/* #define DEBUG_PRINT_TOC 1 */
#if DEBUG_PRINT_TOC
#define PRINT_TOC(d, outbytes) do { \
unsigned char *x = (unsigned char *)(uintptr_t)d; \
@@ -303,7 +305,8 @@ struct xar {
int64_t total;
uint64_t h_base;
int end_of_file;
- unsigned char buff[1024*32];
+#define OUTBUFF_SIZE (1024 * 64)
+ unsigned char *outbuff;
enum xmlstatus xmlsts;
enum xmlstatus xmlsts_unknown;
@@ -350,10 +353,13 @@ struct xar {
int entry_init;
uint64_t entry_total;
uint64_t entry_remaining;
+ size_t entry_unconsumed;
uint64_t entry_size;
enum enctype entry_encoding;
struct chksumval entry_a_sum;
struct chksumval entry_e_sum;
+
+ struct archive_string_conv *sconv;
};
struct xmlattr {
@@ -367,11 +373,11 @@ struct xmlattr_list {
struct xmlattr **last;
};
-static int xar_bid(struct archive_read *);
+static int xar_bid(struct archive_read *, int);
static int xar_read_header(struct archive_read *,
struct archive_entry *);
static int xar_read_data(struct archive_read *,
- const void **, size_t *, off_t *);
+ const void **, size_t *, int64_t *);
static int xar_read_data_skip(struct archive_read *);
static int xar_cleanup(struct archive_read *);
static int move_reading_point(struct archive_read *, uint64_t);
@@ -383,9 +389,11 @@ static uint64_t atol10(const char *, size_t);
static int64_t atol8(const char *, size_t);
static size_t atohex(unsigned char *, size_t, const char *, size_t);
static time_t parse_time(const char *p, size_t n);
-static void heap_add_entry(struct heap_queue *, struct xar_file *);
+static int heap_add_entry(struct archive_read *a,
+ struct heap_queue *, struct xar_file *);
static struct xar_file *heap_get_entry(struct heap_queue *);
-static void add_link(struct xar *, struct xar_file *);
+static int add_link(struct archive_read *,
+ struct xar *, struct xar_file *);
static void checksum_init(struct archive_read *, int, int);
static void checksum_update(struct archive_read *, const void *,
size_t, const void *, size_t);
@@ -396,28 +404,38 @@ static int decompress(struct archive_read *, const void **,
size_t *, const void *, size_t *);
static int decompression_cleanup(struct archive_read *);
static void xmlattr_cleanup(struct xmlattr_list *);
-static void file_new(struct xar *, struct xmlattr_list *);
+static int file_new(struct archive_read *,
+ struct xar *, struct xmlattr_list *);
static void file_free(struct xar_file *);
-static void xattr_new(struct xar *, struct xmlattr_list *);
+static int xattr_new(struct archive_read *,
+ struct xar *, struct xmlattr_list *);
static void xattr_free(struct xattr *);
static int getencoding(struct xmlattr_list *);
static int getsumalgorithm(struct xmlattr_list *);
-static void unknowntag_start(struct xar *, const char *);
+static int unknowntag_start(struct archive_read *,
+ struct xar *, const char *);
static void unknowntag_end(struct xar *, const char *);
-static void xml_start(void *, const char *, struct xmlattr_list *);
+static int xml_start(struct archive_read *,
+ const char *, struct xmlattr_list *);
static void xml_end(void *, const char *);
static void xml_data(void *, const char *, int);
static int xml_parse_file_flags(struct xar *, const char *);
static int xml_parse_file_ext2(struct xar *, const char *);
#if defined(HAVE_LIBXML_XMLREADER_H)
-static int xml2_xmlattr_setup(struct xmlattr_list *, xmlTextReaderPtr);
+static int xml2_xmlattr_setup(struct archive_read *,
+ struct xmlattr_list *, xmlTextReaderPtr);
static int xml2_read_cb(void *, char *, int);
static int xml2_close_cb(void *);
static void xml2_error_hdr(void *, const char *, xmlParserSeverities,
xmlTextReaderLocatorPtr);
static int xml2_read_toc(struct archive_read *);
#elif defined(HAVE_BSDXML_H) || defined(HAVE_EXPAT_H)
-static void expat_xmlattr_setup(struct xmlattr_list *, const XML_Char **);
+struct expat_userData {
+ int state;
+ struct archive_read *archive;
+};
+static int expat_xmlattr_setup(struct archive_read *,
+ struct xmlattr_list *, const XML_Char **);
static void expat_start_cb(void *, const XML_Char *, const XML_Char **);
static void expat_end_cb(void *, const XML_Char *);
static void expat_data_cb(void *, const XML_Char *, int);
@@ -431,6 +449,9 @@ archive_read_support_format_xar(struct archive *_a)
struct archive_read *a = (struct archive_read *)_a;
int r;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_xar");
+
xar = (struct xar *)calloc(1, sizeof(*xar));
if (xar == NULL) {
archive_set_error(&a->archive, ENOMEM,
@@ -453,11 +474,13 @@ archive_read_support_format_xar(struct archive *_a)
}
static int
-xar_bid(struct archive_read *a)
+xar_bid(struct archive_read *a, int best_bid)
{
const unsigned char *b;
int bid;
+ (void)best_bid; /* UNUSED */
+
b = __archive_read_ahead(a, HEADER_SIZE, NULL);
if (b == NULL)
return (-1);
@@ -638,8 +661,17 @@ xar_read_header(struct archive_read *a, struct archive_entry *entry)
int r;
xar = (struct xar *)(a->format->data);
+ r = ARCHIVE_OK;
if (xar->offset == 0) {
+ /* Create a character conversion object. */
+ if (xar->sconv == NULL) {
+ xar->sconv = archive_string_conversion_from_charset(
+ &(a->archive), "UTF-8", 1);
+ if (xar->sconv == NULL)
+ return (ARCHIVE_FATAL);
+ }
+
/* Read TOC. */
r = read_toc(a);
if (r != ARCHIVE_OK)
@@ -666,15 +698,65 @@ xar_read_header(struct archive_read *a, struct archive_entry *entry)
archive_entry_set_ctime(entry, file->ctime, 0);
archive_entry_set_mtime(entry, file->mtime, 0);
archive_entry_set_gid(entry, file->gid);
- if (file->gname.length > 0)
- archive_entry_update_gname_utf8(entry, file->gname.s);
+ if (file->gname.length > 0 &&
+ archive_entry_copy_gname_l(entry, file->gname.s,
+ archive_strlen(&(file->gname)), xar->sconv) != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Gname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Gname cannot be converted from %s to current locale.",
+ archive_string_conversion_charset_name(xar->sconv));
+ r = ARCHIVE_WARN;
+ }
archive_entry_set_uid(entry, file->uid);
- if (file->uname.length > 0)
- archive_entry_update_uname_utf8(entry, file->uname.s);
+ if (file->uname.length > 0 &&
+ archive_entry_copy_uname_l(entry, file->uname.s,
+ archive_strlen(&(file->uname)), xar->sconv) != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Uname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Uname cannot be converted from %s to current locale.",
+ archive_string_conversion_charset_name(xar->sconv));
+ r = ARCHIVE_WARN;
+ }
archive_entry_set_mode(entry, file->mode);
- archive_entry_update_pathname_utf8(entry, file->pathname.s);
- if (file->symlink.length > 0)
- archive_entry_update_symlink_utf8(entry, file->symlink.s);
+ if (archive_entry_copy_pathname_l(entry, file->pathname.s,
+ archive_strlen(&(file->pathname)), xar->sconv) != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Pathname cannot be converted from %s to current locale.",
+ archive_string_conversion_charset_name(xar->sconv));
+ r = ARCHIVE_WARN;
+ }
+
+
+ if (file->symlink.length > 0 &&
+ archive_entry_copy_symlink_l(entry, file->symlink.s,
+ archive_strlen(&(file->symlink)), xar->sconv) != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Linkname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Linkname cannot be converted from %s to current locale.",
+ archive_string_conversion_charset_name(xar->sconv));
+ r = ARCHIVE_WARN;
+ }
/* Set proper nlink. */
if ((file->mode & AE_IFMT) == AE_IFDIR)
archive_entry_set_nlink(entry, file->subdirs + 2);
@@ -682,8 +764,7 @@ xar_read_header(struct archive_read *a, struct archive_entry *entry)
archive_entry_set_nlink(entry, file->nlink);
archive_entry_set_size(entry, file->size);
if (archive_strlen(&(file->hardlink)) > 0)
- archive_entry_update_hardlink_utf8(entry,
- file->hardlink.s);
+ archive_entry_set_hardlink(entry, file->hardlink.s);
archive_entry_set_ino64(entry, file->ino64);
if (file->has & HAS_DEV)
archive_entry_set_dev(entry, file->dev);
@@ -704,7 +785,6 @@ xar_read_header(struct archive_read *a, struct archive_entry *entry)
/*
* Read extended attributes.
*/
- r = ARCHIVE_OK;
xattr = file->xattr_list;
while (xattr != NULL) {
const void *d;
@@ -754,13 +834,19 @@ xar_read_header(struct archive_read *a, struct archive_entry *entry)
static int
xar_read_data(struct archive_read *a,
- const void **buff, size_t *size, off_t *offset)
+ const void **buff, size_t *size, int64_t *offset)
{
struct xar *xar;
size_t used;
int r;
xar = (struct xar *)(a->format->data);
+
+ if (xar->entry_unconsumed) {
+ __archive_read_consume(a, xar->entry_unconsumed);
+ xar->entry_unconsumed = 0;
+ }
+
if (xar->end_of_file || xar->entry_remaining <= 0) {
r = ARCHIVE_EOF;
goto abort_read_data;
@@ -786,7 +872,7 @@ xar_read_data(struct archive_read *a,
xar->total += *size;
xar->offset += used;
xar->entry_remaining -= used;
- __archive_read_consume(a, used);
+ xar->entry_unconsumed = used;
if (xar->entry_remaining == 0) {
if (xar->entry_total != xar->entry_size) {
@@ -819,10 +905,12 @@ xar_read_data_skip(struct archive_read *a)
xar = (struct xar *)(a->format->data);
if (xar->end_of_file)
return (ARCHIVE_EOF);
- bytes_skipped = __archive_read_skip(a, xar->entry_remaining);
+ bytes_skipped = __archive_read_consume(a, xar->entry_remaining +
+ xar->entry_unconsumed);
if (bytes_skipped < 0)
return (ARCHIVE_FATAL);
xar->offset += bytes_skipped;
+ xar->entry_unconsumed = 0;
return (ARCHIVE_OK);
}
@@ -853,6 +941,7 @@ xar_cleanup(struct archive_read *a)
archive_string_free(&(tag->name));
free(tag);
}
+ free(xar->outbuff);
free(xar);
a->format->data = NULL;
return (r);
@@ -870,7 +959,7 @@ move_reading_point(struct archive_read *a, uint64_t offset)
step = offset - (xar->offset - xar->h_base);
if (step > 0) {
- step = __archive_read_skip(a, step);
+ step = __archive_read_consume(a, step);
if (step < 0)
return ((int)step);
xar->offset += step;
@@ -1011,6 +1100,8 @@ time_from_tm(struct tm *t)
#if HAVE_TIMEGM
/* Use platform timegm() if available. */
return (timegm(t));
+#elif HAVE__MKGMTIME64
+ return (_mkgmtime64(t));
#else
/* Else use direct calculation using POSIX assumptions. */
/* First, fix up tm_yday based on the year/month/day. */
@@ -1084,8 +1175,9 @@ parse_time(const char *p, size_t n)
return (t);
}
-static void
-heap_add_entry(struct heap_queue *heap, struct xar_file *file)
+static int
+heap_add_entry(struct archive_read *a,
+ struct heap_queue *heap, struct xar_file *file)
{
uint64_t file_id, parent_id;
int hole, parent;
@@ -1098,12 +1190,18 @@ heap_add_entry(struct heap_queue *heap, struct xar_file *file)
if (heap->allocated < 1024)
new_size = 1024;
/* Overflow might keep us from growing the list. */
- if (new_size <= heap->allocated)
- __archive_errx(1, "Out of memory");
+ if (new_size <= heap->allocated) {
+ archive_set_error(&a->archive,
+ ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
new_pending_files = (struct xar_file **)
malloc(new_size * sizeof(new_pending_files[0]));
- if (new_pending_files == NULL)
- __archive_errx(1, "Out of memory");
+ if (new_pending_files == NULL) {
+ archive_set_error(&a->archive,
+ ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
memcpy(new_pending_files, heap->files,
heap->allocated * sizeof(new_pending_files[0]));
if (heap->files != NULL)
@@ -1123,13 +1221,15 @@ heap_add_entry(struct heap_queue *heap, struct xar_file *file)
parent_id = heap->files[parent]->id;
if (file_id >= parent_id) {
heap->files[hole] = file;
- return;
+ return (ARCHIVE_OK);
}
- // Move parent into hole <==> move hole up tree.
+ /* Move parent into hole <==> move hole up tree. */
heap->files[hole] = heap->files[parent];
hole = parent;
}
heap->files[0] = file;
+
+ return (ARCHIVE_OK);
}
static struct xar_file *
@@ -1155,14 +1255,14 @@ heap_get_entry(struct heap_queue *heap)
/*
* Rebalance the heap.
*/
- a = 0; // Starting element and its heap key
+ a = 0; /* Starting element and its heap key */
a_id = heap->files[a]->id;
for (;;) {
- b = a + a + 1; // First child
+ b = a + a + 1; /* First child */
if (b >= heap->used)
return (r);
b_id = heap->files[b]->id;
- c = b + 1; // Use second child if it is smaller.
+ c = b + 1; /* Use second child if it is smaller. */
if (c < heap->used) {
c_id = heap->files[c]->id;
if (c_id < b_id) {
@@ -1179,8 +1279,8 @@ heap_get_entry(struct heap_queue *heap)
}
}
-static void
-add_link(struct xar *xar, struct xar_file *file)
+static int
+add_link(struct archive_read *a, struct xar *xar, struct xar_file *file)
{
struct hdlink *hdlink;
@@ -1189,18 +1289,21 @@ add_link(struct xar *xar, struct xar_file *file)
file->hdnext = hdlink->files;
hdlink->cnt++;
hdlink->files = file;
- return;
+ return (ARCHIVE_OK);
}
}
hdlink = malloc(sizeof(*hdlink));
- if (hdlink == NULL)
- __archive_errx(1, "No memory for add_link()");
+ if (hdlink == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
file->hdnext = NULL;
hdlink->id = file->link;
hdlink->cnt = 1;
hdlink->files = file;
hdlink->next = xar->hdlink_list;
xar->hdlink_list = hdlink;
+ return (ARCHIVE_OK);
}
static void
@@ -1362,6 +1465,13 @@ decompression_init(struct archive_read *a, enum enctype encoding)
break;
#endif
#if defined(HAVE_LZMA_H) && defined(HAVE_LIBLZMA)
+#if LZMA_VERSION_MAJOR >= 5
+/* Effectively disable the limiter. */
+#define LZMA_MEMLIMIT UINT64_MAX
+#else
+/* NOTE: This needs to check memory size which running system has. */
+#define LZMA_MEMLIMIT (1U << 30)
+#endif
case XZ:
case LZMA:
if (xar->lzstream_valid) {
@@ -1370,11 +1480,11 @@ decompression_init(struct archive_read *a, enum enctype encoding)
}
if (xar->entry_encoding == XZ)
r = lzma_stream_decoder(&(xar->lzstream),
- (1U << 30),/* memlimit */
+ LZMA_MEMLIMIT,/* memlimit */
LZMA_CONCATENATED);
else
r = lzma_alone_decoder(&(xar->lzstream),
- (1U << 30));/* memlimit */
+ LZMA_MEMLIMIT);/* memlimit */
if (r != LZMA_OK) {
switch (r) {
case LZMA_MEM_ERROR:
@@ -1473,9 +1583,17 @@ decompress(struct archive_read *a, const void **buff, size_t *outbytes,
avail_in = *used;
outbuff = (void *)(uintptr_t)*buff;
if (outbuff == NULL) {
- outbuff = xar->buff;
+ if (xar->outbuff == NULL) {
+ xar->outbuff = malloc(OUTBUFF_SIZE);
+ if (xar->outbuff == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Couldn't allocate memory for out buffer");
+ return (ARCHIVE_FATAL);
+ }
+ }
+ outbuff = xar->outbuff;
*buff = outbuff;
- avail_out = sizeof(xar->buff);
+ avail_out = OUTBUFF_SIZE;
} else
avail_out = *outbytes;
switch (xar->rd_encoding) {
@@ -1599,7 +1717,7 @@ decompress(struct archive_read *a, const void **buff, size_t *outbytes,
#endif
case NONE:
default:
- if (outbuff == xar->buff) {
+ if (outbuff == xar->outbuff) {
*buff = b;
*used = avail_in;
*outbytes = avail_in;
@@ -1674,15 +1792,17 @@ xmlattr_cleanup(struct xmlattr_list *list)
list->last = &(list->first);
}
-static void
-file_new(struct xar *xar, struct xmlattr_list *list)
+static int
+file_new(struct archive_read *a, struct xar *xar, struct xmlattr_list *list)
{
struct xar_file *file;
struct xmlattr *attr;
file = calloc(1, sizeof(*file));
- if (file == NULL)
- __archive_errx(1, "Out of memory");
+ if (file == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
file->parent = xar->file;
file->mode = 0777 | AE_IFREG;
file->atime = time(NULL);
@@ -1694,7 +1814,9 @@ file_new(struct xar *xar, struct xmlattr_list *list)
file->id = atol10(attr->value, strlen(attr->value));
}
file->nlink = 1;
- heap_add_entry(&(xar->file_queue), file);
+ if (heap_add_entry(a, &(xar->file_queue), file) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ return (ARCHIVE_OK);
}
static void
@@ -1719,15 +1841,17 @@ file_free(struct xar_file *file)
free(file);
}
-static void
-xattr_new(struct xar *xar, struct xmlattr_list *list)
+static int
+xattr_new(struct archive_read *a, struct xar *xar, struct xmlattr_list *list)
{
struct xattr *xattr, **nx;
struct xmlattr *attr;
xattr = calloc(1, sizeof(*xattr));
- if (xattr == NULL)
- __archive_errx(1, "Out of memory");
+ if (xattr == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
xar->xattr = xattr;
for (attr = list->first; attr != NULL; attr = attr->next) {
if (strcmp(attr->name, "id") == 0)
@@ -1741,6 +1865,8 @@ xattr_new(struct xar *xar, struct xmlattr_list *list)
}
xattr->next = *nx;
*nx = xattr;
+
+ return (ARCHIVE_OK);
}
static void
@@ -1796,8 +1922,8 @@ getsumalgorithm(struct xmlattr_list *list)
return (alg);
}
-static void
-unknowntag_start(struct xar *xar, const char *name)
+static int
+unknowntag_start(struct archive_read *a, struct xar *xar, const char *name)
{
struct unknown_tag *tag;
@@ -1805,8 +1931,10 @@ unknowntag_start(struct xar *xar, const char *name)
fprintf(stderr, "unknowntag_start:%s\n", name);
#endif
tag = malloc(sizeof(*tag));
- if (tag == NULL)
- __archive_errx(1, "Out of memory");
+ if (tag == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
tag->next = xar->unknowntags;
archive_string_init(&(tag->name));
archive_strcpy(&(tag->name), name);
@@ -1815,6 +1943,7 @@ unknowntag_start(struct xar *xar, const char *name)
xar->xmlsts = UNKNOWN;
}
xar->unknowntags = tag;
+ return (ARCHIVE_OK);
}
static void
@@ -1837,14 +1966,12 @@ unknowntag_end(struct xar *xar, const char *name)
}
}
-static void
-xml_start(void *userData, const char *name, struct xmlattr_list *list)
+static int
+xml_start(struct archive_read *a, const char *name, struct xmlattr_list *list)
{
- struct archive_read *a;
struct xar *xar;
struct xmlattr *attr;
- a = (struct archive_read *)userData;
xar = (struct xar *)(a->format->data);
#if DEBUG
@@ -1859,13 +1986,15 @@ xml_start(void *userData, const char *name, struct xmlattr_list *list)
if (strcmp(name, "xar") == 0)
xar->xmlsts = XAR;
else
- unknowntag_start(xar, name);
+ if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
break;
case XAR:
if (strcmp(name, "toc") == 0)
xar->xmlsts = TOC;
else
- unknowntag_start(xar, name);
+ if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
break;
case TOC:
if (strcmp(name, "creation-time") == 0)
@@ -1873,11 +2002,13 @@ xml_start(void *userData, const char *name, struct xmlattr_list *list)
else if (strcmp(name, "checksum") == 0)
xar->xmlsts = TOC_CHECKSUM;
else if (strcmp(name, "file") == 0) {
- file_new(xar, list);
+ if (file_new(a, xar, list) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
xar->xmlsts = TOC_FILE;
}
else
- unknowntag_start(xar, name);
+ if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
break;
case TOC_CHECKSUM:
if (strcmp(name, "offset") == 0)
@@ -1885,16 +2016,19 @@ xml_start(void *userData, const char *name, struct xmlattr_list *list)
else if (strcmp(name, "size") == 0)
xar->xmlsts = TOC_CHECKSUM_SIZE;
else
- unknowntag_start(xar, name);
+ if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
break;
case TOC_FILE:
if (strcmp(name, "file") == 0) {
- file_new(xar, list);
+ if (file_new(a, xar, list) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
}
else if (strcmp(name, "data") == 0)
xar->xmlsts = FILE_DATA;
else if (strcmp(name, "ea") == 0) {
- xattr_new(xar, list);
+ if (xattr_new(a, xar, list) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
xar->xmlsts = FILE_EA;
}
else if (strcmp(name, "ctime") == 0)
@@ -1934,7 +2068,9 @@ xml_start(void *userData, const char *name, struct xmlattr_list *list)
xar->file->link = atol10(attr->value,
strlen(attr->value));
if (xar->file->link > 0)
- add_link(xar, xar->file);
+ if (add_link(a, xar, xar->file) != ARCHIVE_OK) {
+ return (ARCHIVE_FATAL);
+ };
}
}
}
@@ -1954,7 +2090,8 @@ xml_start(void *userData, const char *name, struct xmlattr_list *list)
else if (strcmp(name, "ext2") == 0)
xar->xmlsts = FILE_EXT2;
else
- unknowntag_start(xar, name);
+ if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
break;
case FILE_DATA:
if (strcmp(name, "length") == 0)
@@ -1978,7 +2115,8 @@ xml_start(void *userData, const char *name, struct xmlattr_list *list)
else if (strcmp(name, "content") == 0)
xar->xmlsts = FILE_DATA_CONTENT;
else
- unknowntag_start(xar, name);
+ if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
break;
case FILE_DEVICE:
if (strcmp(name, "major") == 0)
@@ -1986,10 +2124,12 @@ xml_start(void *userData, const char *name, struct xmlattr_list *list)
else if (strcmp(name, "minor") == 0)
xar->xmlsts = FILE_DEVICE_MINOR;
else
- unknowntag_start(xar, name);
+ if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
break;
case FILE_DATA_CONTENT:
- unknowntag_start(xar, name);
+ if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
break;
case FILE_EA:
if (strcmp(name, "length") == 0)
@@ -2010,7 +2150,8 @@ xml_start(void *userData, const char *name, struct xmlattr_list *list)
else if (strcmp(name, "fstype") == 0)
xar->xmlsts = FILE_EA_FSTYPE;
else
- unknowntag_start(xar, name);
+ if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
break;
case FILE_ACL:
if (strcmp(name, "appleextended") == 0)
@@ -2020,15 +2161,18 @@ xml_start(void *userData, const char *name, struct xmlattr_list *list)
else if (strcmp(name, "access") == 0)
xar->xmlsts = FILE_ACL_ACCESS;
else
- unknowntag_start(xar, name);
+ if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
break;
case FILE_FLAGS:
if (!xml_parse_file_flags(xar, name))
- unknowntag_start(xar, name);
+ if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
break;
case FILE_EXT2:
if (!xml_parse_file_ext2(xar, name))
- unknowntag_start(xar, name);
+ if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
break;
case TOC_CREATION_TIME:
case TOC_CHECKSUM_OFFSET:
@@ -2096,9 +2240,11 @@ xml_start(void *userData, const char *name, struct xmlattr_list *list)
case FILE_EXT2_TopDir:
case FILE_EXT2_Reserved:
case UNKNOWN:
- unknowntag_start(xar, name);
+ if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
break;
}
+ return (ARCHIVE_OK);
}
static void
@@ -2470,7 +2616,8 @@ static const int base64[256] = {
};
static void
-strappend_base64(struct archive_string *as, const char *s, size_t l)
+strappend_base64(struct xar *xar,
+ struct archive_string *as, const char *s, size_t l)
{
unsigned char buff[256];
unsigned char *out;
@@ -2558,9 +2705,10 @@ xml_data(void *userData, const char *s, int len)
archive_strappend_char(&(xar->file->pathname), '/');
}
xar->file->has |= HAS_PATHNAME;
- if (xar->base64text)
- strappend_base64(&(xar->file->pathname), s, len);
- else
+ if (xar->base64text) {
+ strappend_base64(xar,
+ &(xar->file->pathname), s, len);
+ } else
archive_strncat(&(xar->file->pathname), s, len);
break;
case FILE_LINK:
@@ -2909,7 +3057,8 @@ xml_parse_file_ext2(struct xar *xar, const char *name)
#ifdef HAVE_LIBXML_XMLREADER_H
static int
-xml2_xmlattr_setup(struct xmlattr_list *list, xmlTextReaderPtr reader)
+xml2_xmlattr_setup(struct archive_read *a,
+ struct xmlattr_list *list, xmlTextReaderPtr reader)
{
struct xmlattr *attr;
int r;
@@ -2919,16 +3068,22 @@ xml2_xmlattr_setup(struct xmlattr_list *list, xmlTextReaderPtr reader)
r = xmlTextReaderMoveToFirstAttribute(reader);
while (r == 1) {
attr = malloc(sizeof*(attr));
- if (attr == NULL)
- __archive_errx(1, "Out of memory");
+ if (attr == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
attr->name = strdup(
(const char *)xmlTextReaderConstLocalName(reader));
- if (attr->name == NULL)
- __archive_errx(1, "Out of memory");
+ if (attr->name == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
attr->value = strdup(
(const char *)xmlTextReaderConstValue(reader));
- if (attr->value == NULL)
- __archive_errx(1, "Out of memory");
+ if (attr->value == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
attr->next = NULL;
*list->last = attr;
list->last = &(attr->next);
@@ -3020,13 +3175,15 @@ xml2_read_toc(struct archive_read *a)
switch (type) {
case XML_READER_TYPE_ELEMENT:
empty = xmlTextReaderIsEmptyElement(reader);
- r = xml2_xmlattr_setup(&list, reader);
- if (r == 0) {
- xml_start(a, name, &list);
- xmlattr_cleanup(&list);
- if (empty)
- xml_end(a, name);
- }
+ r = xml2_xmlattr_setup(a, &list, reader);
+ if (r != ARCHIVE_OK)
+ return (r);
+ r = xml_start(a, name, &list);
+ xmlattr_cleanup(&list);
+ if (r != ARCHIVE_OK)
+ return (r);
+ if (empty)
+ xml_end(a, name);
break;
case XML_READER_TYPE_END_ELEMENT:
xml_end(a, name);
@@ -3050,52 +3207,64 @@ xml2_read_toc(struct archive_read *a)
#elif defined(HAVE_BSDXML_H) || defined(HAVE_EXPAT_H)
-static void
-expat_xmlattr_setup(struct xmlattr_list *list, const XML_Char **atts)
+static int
+expat_xmlattr_setup(struct archive_read *a,
+ struct xmlattr_list *list, const XML_Char **atts)
{
struct xmlattr *attr;
+ char *name, *value;
list->first = NULL;
list->last = &(list->first);
if (atts == NULL)
- return;
+ return (ARCHIVE_OK);
while (atts[0] != NULL && atts[1] != NULL) {
attr = malloc(sizeof*(attr));
- if (attr == NULL)
- __archive_errx(1, "Out of memory");
- attr->name = strdup(atts[0]);
- if (attr->name == NULL)
- __archive_errx(1, "Out of memory");
- attr->value = strdup(atts[1]);
- if (attr->value == NULL)
- __archive_errx(1, "Out of memory");
+ name = strdup(atts[0]);
+ value = strdup(atts[1]);
+ if (attr == NULL || name == NULL || value == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+ attr->name = name;
+ attr->value = value;
attr->next = NULL;
*list->last = attr;
list->last = &(attr->next);
atts += 2;
}
+ return (ARCHIVE_OK);
}
static void
expat_start_cb(void *userData, const XML_Char *name, const XML_Char **atts)
{
+ struct expat_userData *ud = (struct expat_userData *)userData;
+ struct archive_read *a = ud->archive;
struct xmlattr_list list;
+ int r;
- expat_xmlattr_setup(&list, atts);
- xml_start(userData, (const char *)name, &list);
+ r = expat_xmlattr_setup(a, &list, atts);
+ if (r == ARCHIVE_OK)
+ r = xml_start(a, (const char *)name, &list);
xmlattr_cleanup(&list);
+ ud->state = r;
}
static void
expat_end_cb(void *userData, const XML_Char *name)
{
- xml_end(userData, (const char *)name);
+ struct expat_userData *ud = (struct expat_userData *)userData;
+
+ xml_end(ud->archive, (const char *)name);
}
static void
expat_data_cb(void *userData, const XML_Char *s, int len)
{
- xml_data(userData, s, len);
+ struct expat_userData *ud = (struct expat_userData *)userData;
+
+ xml_data(ud->archive, s, len);
}
static int
@@ -3103,6 +3272,10 @@ expat_read_toc(struct archive_read *a)
{
struct xar *xar;
XML_Parser parser;
+ struct expat_userData ud;
+
+ ud.state = ARCHIVE_OK;
+ ud.archive = a;
xar = (struct xar *)(a->format->data);
@@ -3113,12 +3286,12 @@ expat_read_toc(struct archive_read *a)
"Couldn't allocate memory for xml parser");
return (ARCHIVE_FATAL);
}
- XML_SetUserData(parser, a);
+ XML_SetUserData(parser, &ud);
XML_SetElementHandler(parser, expat_start_cb, expat_end_cb);
XML_SetCharacterDataHandler(parser, expat_data_cb);
xar->xmlsts = INIT;
- while (xar->toc_remaining) {
+ while (xar->toc_remaining && ud.state == ARCHIVE_OK) {
enum XML_Status xr;
const void *d;
size_t outbytes;
@@ -3129,13 +3302,13 @@ expat_read_toc(struct archive_read *a)
r = rd_contents(a, &d, &outbytes, &used, xar->toc_remaining);
if (r != ARCHIVE_OK)
return (r);
- __archive_read_consume(a, used);
xar->toc_remaining -= used;
xar->offset += used;
xar->toc_total += outbytes;
PRINT_TOC(d, outbytes);
xr = XML_Parse(parser, d, outbytes, xar->toc_remaining == 0);
+ __archive_read_consume(a, used);
if (xr == XML_STATUS_ERROR) {
XML_ParserFree(parser);
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
@@ -3144,7 +3317,7 @@ expat_read_toc(struct archive_read *a)
}
}
XML_ParserFree(parser);
- return (ARCHIVE_OK);
+ return (ud.state);
}
#endif /* defined(HAVE_BSDXML_H) || defined(HAVE_EXPAT_H) */
diff --git a/libarchive/archive_read_support_format_zip.c b/libarchive/archive_read_support_format_zip.c
index 572cc58549ec..f805855fa7ad 100644
--- a/libarchive/archive_read_support_format_zip.c
+++ b/libarchive/archive_read_support_format_zip.c
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2004 Tim Kientzle
+ * Copyright (c) 2011 Michihiro NAKAJIMA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -29,17 +30,16 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_zip.c 201102
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
-#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
-#include <time.h>
#ifdef HAVE_ZLIB_H
#include <zlib.h>
#endif
#include "archive.h"
#include "archive_entry.h"
+#include "archive_entry_locale.h"
#include "archive_private.h"
#include "archive_read_private.h"
#include "archive_endian.h"
@@ -48,10 +48,39 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_zip.c 201102
#include "archive_crc32.h"
#endif
+struct zip_entry {
+ int64_t local_header_offset;
+ int64_t compressed_size;
+ int64_t uncompressed_size;
+ int64_t gid;
+ int64_t uid;
+ struct archive_entry *entry;
+ time_t mtime;
+ time_t atime;
+ time_t ctime;
+ uint32_t crc32;
+ uint16_t mode;
+ uint16_t flags;
+ char compression;
+ char system;
+};
+
struct zip {
+ /* Structural information about the archive. */
+ int64_t central_directory_offset;
+ size_t central_directory_size;
+ size_t central_directory_entries;
+ char have_central_directory;
+
+ /* List of entries (seekable Zip only) */
+ size_t entries_remaining;
+ struct zip_entry *zip_entries;
+ struct zip_entry *entry;
+
+ size_t unconsumed;
+
/* entry_bytes_remaining is the number of bytes we expect. */
int64_t entry_bytes_remaining;
- int64_t entry_offset;
/* These count the number of bytes actually read for the entry. */
int64_t entry_compressed_bytes_read;
@@ -60,27 +89,12 @@ struct zip {
/* Running CRC32 of the decompressed data */
unsigned long entry_crc32;
- unsigned version;
- unsigned system;
- unsigned flags;
- unsigned compression;
- const char * compression_name;
- time_t mtime;
- time_t ctime;
- time_t atime;
- mode_t mode;
- uid_t uid;
- gid_t gid;
-
/* Flags to mark progress of decompression. */
char decompress_init;
char end_of_entry;
- unsigned long crc32;
ssize_t filename_length;
ssize_t extra_length;
- int64_t uncompressed_size;
- int64_t compressed_size;
unsigned char *uncompressed_buffer;
size_t uncompressed_buffer_size;
@@ -89,65 +103,90 @@ struct zip {
char stream_valid;
#endif
- struct archive_string pathname;
struct archive_string extra;
+ struct archive_string_conv *sconv;
+ struct archive_string_conv *sconv_default;
+ struct archive_string_conv *sconv_utf8;
+ int init_default_conversion;
char format_name[64];
};
#define ZIP_LENGTH_AT_END 8
-
-struct zip_file_header {
- char signature[4];
- char version[2];
- char flags[2];
- char compression[2];
- char timedate[4];
- char crc32[4];
- char compressed_size[4];
- char uncompressed_size[4];
- char filename_length[2];
- char extra_length[2];
-};
-
-static const char *compression_names[] = {
- "uncompressed",
- "shrinking",
- "reduced-1",
- "reduced-2",
- "reduced-3",
- "reduced-4",
- "imploded",
- "reserved",
- "deflation"
-};
-
-static int archive_read_format_zip_bid(struct archive_read *);
+#define ZIP_ENCRYPTED (1<<0)
+#define ZIP_STRONG_ENCRYPTED (1<<6)
+#define ZIP_UTF8_NAME (1<<11)
+
+static int archive_read_format_zip_streamable_bid(struct archive_read *, int);
+static int archive_read_format_zip_seekable_bid(struct archive_read *, int);
+static int archive_read_format_zip_options(struct archive_read *,
+ const char *, const char *);
static int archive_read_format_zip_cleanup(struct archive_read *);
static int archive_read_format_zip_read_data(struct archive_read *,
- const void **, size_t *, off_t *);
+ const void **, size_t *, int64_t *);
static int archive_read_format_zip_read_data_skip(struct archive_read *a);
-static int archive_read_format_zip_read_header(struct archive_read *,
+static int archive_read_format_zip_seekable_read_header(struct archive_read *,
+ struct archive_entry *);
+static int archive_read_format_zip_streamable_read_header(struct archive_read *,
struct archive_entry *);
-static int search_next_signature(struct archive_read *);
+#ifdef HAVE_ZLIB_H
static int zip_read_data_deflate(struct archive_read *a, const void **buff,
- size_t *size, off_t *offset);
+ size_t *size, int64_t *offset);
+#endif
static int zip_read_data_none(struct archive_read *a, const void **buff,
- size_t *size, off_t *offset);
-static int zip_read_file_header(struct archive_read *a,
- struct archive_entry *entry, struct zip *zip);
+ size_t *size, int64_t *offset);
+static int zip_read_local_file_header(struct archive_read *a,
+ struct archive_entry *entry, struct zip *);
static time_t zip_time(const char *);
-static void process_extra(const void* extra, struct zip* zip);
+static const char *compression_name(int compression);
+static void process_extra(const char *, size_t, struct zip_entry *);
+
+int
+archive_read_support_format_zip_streamable(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct zip *zip;
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_zip");
+
+ zip = (struct zip *)malloc(sizeof(*zip));
+ if (zip == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate zip data");
+ return (ARCHIVE_FATAL);
+ }
+ memset(zip, 0, sizeof(*zip));
+
+ r = __archive_read_register_format(a,
+ zip,
+ "zip",
+ archive_read_format_zip_streamable_bid,
+ archive_read_format_zip_options,
+ archive_read_format_zip_streamable_read_header,
+ archive_read_format_zip_read_data,
+ archive_read_format_zip_read_data_skip,
+ archive_read_format_zip_cleanup);
+
+ if (r != ARCHIVE_OK)
+ free(zip);
+ return (ARCHIVE_OK);
+}
int
-archive_read_support_format_zip(struct archive *_a)
+archive_read_support_format_zip_seekable(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
struct zip *zip;
int r;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_zip_seekable");
+
zip = (struct zip *)malloc(sizeof(*zip));
if (zip == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Can't allocate zip data");
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate zip data");
return (ARCHIVE_FATAL);
}
memset(zip, 0, sizeof(*zip));
@@ -155,9 +194,9 @@ archive_read_support_format_zip(struct archive *_a)
r = __archive_read_register_format(a,
zip,
"zip",
- archive_read_format_zip_bid,
- NULL,
- archive_read_format_zip_read_header,
+ archive_read_format_zip_seekable_bid,
+ archive_read_format_zip_options,
+ archive_read_format_zip_seekable_read_header,
archive_read_format_zip_read_data,
archive_read_format_zip_read_data_skip,
archive_read_format_zip_cleanup);
@@ -167,13 +206,201 @@ archive_read_support_format_zip(struct archive *_a)
return (ARCHIVE_OK);
}
+int
+archive_read_support_format_zip(struct archive *a)
+{
+ int r;
+ r = archive_read_support_format_zip_streamable(a);
+ if (r != ARCHIVE_OK)
+ return r;
+ return (archive_read_support_format_zip_seekable(a));
+}
+/*
+ * TODO: This is a performance sink because it forces the read core to
+ * drop buffered data from the start of file, which will then have to
+ * be re-read again if this bidder loses.
+ *
+ * We workaround this a little by passing in the best bid so far so
+ * that later bidders can do nothing if they know they'll never
+ * outbid. But we can certainly do better...
+ */
static int
-archive_read_format_zip_bid(struct archive_read *a)
+archive_read_format_zip_seekable_bid(struct archive_read *a, int best_bid)
{
+ struct zip *zip = (struct zip *)a->format->data;
+ int64_t filesize;
const char *p;
- const void *buff;
- ssize_t bytes_avail, offset;
+
+ /* If someone has already bid more than 32, then avoid
+ trashing the look-ahead buffers with a seek. */
+ if (best_bid > 32)
+ return (-1);
+
+ filesize = __archive_read_seek(a, -22, SEEK_END);
+ /* If we can't seek, then we can't bid. */
+ if (filesize <= 0)
+ return 0;
+
+ /* TODO: More robust search for end of central directory record. */
+ if ((p = __archive_read_ahead(a, 22, NULL)) == NULL)
+ return 0;
+ /* First four bytes are signature for end of central directory
+ record. Four zero bytes ensure this isn't a multi-volume
+ Zip file (which we don't yet support). */
+ if (memcmp(p, "PK\005\006\000\000\000\000", 8) != 0)
+ return 0;
+
+ /* Since we've already done the hard work of finding the
+ end of central directory record, let's save the important
+ information. */
+ zip->central_directory_entries = archive_le16dec(p + 10);
+ zip->central_directory_size = archive_le32dec(p + 12);
+ zip->central_directory_offset = archive_le32dec(p + 16);
+
+ /* Just one volume, so central dir must all be on this volume. */
+ if (zip->central_directory_entries != archive_le16dec(p + 8))
+ return 0;
+ /* Central directory can't extend beyond end of this file. */
+ if (zip->central_directory_offset + zip->central_directory_size > filesize)
+ return 0;
+
+ /* This is just a tiny bit higher than the maximum returned by
+ the streaming Zip bidder. This ensures that the more accurate
+ seeking Zip parser wins whenever seek is available. */
+ return 32;
+}
+
+static int
+slurp_central_directory(struct archive_read *a, struct zip *zip)
+{
+ unsigned i;
+
+ __archive_read_seek(a, zip->central_directory_offset, SEEK_SET);
+
+ zip->zip_entries = calloc(zip->central_directory_entries, sizeof(struct zip_entry));
+ for (i = 0; i < zip->central_directory_entries; ++i) {
+ struct zip_entry *zip_entry = &zip->zip_entries[i];
+ size_t filename_length, extra_length, comment_length;
+ uint32_t external_attributes;
+ const char *p;
+
+ if ((p = __archive_read_ahead(a, 46, NULL)) == NULL)
+ return ARCHIVE_FATAL;
+ if (memcmp(p, "PK\001\002", 4) != 0) {
+ archive_set_error(&a->archive,
+ -1, "Invalid central directory signature");
+ return ARCHIVE_FATAL;
+ }
+ zip->have_central_directory = 1;
+ /* version = p[4]; */
+ zip_entry->system = p[5];
+ /* version_required = archive_le16dec(p + 6); */
+ zip_entry->flags = archive_le16dec(p + 8);
+ zip_entry->compression = archive_le16dec(p + 10);
+ zip_entry->mtime = zip_time(p + 12);
+ zip_entry->crc32 = archive_le32dec(p + 16);
+ zip_entry->compressed_size = archive_le32dec(p + 20);
+ zip_entry->uncompressed_size = archive_le32dec(p + 24);
+ filename_length = archive_le16dec(p + 28);
+ extra_length = archive_le16dec(p + 30);
+ comment_length = archive_le16dec(p + 32);
+ /* disk_start = archive_le16dec(p + 34); */ /* Better be zero. */
+ /* internal_attributes = archive_le16dec(p + 36); */ /* text bit */
+ external_attributes = archive_le32dec(p + 38);
+ zip_entry->local_header_offset = archive_le32dec(p + 42);
+
+ /* If we can't guess the mode, leave it zero here;
+ when we read the local file header we might get
+ more information. */
+ zip_entry->mode = 0;
+ if (zip_entry->system == 3) {
+ zip_entry->mode = external_attributes >> 16;
+ }
+
+ /* We don't read the filename until we get to the
+ local file header. Reading it here would speed up
+ table-of-contents operations (removing the need to
+ find and read local file header to get the
+ filename) at the cost of requiring a lot of extra
+ space. */
+ /* We don't read the extra block here. We assume it
+ will be duplicated at the local file header. */
+ __archive_read_consume(a,
+ 46 + filename_length + extra_length + comment_length);
+ }
+
+ /* TODO: Sort zip entries by file offset so that we
+ can optimize get_next_header() to use skip instead of
+ seek. */
+
+ return ARCHIVE_OK;
+}
+
+static int
+archive_read_format_zip_seekable_read_header(struct archive_read *a,
+ struct archive_entry *entry)
+{
+ struct zip *zip = (struct zip *)a->format->data;
+ int r;
+
+ a->archive.archive_format = ARCHIVE_FORMAT_ZIP;
+ if (a->archive.archive_format_name == NULL)
+ a->archive.archive_format_name = "ZIP";
+
+ if (zip->zip_entries == NULL) {
+ r = slurp_central_directory(a, zip);
+ zip->entries_remaining = zip->central_directory_entries;
+ if (r != ARCHIVE_OK)
+ return r;
+ zip->entry = zip->zip_entries;
+ } else {
+ ++zip->entry;
+ }
+
+ if (zip->entries_remaining <= 0)
+ return ARCHIVE_EOF;
+ --zip->entries_remaining;
+
+ /* TODO: If entries are sorted by offset within the file, we
+ should be able to skip here instead of seeking. Skipping is
+ typically faster (easier for I/O layer to optimize). */
+ __archive_read_seek(a, zip->entry->local_header_offset, SEEK_SET);
+ zip->unconsumed = 0;
+ r = zip_read_local_file_header(a, entry, zip);
+ if (r != ARCHIVE_OK)
+ return r;
+ if ((zip->entry->mode & AE_IFMT) == AE_IFLNK) {
+ const void *p;
+ size_t linkname_length = archive_entry_size(entry);
+
+ archive_entry_set_size(entry, 0);
+ p = __archive_read_ahead(a, linkname_length, NULL);
+ if (p == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Truncated Zip file");
+ return ARCHIVE_FATAL;
+ }
+
+ if (archive_entry_copy_symlink_l(entry, p, linkname_length,
+ NULL) != 0) {
+ /* NOTE: If the last argument is NULL, this will
+ * fail only by memeory allocation failure. */
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Symlink");
+ return (ARCHIVE_FATAL);
+ }
+ /* TODO: handle character-set issues? */
+ }
+ return ARCHIVE_OK;
+}
+
+static int
+archive_read_format_zip_streamable_bid(struct archive_read *a, int best_bid)
+{
+ const char *p;
+
+ (void)best_bid; /* UNUSED */
if ((p = __archive_read_ahead(a, 4, NULL)) == NULL)
return (-1);
@@ -192,321 +419,308 @@ archive_read_format_zip_bid(struct archive_read *a)
return (30);
}
- /*
- * Attempt to handle self-extracting archives
- * by noting a PE header and searching forward
- * up to 128k for a 'PK\003\004' marker.
- */
- if (p[0] == 'M' && p[1] == 'Z') {
- /*
- * TODO: Optimize by initializing 'offset' to an
- * estimate of the likely start of the archive data
- * based on values in the PE header. Note that we
- * don't need to be exact, but we mustn't skip too
- * far. The search below will compensate if we
- * undershoot.
- */
- offset = 0;
- while (offset < 124000) {
- /* Get 4k of data beyond where we stopped. */
- buff = __archive_read_ahead(a, offset + 4096,
- &bytes_avail);
- if (buff == NULL)
- break;
- p = (const char *)buff + offset;
- while (p + 9 < (const char *)buff + bytes_avail) {
- if (p[0] == 'P' && p[1] == 'K' /* signature */
- && p[2] == 3 && p[3] == 4 /* File entry */
- && p[8] == 8 /* compression == deflate */
- && p[9] == 0 /* High byte of compression */
- )
- {
- return (30);
- }
- ++p;
- }
- offset = p - (const char *)buff;
- }
- }
+ /* TODO: It's worth looking ahead a little bit for a valid
+ * PK signature. In particular, that would make it possible
+ * to read some UUEncoded SFX files or SFX files coming from
+ * a network socket. */
return (0);
}
-/*
- * Search forward for a "PK\003\004" file header. This handles the
- * case of self-extracting archives, where there is an executable
- * prepended to the ZIP archive.
- */
static int
-skip_sfx(struct archive_read *a)
+archive_read_format_zip_options(struct archive_read *a,
+ const char *key, const char *val)
{
- const void *h;
- const char *p, *q;
- size_t skip;
- ssize_t bytes;
+ struct zip *zip;
+ int ret = ARCHIVE_FAILED;
- /*
- * TODO: We should be able to skip forward by a bunch
- * by lifting some values from the PE header. We don't
- * need to be exact (we're still going to search forward
- * to find the header), but it will speed things up and
- * reduce the chance of a false positive.
- */
- for (;;) {
- h = __archive_read_ahead(a, 4, &bytes);
- if (bytes < 4)
- return (ARCHIVE_FATAL);
- p = h;
- q = p + bytes;
-
- /*
- * Scan ahead until we find something that looks
- * like the zip header.
- */
- while (p + 4 < q) {
- switch (p[3]) {
- case '\004':
- /* TODO: Additional verification here. */
- if (memcmp("PK\003\004", p, 4) == 0) {
- skip = p - (const char *)h;
- __archive_read_consume(a, skip);
- return (ARCHIVE_OK);
- }
- p += 4;
- break;
- case '\003': p += 1; break;
- case 'K': p += 2; break;
- case 'P': p += 3; break;
- default: p += 4; break;
- }
+ zip = (struct zip *)(a->format->data);
+ if (strcmp(key, "compat-2x") == 0) {
+ /* Handle filnames as libarchive 2.x */
+ zip->init_default_conversion = (val != NULL) ? 1 : 0;
+ ret = ARCHIVE_OK;
+ } else if (strcmp(key, "hdrcharset") == 0) {
+ if (val == NULL || val[0] == 0)
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "zip: hdrcharset option needs a character-set name");
+ else {
+ zip->sconv = archive_string_conversion_from_charset(
+ &a->archive, val, 0);
+ if (zip->sconv != NULL) {
+ if (strcmp(val, "UTF-8") == 0)
+ zip->sconv_utf8 = zip->sconv;
+ ret = ARCHIVE_OK;
+ } else
+ ret = ARCHIVE_FATAL;
}
- skip = p - (const char *)h;
- __archive_read_consume(a, skip);
- }
+ } else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "zip: unknown keyword ``%s''", key);
+
+ return (ret);
}
static int
-archive_read_format_zip_read_header(struct archive_read *a,
+archive_read_format_zip_streamable_read_header(struct archive_read *a,
struct archive_entry *entry)
{
- const void *h;
- const char *signature;
struct zip *zip;
- int r = ARCHIVE_OK, r1;
a->archive.archive_format = ARCHIVE_FORMAT_ZIP;
if (a->archive.archive_format_name == NULL)
a->archive.archive_format_name = "ZIP";
zip = (struct zip *)(a->format->data);
- zip->decompress_init = 0;
- zip->end_of_entry = 0;
- zip->entry_uncompressed_bytes_read = 0;
- zip->entry_compressed_bytes_read = 0;
- zip->entry_crc32 = crc32(0, NULL, 0);
- if ((h = __archive_read_ahead(a, 4, NULL)) == NULL)
- return (ARCHIVE_FATAL);
-
- signature = (const char *)h;
- if (signature[0] == 'M' && signature[1] == 'Z') {
- /* This is an executable? Must be self-extracting... */
- r = skip_sfx(a);
- if (r < ARCHIVE_WARN)
- return (r);
- if ((h = __archive_read_ahead(a, 4, NULL)) == NULL)
- return (ARCHIVE_FATAL);
- signature = (const char *)h;
- }
- /* If we don't see a PK signature here, scan forward. */
- if (signature[0] != 'P' || signature[1] != 'K') {
- r = search_next_signature(a);
- if (r != ARCHIVE_OK) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Bad ZIP file");
- return (ARCHIVE_FATAL);
- }
- if ((h = __archive_read_ahead(a, 4, NULL)) == NULL)
- return (ARCHIVE_FATAL);
- signature = (const char *)h;
- }
-
- /*
- * "PK00" signature is used for "split" archives that
- * only have a single segment. This means we can just
- * skip the PK00; the first real file header should follow.
- */
- if (signature[2] == '0' && signature[3] == '0') {
- __archive_read_consume(a, 4);
- if ((h = __archive_read_ahead(a, 4, NULL)) == NULL)
- return (ARCHIVE_FATAL);
- signature = (const char *)h;
- if (signature[0] != 'P' || signature[1] != 'K') {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Bad ZIP file");
- return (ARCHIVE_FATAL);
+ /* Make sure we have a zip_entry structure to use. */
+ if (zip->zip_entries == NULL) {
+ zip->zip_entries = malloc(sizeof(struct zip_entry));
+ if (zip->zip_entries == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return ARCHIVE_FATAL;
}
}
+ zip->entry = zip->zip_entries;
+ memset(zip->entry, 0, sizeof(struct zip_entry));
- if (signature[2] == '\001' && signature[3] == '\002') {
- /* Beginning of central directory. */
- return (ARCHIVE_EOF);
- }
-
- if (signature[2] == '\003' && signature[3] == '\004') {
- /* Regular file entry. */
- r1 = zip_read_file_header(a, entry, zip);
- if (r1 != ARCHIVE_OK)
- return (r1);
- return (r);
- }
-
- if (signature[2] == '\005' && signature[3] == '\006') {
- /* End-of-archive record. */
- return (ARCHIVE_EOF);
- }
-
- if (signature[2] == '\007' && signature[3] == '\010') {
- /*
- * We should never encounter this record here;
- * see ZIP_LENGTH_AT_END handling below for details.
- */
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Bad ZIP file: Unexpected end-of-entry record");
- return (ARCHIVE_FATAL);
- }
-
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Damaged ZIP file or unsupported format variant (%d,%d)",
- signature[2], signature[3]);
- return (ARCHIVE_FATAL);
-}
-
-static int
-search_next_signature(struct archive_read *a)
-{
- const void *h;
- const char *p, *q;
- size_t skip;
- ssize_t bytes;
- int64_t skipped = 0;
-
+ /* Search ahead for the next local file header. */
+ __archive_read_consume(a, zip->unconsumed);
+ zip->unconsumed = 0;
for (;;) {
- h = __archive_read_ahead(a, 4, &bytes);
- if (h == NULL)
+ int64_t skipped = 0;
+ const char *p, *end;
+ ssize_t bytes;
+
+ p = __archive_read_ahead(a, 4, &bytes);
+ if (p == NULL)
return (ARCHIVE_FATAL);
- p = h;
- q = p + bytes;
+ end = p + bytes;
- while (p + 4 <= q) {
+ while (p + 4 <= end) {
if (p[0] == 'P' && p[1] == 'K') {
- if ((p[2] == '\001' && p[3] == '\002')
- || (p[2] == '\003' && p[3] == '\004')
- || (p[2] == '\005' && p[3] == '\006')
- || (p[2] == '\007' && p[3] == '\010')
- || (p[2] == '0' && p[3] == '0')) {
- skip = p - (const char *)h;
- __archive_read_consume(a, skip);
- return (ARCHIVE_OK);
+ if (p[2] == '\001' && p[3] == '\002')
+ /* Beginning of central directory. */
+ return (ARCHIVE_EOF);
+
+ if (p[2] == '\003' && p[3] == '\004') {
+ /* Regular file entry. */
+ __archive_read_consume(a, skipped);
+ return zip_read_local_file_header(a, entry, zip);
}
+
+ if (p[2] == '\005' && p[3] == '\006')
+ /* End of central directory. */
+ return (ARCHIVE_EOF);
}
++p;
+ ++skipped;
}
- skip = p - (const char *)h;
- __archive_read_consume(a, skip);
- skipped += skip;
+ __archive_read_consume(a, skipped);
}
}
+/*
+ * Assumes file pointer is at beginning of local file header.
+ */
static int
-zip_read_file_header(struct archive_read *a, struct archive_entry *entry,
+zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
struct zip *zip)
{
- const struct zip_file_header *p;
+ const char *p;
const void *h;
+ const wchar_t *wp;
+ const char *cp;
+ size_t len, filename_length, extra_length;
+ struct archive_string_conv *sconv;
+ struct zip_entry *zip_entry = zip->entry;
+ uint32_t local_crc32;
+ int64_t compressed_size, uncompressed_size;
+ int ret = ARCHIVE_OK;
+ char version;
+
+ zip->decompress_init = 0;
+ zip->end_of_entry = 0;
+ zip->entry_uncompressed_bytes_read = 0;
+ zip->entry_compressed_bytes_read = 0;
+ zip->entry_crc32 = crc32(0, NULL, 0);
+
+ /* Setup default conversion. */
+ if (zip->sconv == NULL && !zip->init_default_conversion) {
+ zip->sconv_default =
+ archive_string_default_conversion_for_read(&(a->archive));
+ zip->init_default_conversion = 1;
+ }
- if ((p = __archive_read_ahead(a, sizeof *p, NULL)) == NULL) {
+ if ((p = __archive_read_ahead(a, 30, NULL)) == NULL) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Truncated ZIP file header");
return (ARCHIVE_FATAL);
}
- zip->version = p->version[0];
- zip->system = p->version[1];
- zip->flags = archive_le16dec(p->flags);
- zip->compression = archive_le16dec(p->compression);
- if (zip->compression <
- sizeof(compression_names)/sizeof(compression_names[0]))
- zip->compression_name = compression_names[zip->compression];
- else
- zip->compression_name = "??";
- zip->mtime = zip_time(p->timedate);
- zip->ctime = 0;
- zip->atime = 0;
- zip->mode = 0;
- zip->uid = 0;
- zip->gid = 0;
- zip->crc32 = archive_le32dec(p->crc32);
- zip->filename_length = archive_le16dec(p->filename_length);
- zip->extra_length = archive_le16dec(p->extra_length);
- zip->uncompressed_size = archive_le32dec(p->uncompressed_size);
- zip->compressed_size = archive_le32dec(p->compressed_size);
-
- __archive_read_consume(a, sizeof(struct zip_file_header));
-
+ if (memcmp(p, "PK\003\004", 4) != 0) {
+ archive_set_error(&a->archive, -1, "Damaged Zip archive");
+ return ARCHIVE_FATAL;
+ }
+ version = p[4];
+ zip_entry->system = p[5];
+ zip_entry->flags = archive_le16dec(p + 6);
+ zip_entry->compression = archive_le16dec(p + 8);
+ zip_entry->mtime = zip_time(p + 10);
+ local_crc32 = archive_le32dec(p + 14);
+ compressed_size = archive_le32dec(p + 18);
+ uncompressed_size = archive_le32dec(p + 22);
+ filename_length = archive_le16dec(p + 26);
+ extra_length = archive_le16dec(p + 28);
+
+ __archive_read_consume(a, 30);
+
+ if (zip->have_central_directory) {
+ /* If we read the central dir entry, we must have size information
+ as well, so ignore the length-at-end flag. */
+ zip_entry->flags &= ~ZIP_LENGTH_AT_END;
+ /* If we have values from both the local file header
+ and the central directory, warn about mismatches
+ which might indicate a damaged file. But some
+ writers always put zero in the local header; don't
+ bother warning about that. */
+ if (local_crc32 != 0 && local_crc32 != zip_entry->crc32) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Inconsistent CRC32 values");
+ ret = ARCHIVE_WARN;
+ }
+ if (compressed_size != 0
+ && compressed_size != zip_entry->compressed_size) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Inconsistent compressed size");
+ ret = ARCHIVE_WARN;
+ }
+ if (uncompressed_size != 0
+ && uncompressed_size != zip_entry->uncompressed_size) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Inconsistent uncompressed size");
+ ret = ARCHIVE_WARN;
+ }
+ } else {
+ /* If we don't have the CD info, use whatever we do have. */
+ zip_entry->crc32 = local_crc32;
+ zip_entry->compressed_size = compressed_size;
+ zip_entry->uncompressed_size = uncompressed_size;
+ }
/* Read the filename. */
- if ((h = __archive_read_ahead(a, zip->filename_length, NULL)) == NULL) {
+ if ((h = __archive_read_ahead(a, filename_length, NULL)) == NULL) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Truncated ZIP file header");
return (ARCHIVE_FATAL);
}
- if (archive_string_ensure(&zip->pathname, zip->filename_length) == NULL)
- __archive_errx(1, "Out of memory");
- archive_strncpy(&zip->pathname, h, zip->filename_length);
- __archive_read_consume(a, zip->filename_length);
- archive_entry_set_pathname(entry, zip->pathname.s);
-
- if (zip->pathname.s[archive_strlen(&zip->pathname) - 1] == '/')
- zip->mode = AE_IFDIR | 0777;
+ if (zip_entry->flags & ZIP_UTF8_NAME) {
+ /* The filename is stored to be UTF-8. */
+ if (zip->sconv_utf8 == NULL) {
+ zip->sconv_utf8 =
+ archive_string_conversion_from_charset(
+ &a->archive, "UTF-8", 1);
+ if (zip->sconv_utf8 == NULL)
+ return (ARCHIVE_FATAL);
+ }
+ sconv = zip->sconv_utf8;
+ } else if (zip->sconv != NULL)
+ sconv = zip->sconv;
else
- zip->mode = AE_IFREG | 0777;
+ sconv = zip->sconv_default;
+
+ if (archive_entry_copy_pathname_l(entry,
+ h, filename_length, sconv) != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Pathname cannot be converted "
+ "from %s to current locale.",
+ archive_string_conversion_charset_name(sconv));
+ ret = ARCHIVE_WARN;
+ }
+ __archive_read_consume(a, filename_length);
+
+ if (zip_entry->mode == 0) {
+ /* Especially in streaming mode, we can end up
+ here without having seen any mode information.
+ Guess from the filename. */
+ wp = archive_entry_pathname_w(entry);
+ if (wp != NULL) {
+ len = wcslen(wp);
+ if (len > 0 && wp[len - 1] == L'/')
+ zip_entry->mode = AE_IFDIR | 0777;
+ else
+ zip_entry->mode = AE_IFREG | 0777;
+ } else {
+ cp = archive_entry_pathname(entry);
+ len = (cp != NULL)?strlen(cp):0;
+ if (len > 0 && cp[len - 1] == '/')
+ zip_entry->mode = AE_IFDIR | 0777;
+ else
+ zip_entry->mode = AE_IFREG | 0777;
+ }
+ }
/* Read the extra data. */
- if ((h = __archive_read_ahead(a, zip->extra_length, NULL)) == NULL) {
+ if ((h = __archive_read_ahead(a, extra_length, NULL)) == NULL) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Truncated ZIP file header");
return (ARCHIVE_FATAL);
}
- process_extra(h, zip);
- __archive_read_consume(a, zip->extra_length);
+ process_extra(h, extra_length, zip_entry);
+ __archive_read_consume(a, extra_length);
/* Populate some additional entry fields: */
- archive_entry_set_mode(entry, zip->mode);
- archive_entry_set_uid(entry, zip->uid);
- archive_entry_set_gid(entry, zip->gid);
- archive_entry_set_mtime(entry, zip->mtime, 0);
- archive_entry_set_ctime(entry, zip->ctime, 0);
- archive_entry_set_atime(entry, zip->atime, 0);
+ archive_entry_set_mode(entry, zip_entry->mode);
+ archive_entry_set_uid(entry, zip_entry->uid);
+ archive_entry_set_gid(entry, zip_entry->gid);
+ archive_entry_set_mtime(entry, zip_entry->mtime, 0);
+ archive_entry_set_ctime(entry, zip_entry->ctime, 0);
+ archive_entry_set_atime(entry, zip_entry->atime, 0);
/* Set the size only if it's meaningful. */
- if (0 == (zip->flags & ZIP_LENGTH_AT_END))
- archive_entry_set_size(entry, zip->uncompressed_size);
+ if (0 == (zip_entry->flags & ZIP_LENGTH_AT_END))
+ archive_entry_set_size(entry, zip_entry->uncompressed_size);
- zip->entry_bytes_remaining = zip->compressed_size;
- zip->entry_offset = 0;
+ zip->entry_bytes_remaining = zip_entry->compressed_size;
/* If there's no body, force read_data() to return EOF immediately. */
- if (0 == (zip->flags & ZIP_LENGTH_AT_END)
+ if (0 == (zip_entry->flags & ZIP_LENGTH_AT_END)
&& zip->entry_bytes_remaining < 1)
zip->end_of_entry = 1;
/* Set up a more descriptive format name. */
sprintf(zip->format_name, "ZIP %d.%d (%s)",
- zip->version / 10, zip->version % 10,
- zip->compression_name);
+ version / 10, version % 10,
+ compression_name(zip->entry->compression));
a->archive.archive_format_name = zip->format_name;
- return (ARCHIVE_OK);
+ return (ret);
+}
+
+static const char *
+compression_name(int compression)
+{
+ static const char *compression_names[] = {
+ "uncompressed",
+ "shrinking",
+ "reduced-1",
+ "reduced-2",
+ "reduced-3",
+ "reduced-4",
+ "imploded",
+ "reserved",
+ "deflation"
+ };
+
+ if (compression <
+ sizeof(compression_names)/sizeof(compression_names[0]))
+ return compression_names[compression];
+ else
+ return "??";
}
/* Convert an MSDOS-style date/time into Unix-style time. */
@@ -532,52 +746,49 @@ zip_time(const char *p)
static int
archive_read_format_zip_read_data(struct archive_read *a,
- const void **buff, size_t *size, off_t *offset)
+ const void **buff, size_t *size, int64_t *offset)
{
int r;
- struct zip *zip;
+ struct zip *zip = (struct zip *)(a->format->data);
- zip = (struct zip *)(a->format->data);
+ *offset = zip->entry_uncompressed_bytes_read;
+ *size = 0;
+ *buff = NULL;
- /*
- * If we hit end-of-entry last time, clean up and return
- * ARCHIVE_EOF this time.
- */
- if (zip->end_of_entry) {
- *offset = zip->entry_uncompressed_bytes_read;
- *size = 0;
- *buff = NULL;
+ /* If we hit end-of-entry last time, return ARCHIVE_EOF. */
+ if (zip->end_of_entry)
+ return (ARCHIVE_EOF);
+
+ /* Return EOF immediately if this is a non-regular file. */
+ if (AE_IFREG != (zip->entry->mode & AE_IFMT))
return (ARCHIVE_EOF);
+
+ if (zip->entry->flags & (ZIP_ENCRYPTED | ZIP_STRONG_ENCRYPTED)) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Encrypted file is unsupported");
+ return (ARCHIVE_FAILED);
}
- switch(zip->compression) {
+ __archive_read_consume(a, zip->unconsumed);
+ zip->unconsumed = 0;
+
+ switch(zip->entry->compression) {
case 0: /* No compression. */
r = zip_read_data_none(a, buff, size, offset);
break;
+#ifdef HAVE_ZLIB_H
case 8: /* Deflate compression. */
r = zip_read_data_deflate(a, buff, size, offset);
break;
+#endif
default: /* Unsupported compression. */
- *buff = NULL;
- *size = 0;
- *offset = 0;
/* Return a warning. */
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Unsupported ZIP compression method (%s)",
- zip->compression_name);
- if (zip->flags & ZIP_LENGTH_AT_END) {
- /*
- * ZIP_LENGTH_AT_END requires us to
- * decompress the entry in order to
- * skip it, but we don't know this
- * compression method, so we give up.
- */
- r = ARCHIVE_FATAL;
- } else {
- /* We can't decompress this entry, but we will
- * be able to skip() it and try the next entry. */
- r = ARCHIVE_WARN;
- }
+ compression_name(zip->entry->compression));
+ /* We can't decompress this entry, but we will
+ * be able to skip() it and try the next entry. */
+ return (ARCHIVE_FAILED);
break;
}
if (r != ARCHIVE_OK)
@@ -587,105 +798,142 @@ archive_read_format_zip_read_data(struct archive_read *a,
zip->entry_crc32 = crc32(zip->entry_crc32, *buff, *size);
/* If we hit the end, swallow any end-of-data marker. */
if (zip->end_of_entry) {
- if (zip->flags & ZIP_LENGTH_AT_END) {
- const char *p;
-
- if ((p = __archive_read_ahead(a, 16, NULL)) == NULL) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated ZIP end-of-file record");
- return (ARCHIVE_FATAL);
- }
- zip->crc32 = archive_le32dec(p + 4);
- zip->compressed_size = archive_le32dec(p + 8);
- zip->uncompressed_size = archive_le32dec(p + 12);
- __archive_read_consume(a, 16);
- }
/* Check file size, CRC against these values. */
- if (zip->compressed_size != zip->entry_compressed_bytes_read) {
+ if (zip->entry->compressed_size != zip->entry_compressed_bytes_read) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "ZIP compressed data is wrong size");
+ "ZIP compressed data is wrong size (read %jd, expected %jd)",
+ (intmax_t)zip->entry_compressed_bytes_read,
+ (intmax_t)zip->entry->compressed_size);
return (ARCHIVE_WARN);
}
- /* Size field only stores the lower 32 bits of the actual size. */
- if ((zip->uncompressed_size & UINT32_MAX)
+ /* Size field only stores the lower 32 bits of the actual
+ * size. */
+ if ((zip->entry->uncompressed_size & UINT32_MAX)
!= (zip->entry_uncompressed_bytes_read & UINT32_MAX)) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "ZIP uncompressed data is wrong size");
+ "ZIP uncompressed data is wrong size (read %jd, expected %jd)",
+ (intmax_t)zip->entry_uncompressed_bytes_read,
+ (intmax_t)zip->entry->uncompressed_size);
return (ARCHIVE_WARN);
}
/* Check computed CRC against header */
- if (zip->crc32 != zip->entry_crc32) {
+ if (zip->entry->crc32 != zip->entry_crc32) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"ZIP bad CRC: 0x%lx should be 0x%lx",
- zip->entry_crc32, zip->crc32);
+ (unsigned long)zip->entry_crc32,
+ (unsigned long)zip->entry->crc32);
return (ARCHIVE_WARN);
}
}
- /* Return EOF immediately if this is a non-regular file. */
- if (AE_IFREG != (zip->mode & AE_IFMT))
- return (ARCHIVE_EOF);
return (ARCHIVE_OK);
}
/*
- * Read "uncompressed" data. According to the current specification,
- * if ZIP_LENGTH_AT_END is specified, then the size fields in the
- * initial file header are supposed to be set to zero. This would, of
- * course, make it impossible for us to read the archive, since we
- * couldn't determine the end of the file data. Info-ZIP seems to
- * include the real size fields both before and after the data in this
- * case (the CRC only appears afterwards), so this works as you would
- * expect.
+ * Read "uncompressed" data. There are three cases:
+ * 1) We know the size of the data. This is always true for the
+ * seeking reader (we've examined the Central Directory already).
+ * 2) ZIP_LENGTH_AT_END was set, but only the CRC was deferred.
+ * Info-ZIP seems to do this; we know the size but have to grab
+ * the CRC from the data descriptor afterwards.
+ * 3) We're streaming and ZIP_LENGTH_AT_END was specified and
+ * we have no size information. In this case, we can do pretty
+ * well by watching for the data descriptor record. The data
+ * descriptor is 16 bytes and includes a computed CRC that should
+ * provide a strong check.
+ *
+ * TODO: Technically, the PK\007\010 signature is optional.
+ * In the original spec, the data descriptor contained CRC
+ * and size fields but had no leading signature. In practice,
+ * newer writers seem to provide the signature pretty consistently,
+ * but we might need to do something more complex here if
+ * we want to handle older archives that lack that signature.
*
* Returns ARCHIVE_OK if successful, ARCHIVE_FATAL otherwise, sets
* zip->end_of_entry if it consumes all of the data.
*/
static int
-zip_read_data_none(struct archive_read *a, const void **buff,
- size_t *size, off_t *offset)
+zip_read_data_none(struct archive_read *a, const void **_buff,
+ size_t *size, int64_t *offset)
{
struct zip *zip;
+ const char *buff;
ssize_t bytes_avail;
zip = (struct zip *)(a->format->data);
- if (zip->entry_bytes_remaining == 0) {
- *buff = NULL;
- *size = 0;
- *offset = zip->entry_offset;
- zip->end_of_entry = 1;
- return (ARCHIVE_OK);
- }
- /*
- * Note: '1' here is a performance optimization.
- * Recall that the decompression layer returns a count of
- * available bytes; asking for more than that forces the
- * decompressor to combine reads by copying data.
- */
- *buff = __archive_read_ahead(a, 1, &bytes_avail);
- if (bytes_avail <= 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated ZIP file data");
- return (ARCHIVE_FATAL);
+ if (zip->entry->flags & ZIP_LENGTH_AT_END) {
+ const char *p;
+
+ /* Grab at least 16 bytes. */
+ buff = __archive_read_ahead(a, 16, &bytes_avail);
+ if (bytes_avail < 16) {
+ /* Zip archives have end-of-archive markers
+ that are longer than this, so a failure to get at
+ least 16 bytes really does indicate a truncated
+ file. */
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated ZIP file data");
+ return (ARCHIVE_FATAL);
+ }
+ /* Check for a complete PK\007\010 signature. */
+ p = buff;
+ if (p[0] == 'P' && p[1] == 'K'
+ && p[2] == '\007' && p[3] == '\010'
+ && archive_le32dec(p + 4) == zip->entry_crc32
+ && archive_le32dec(p + 8) == zip->entry_compressed_bytes_read
+ && archive_le32dec(p + 12) == zip->entry_uncompressed_bytes_read) {
+ zip->entry->crc32 = archive_le32dec(p + 4);
+ zip->entry->compressed_size = archive_le32dec(p + 8);
+ zip->entry->uncompressed_size = archive_le32dec(p + 12);
+ zip->end_of_entry = 1;
+ zip->unconsumed = 16;
+ return (ARCHIVE_OK);
+ }
+ /* If not at EOF, ensure we consume at least one byte. */
+ ++p;
+
+ /* Scan forward until we see where a PK\007\010 signature might be. */
+ /* Return bytes up until that point. On the next call, the code
+ above will verify the data descriptor. */
+ while (p < buff + bytes_avail - 4) {
+ if (p[3] == 'P') { p += 3; }
+ else if (p[3] == 'K') { p += 2; }
+ else if (p[3] == '\007') { p += 1; }
+ else if (p[3] == '\010' && p[2] == '\007'
+ && p[1] == 'K' && p[0] == 'P') {
+ break;
+ } else { p += 4; }
+ }
+ bytes_avail = p - buff;
+ } else {
+ if (zip->entry_bytes_remaining == 0) {
+ zip->end_of_entry = 1;
+ return (ARCHIVE_OK);
+ }
+ /* Grab a bunch of bytes. */
+ buff = __archive_read_ahead(a, 1, &bytes_avail);
+ if (bytes_avail <= 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated ZIP file data");
+ return (ARCHIVE_FATAL);
+ }
+ if (bytes_avail > zip->entry_bytes_remaining)
+ bytes_avail = zip->entry_bytes_remaining;
}
- if (bytes_avail > zip->entry_bytes_remaining)
- bytes_avail = zip->entry_bytes_remaining;
- __archive_read_consume(a, bytes_avail);
*size = bytes_avail;
- *offset = zip->entry_offset;
- zip->entry_offset += *size;
- zip->entry_bytes_remaining -= *size;
- zip->entry_uncompressed_bytes_read += *size;
- zip->entry_compressed_bytes_read += *size;
+ zip->entry_bytes_remaining -= bytes_avail;
+ zip->entry_uncompressed_bytes_read += bytes_avail;
+ zip->entry_compressed_bytes_read += bytes_avail;
+ zip->unconsumed += bytes_avail;
+ *_buff = buff;
return (ARCHIVE_OK);
}
#ifdef HAVE_ZLIB_H
static int
zip_read_data_deflate(struct archive_read *a, const void **buff,
- size_t *size, off_t *offset)
+ size_t *size, int64_t *offset)
{
struct zip *zip;
ssize_t bytes_avail;
@@ -696,7 +944,7 @@ zip_read_data_deflate(struct archive_read *a, const void **buff,
/* If the buffer hasn't been allocated, allocate it now. */
if (zip->uncompressed_buffer == NULL) {
- zip->uncompressed_buffer_size = 32 * 1024;
+ zip->uncompressed_buffer_size = 256 * 1024;
zip->uncompressed_buffer
= (unsigned char *)malloc(zip->uncompressed_buffer_size);
if (zip->uncompressed_buffer == NULL) {
@@ -731,6 +979,10 @@ zip_read_data_deflate(struct archive_read *a, const void **buff,
* decompressor to combine reads by copying data.
*/
compressed_buff = __archive_read_ahead(a, 1, &bytes_avail);
+ if (0 == (zip->entry->flags & ZIP_LENGTH_AT_END)
+ && bytes_avail > zip->entry_bytes_remaining) {
+ bytes_avail = zip->entry_bytes_remaining;
+ }
if (bytes_avail <= 0) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Truncated ZIP file body");
@@ -773,66 +1025,102 @@ zip_read_data_deflate(struct archive_read *a, const void **buff,
zip->entry_bytes_remaining -= bytes_avail;
zip->entry_compressed_bytes_read += bytes_avail;
- *offset = zip->entry_offset;
*size = zip->stream.total_out;
- zip->entry_uncompressed_bytes_read += *size;
+ zip->entry_uncompressed_bytes_read += zip->stream.total_out;
*buff = zip->uncompressed_buffer;
- zip->entry_offset += *size;
+
+ if (zip->end_of_entry && (zip->entry->flags & ZIP_LENGTH_AT_END)) {
+ const char *p;
+
+ if (NULL == (p = __archive_read_ahead(a, 16, NULL))) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated ZIP end-of-file record");
+ return (ARCHIVE_FATAL);
+ }
+ /* Consume the optional PK\007\010 marker. */
+ if (p[0] == 'P' && p[1] == 'K' && p[2] == '\007' && p[3] == '\010') {
+ zip->entry->crc32 = archive_le32dec(p + 4);
+ zip->entry->compressed_size = archive_le32dec(p + 8);
+ zip->entry->uncompressed_size = archive_le32dec(p + 12);
+ zip->unconsumed = 16;
+ }
+ }
+
return (ARCHIVE_OK);
}
-#else
-static int
-zip_read_data_deflate(struct archive_read *a, const void **buff,
- size_t *size, off_t *offset)
-{
- *buff = NULL;
- *size = 0;
- *offset = 0;
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "libarchive compiled without deflate support (no libz)");
- return (ARCHIVE_FATAL);
-}
#endif
static int
archive_read_format_zip_read_data_skip(struct archive_read *a)
{
struct zip *zip;
- const void *buff = NULL;
- off_t bytes_skipped;
zip = (struct zip *)(a->format->data);
/* If we've already read to end of data, we're done. */
if (zip->end_of_entry)
return (ARCHIVE_OK);
+ /* If we're seeking, we're done. */
+ if (zip->have_central_directory)
+ return (ARCHIVE_OK);
- /*
- * If the length is at the end, we have no choice but
- * to decompress all the data to find the end marker.
- */
- if (zip->flags & ZIP_LENGTH_AT_END) {
- size_t size;
- off_t offset;
- int r;
- do {
- r = archive_read_format_zip_read_data(a, &buff,
- &size, &offset);
- } while (r == ARCHIVE_OK);
- return (r);
+ /* So we know we're streaming... */
+ if (0 == (zip->entry->flags & ZIP_LENGTH_AT_END)) {
+ /* We know the compressed length, so we can just skip. */
+ int64_t bytes_skipped = __archive_read_consume(a,
+ zip->entry_bytes_remaining + zip->unconsumed);
+ if (bytes_skipped < 0)
+ return (ARCHIVE_FATAL);
+ zip->unconsumed = 0;
+ return (ARCHIVE_OK);
}
- /*
- * If the length is at the beginning, we can skip the
- * compressed data much more quickly.
- */
- bytes_skipped = __archive_read_skip(a, zip->entry_bytes_remaining);
- if (bytes_skipped < 0)
- return (ARCHIVE_FATAL);
-
- /* This entry is finished and done. */
- zip->end_of_entry = 1;
- return (ARCHIVE_OK);
+ /* We're streaming and we don't know the length. */
+ /* If the body is compressed and we know the format, we can
+ * find an exact end-of-entry by decompressing it. */
+ switch (zip->entry->compression) {
+#ifdef HAVE_ZLIB_H
+ case 8: /* Deflate compression. */
+ while (!zip->end_of_entry) {
+ int64_t offset = 0;
+ const void *buff = NULL;
+ size_t size = 0;
+ int r;
+ r = zip_read_data_deflate(a, &buff, &size, &offset);
+ if (r != ARCHIVE_OK)
+ return (r);
+ }
+ break;
+#endif
+ default: /* Uncompressed or unknown. */
+ /* Scan for a PK\007\010 signature. */
+ __archive_read_consume(a, zip->unconsumed);
+ zip->unconsumed = 0;
+ for (;;) {
+ const char *p, *buff;
+ ssize_t bytes_avail;
+ buff = __archive_read_ahead(a, 16, &bytes_avail);
+ if (bytes_avail < 16) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated ZIP file data");
+ return (ARCHIVE_FATAL);
+ }
+ p = buff;
+ while (p <= buff + bytes_avail - 16) {
+ if (p[3] == 'P') { p += 3; }
+ else if (p[3] == 'K') { p += 2; }
+ else if (p[3] == '\007') { p += 1; }
+ else if (p[3] == '\010' && p[2] == '\007'
+ && p[1] == 'K' && p[0] == 'P') {
+ __archive_read_consume(a, p - buff + 16);
+ return ARCHIVE_OK;
+ } else { p += 4; }
+ }
+ __archive_read_consume(a, p - buff);
+ }
+ }
+ return ARCHIVE_OK;
}
static int
@@ -845,8 +1133,8 @@ archive_read_format_zip_cleanup(struct archive_read *a)
if (zip->stream_valid)
inflateEnd(&zip->stream);
#endif
+ free(zip->zip_entries);
free(zip->uncompressed_buffer);
- archive_string_free(&(zip->pathname));
archive_string_free(&(zip->extra));
free(zip);
(a->format->data) = NULL;
@@ -859,28 +1147,30 @@ archive_read_format_zip_cleanup(struct archive_read *a)
* triplets. id and size are 2 bytes each.
*/
static void
-process_extra(const void* extra, struct zip* zip)
+process_extra(const char *p, size_t extra_length, struct zip_entry* zip_entry)
{
- int offset = 0;
- const char *p = (const char *)extra;
- while (offset < zip->extra_length - 4)
+ unsigned offset = 0;
+
+ while (offset < extra_length - 4)
{
unsigned short headerid = archive_le16dec(p + offset);
unsigned short datasize = archive_le16dec(p + offset + 2);
offset += 4;
- if (offset + datasize > zip->extra_length)
+ if (offset + datasize > extra_length)
break;
#ifdef DEBUG
- fprintf(stderr, "Header id 0x%04x, length %d\n",
+ fprintf(stderr, "Header id 0x%x, length %d\n",
headerid, datasize);
#endif
switch (headerid) {
case 0x0001:
/* Zip64 extended information extra field. */
if (datasize >= 8)
- zip->uncompressed_size = archive_le64dec(p + offset);
+ zip_entry->uncompressed_size =
+ archive_le64dec(p + offset);
if (datasize >= 16)
- zip->compressed_size = archive_le64dec(p + offset + 8);
+ zip_entry->compressed_size =
+ archive_le64dec(p + offset + 8);
break;
case 0x5455:
{
@@ -893,12 +1183,12 @@ process_extra(const void* extra, struct zip* zip)
{
#ifdef DEBUG
fprintf(stderr, "mtime: %lld -> %d\n",
- (long long)zip->mtime,
+ (long long)zip_entry->mtime,
archive_le32dec(p + offset));
#endif
if (datasize < 4)
break;
- zip->mtime = archive_le32dec(p + offset);
+ zip_entry->mtime = archive_le32dec(p + offset);
offset += 4;
datasize -= 4;
}
@@ -906,7 +1196,7 @@ process_extra(const void* extra, struct zip* zip)
{
if (datasize < 4)
break;
- zip->atime = archive_le32dec(p + offset);
+ zip_entry->atime = archive_le32dec(p + offset);
offset += 4;
datasize -= 4;
}
@@ -914,12 +1204,25 @@ process_extra(const void* extra, struct zip* zip)
{
if (datasize < 4)
break;
- zip->ctime = archive_le32dec(p + offset);
+ zip_entry->ctime = archive_le32dec(p + offset);
offset += 4;
datasize -= 4;
}
break;
}
+ case 0x5855:
+ {
+ /* Info-ZIP Unix Extra Field (old version) "UX". */
+ if (datasize >= 8) {
+ zip_entry->atime = archive_le32dec(p + offset);
+ zip_entry->mtime = archive_le32dec(p + offset + 4);
+ }
+ if (datasize >= 12) {
+ zip_entry->uid = archive_le16dec(p + offset + 8);
+ zip_entry->gid = archive_le16dec(p + offset + 10);
+ }
+ break;
+ }
case 0x7855:
/* Info-ZIP Unix Extra Field (type 2) "Ux". */
#ifdef DEBUG
@@ -928,23 +1231,50 @@ process_extra(const void* extra, struct zip* zip)
archive_le16dec(p + offset + 2));
#endif
if (datasize >= 2)
- zip->uid = archive_le16dec(p + offset);
+ zip_entry->uid = archive_le16dec(p + offset);
if (datasize >= 4)
- zip->gid = archive_le16dec(p + offset + 2);
+ zip_entry->gid = archive_le16dec(p + offset + 2);
break;
case 0x7875:
+ {
/* Info-Zip Unix Extra Field (type 3) "ux". */
+ int uidsize = 0, gidsize = 0;
+
+ if (datasize >= 1 && p[offset] == 1) {/* version=1 */
+ if (datasize >= 4) {
+ /* get a uid size. */
+ uidsize = p[offset+1];
+ if (uidsize == 2)
+ zip_entry->uid = archive_le16dec(
+ p + offset + 2);
+ else if (uidsize == 4 && datasize >= 6)
+ zip_entry->uid = archive_le32dec(
+ p + offset + 2);
+ }
+ if (datasize >= (2 + uidsize + 3)) {
+ /* get a gid size. */
+ gidsize = p[offset+2+uidsize];
+ if (gidsize == 2)
+ zip_entry->gid = archive_le16dec(
+ p+offset+2+uidsize+1);
+ else if (gidsize == 4 &&
+ datasize >= (2 + uidsize + 5))
+ zip_entry->gid = archive_le32dec(
+ p+offset+2+uidsize+1);
+ }
+ }
break;
+ }
default:
break;
}
offset += datasize;
}
#ifdef DEBUG
- if (offset != zip->extra_length)
+ if (offset != extra_length)
{
fprintf(stderr,
- "Extra data field contents do not match reported size!");
+ "Extra data field contents do not match reported size!\n");
}
#endif
}
diff --git a/libarchive/archive_string.c b/libarchive/archive_string.c
index 95bed6eda39b..550d7e7e6b62 100644
--- a/libarchive/archive_string.c
+++ b/libarchive/archive_string.c
@@ -1,5 +1,6 @@
/*-
- * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2003-2011 Tim Kientzle
+ * Copyright (c) 2011 Michihiro NAKAJIMA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -29,8 +30,24 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_string.c 201095 2009-12-28 02:33
/*
* Basic resizable string support, to simplify manipulating arbitrary-sized
* strings while minimizing heap activity.
+ *
+ * In particular, the buffer used by a string object is only grown, it
+ * never shrinks, so you can clear and reuse the same string object
+ * without incurring additional memory allocations.
*/
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_ICONV_H
+#include <iconv.h>
+#endif
+#ifdef HAVE_LANGINFO_H
+#include <langinfo.h>
+#endif
+#ifdef HAVE_LOCALCHARSET_H
+#include <localcharset.h>
+#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
@@ -42,63 +59,224 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_string.c 201095 2009-12-28 02:33
#endif
#if defined(_WIN32) && !defined(__CYGWIN__)
#include <windows.h>
+#include <locale.h>
+#endif
+#if defined(__APPLE__)
+#include <CoreServices/CoreServices.h>
#endif
+#include "archive_endian.h"
#include "archive_private.h"
#include "archive_string.h"
+#include "archive_string_composition.h"
-struct archive_string *
-__archive_string_append(struct archive_string *as, const char *p, size_t s)
+#if !defined(HAVE_WMEMCPY) && !defined(wmemcpy)
+#define wmemcpy(a,b,i) (wchar_t *)memcpy((a), (b), (i) * sizeof(wchar_t))
+#endif
+
+struct archive_string_conv {
+ struct archive_string_conv *next;
+ char *from_charset;
+ char *to_charset;
+ unsigned from_cp;
+ unsigned to_cp;
+ /* Set 1 if from_charset and to_charset are the same. */
+ int same;
+ int flag;
+#define SCONV_TO_CHARSET 1 /* MBS is being converted to specified
+ * charset. */
+#define SCONV_FROM_CHARSET (1<<1) /* MBS is being converted from
+ * specified charset. */
+#define SCONV_BEST_EFFORT (1<<2) /* Copy at least ASCII code. */
+#define SCONV_WIN_CP (1<<3) /* Use Windows API for converting
+ * MBS. */
+#define SCONV_UTF8_LIBARCHIVE_2 (1<<4) /* Incorrect UTF-8 made by libarchive
+ * 2.x in the wrong assumption. */
+#define SCONV_NORMALIZATION_C (1<<6) /* Need normalization to be Form C.
+ * Before UTF-8 characters are actually
+ * processed. */
+#define SCONV_NORMALIZATION_D (1<<7) /* Need normalization to be Form D.
+ * Before UTF-8 characters are actually
+ * processed.
+ * Currently this only for MAC OS X. */
+#define SCONV_TO_UTF8 (1<<8) /* "to charset" side is UTF-8. */
+#define SCONV_FROM_UTF8 (1<<9) /* "from charset" side is UTF-8. */
+#define SCONV_TO_UTF16BE (1<<10) /* "to charset" side is UTF-16BE. */
+#define SCONV_FROM_UTF16BE (1<<11) /* "from charset" side is UTF-16BE. */
+#define SCONV_TO_UTF16LE (1<<12) /* "to charset" side is UTF-16LE. */
+#define SCONV_FROM_UTF16LE (1<<13) /* "from charset" side is UTF-16LE. */
+#define SCONV_TO_UTF16 (SCONV_TO_UTF16BE | SCONV_TO_UTF16LE)
+#define SCONV_FROM_UTF16 (SCONV_FROM_UTF16BE | SCONV_FROM_UTF16LE)
+
+#if HAVE_ICONV
+ iconv_t cd;
+ iconv_t cd_w;/* Use at archive_mstring on
+ * Windows. */
+#endif
+ /* A temporary buffer for normalization. */
+ struct archive_string utftmp;
+#if defined(__APPLE__)
+ UnicodeToTextInfo uniInfo;
+ struct archive_string utf16nfc;
+ struct archive_string utf16nfd;
+#endif
+ int (*converter[2])(struct archive_string *, const void *, size_t,
+ struct archive_string_conv *);
+ int nconverter;
+};
+
+#define CP_C_LOCALE 0 /* "C" locale only for this file. */
+#define CP_UTF16LE 1200
+#define CP_UTF16BE 1201
+
+#define IS_HIGH_SURROGATE_LA(uc) ((uc) >= 0xD800 && (uc) <= 0xDBFF)
+#define IS_LOW_SURROGATE_LA(uc) ((uc) >= 0xDC00 && (uc) <= 0xDFFF)
+#define IS_SURROGATE_PAIR_LA(uc) ((uc) >= 0xD800 && (uc) <= 0xDFFF)
+#define UNICODE_MAX 0x10FFFF
+#define UNICODE_R_CHAR 0xFFFD /* Replacement character. */
+/* Set U+FFFD(Replacement character) in UTF-8. */
+#define UTF8_SET_R_CHAR(outp) do { \
+ (outp)[0] = 0xef; \
+ (outp)[1] = 0xbf; \
+ (outp)[2] = 0xbd; \
+} while (0)
+#define UTF8_R_CHAR_SIZE 3
+
+static struct archive_string_conv *find_sconv_object(struct archive *,
+ const char *, const char *);
+static void add_sconv_object(struct archive *, struct archive_string_conv *);
+static struct archive_string_conv *create_sconv_object(const char *,
+ const char *, unsigned, int);
+static void free_sconv_object(struct archive_string_conv *);
+static struct archive_string_conv *get_sconv_object(struct archive *,
+ const char *, const char *, int);
+static unsigned make_codepage_from_charset(const char *);
+static unsigned get_current_codepage(void);
+static unsigned get_current_oemcp(void);
+static size_t mbsnbytes(const void *, size_t);
+static size_t utf16nbytes(const void *, size_t);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+static int archive_wstring_append_from_mbs_in_codepage(
+ struct archive_wstring *, const char *, size_t,
+ struct archive_string_conv *);
+static int archive_string_append_from_wcs_in_codepage(struct archive_string *,
+ const wchar_t *, size_t, struct archive_string_conv *);
+static int is_big_endian(void);
+static int strncat_in_codepage(struct archive_string *, const void *,
+ size_t, struct archive_string_conv *);
+static int win_strncat_from_utf16be(struct archive_string *, const void *, size_t,
+ struct archive_string_conv *);
+static int win_strncat_from_utf16le(struct archive_string *, const void *, size_t,
+ struct archive_string_conv *);
+static int win_strncat_to_utf16be(struct archive_string *, const void *, size_t,
+ struct archive_string_conv *);
+static int win_strncat_to_utf16le(struct archive_string *, const void *, size_t,
+ struct archive_string_conv *);
+#endif
+static int best_effort_strncat_from_utf16be(struct archive_string *, const void *,
+ size_t, struct archive_string_conv *);
+static int best_effort_strncat_from_utf16le(struct archive_string *, const void *,
+ size_t, struct archive_string_conv *);
+static int best_effort_strncat_to_utf16be(struct archive_string *, const void *,
+ size_t, struct archive_string_conv *);
+static int best_effort_strncat_to_utf16le(struct archive_string *, const void *,
+ size_t, struct archive_string_conv *);
+#if defined(HAVE_ICONV)
+static int iconv_strncat_in_locale(struct archive_string *, const void *,
+ size_t, struct archive_string_conv *);
+#endif
+static int best_effort_strncat_in_locale(struct archive_string *, const void *,
+ size_t, struct archive_string_conv *);
+static int _utf8_to_unicode(uint32_t *, const char *, size_t);
+static int utf8_to_unicode(uint32_t *, const char *, size_t);
+static inline uint32_t combine_surrogate_pair(uint32_t, uint32_t);
+static int cesu8_to_unicode(uint32_t *, const char *, size_t);
+static size_t unicode_to_utf8(char *, size_t, uint32_t);
+static int utf16_to_unicode(uint32_t *, const char *, size_t, int);
+static size_t unicode_to_utf16be(char *, size_t, uint32_t);
+static size_t unicode_to_utf16le(char *, size_t, uint32_t);
+static int strncat_from_utf8_libarchive2(struct archive_string *,
+ const void *, size_t, struct archive_string_conv *);
+static int strncat_from_utf8_to_utf8(struct archive_string *, const void *,
+ size_t, struct archive_string_conv *);
+static int archive_string_normalize_C(struct archive_string *, const void *,
+ size_t, struct archive_string_conv *);
+#if defined(__APPLE__)
+static int archive_string_normalize_D(struct archive_string *, const void *,
+ size_t, struct archive_string_conv *);
+#endif
+static int archive_string_append_unicode(struct archive_string *,
+ const void *, size_t, struct archive_string_conv *);
+
+static struct archive_string *
+archive_string_append(struct archive_string *as, const char *p, size_t s)
{
- if (__archive_string_ensure(as, as->length + s + 1) == NULL)
- __archive_errx(1, "Out of memory");
+ if (archive_string_ensure(as, as->length + s + 1) == NULL)
+ return (NULL);
memcpy(as->s + as->length, p, s);
- as->s[as->length + s] = 0;
as->length += s;
+ as->s[as->length] = 0;
+ return (as);
+}
+
+static struct archive_wstring *
+archive_wstring_append(struct archive_wstring *as, const wchar_t *p, size_t s)
+{
+ if (archive_wstring_ensure(as, as->length + s + 1) == NULL)
+ return (NULL);
+ wmemcpy(as->s + as->length, p, s);
+ as->length += s;
+ as->s[as->length] = 0;
return (as);
}
void
-__archive_string_copy(struct archive_string *dest, struct archive_string *src)
+archive_string_concat(struct archive_string *dest, struct archive_string *src)
{
- if (src->length == 0)
- dest->length = 0;
- else {
- if (__archive_string_ensure(dest, src->length + 1) == NULL)
- __archive_errx(1, "Out of memory");
- memcpy(dest->s, src->s, src->length);
- dest->length = src->length;
- dest->s[dest->length] = 0;
- }
+ if (archive_string_append(dest, src->s, src->length) == NULL)
+ __archive_errx(1, "Out of memory");
}
void
-__archive_string_concat(struct archive_string *dest, struct archive_string *src)
+archive_wstring_concat(struct archive_wstring *dest, struct archive_wstring *src)
{
- if (src->length > 0) {
- if (__archive_string_ensure(dest, dest->length + src->length + 1) == NULL)
- __archive_errx(1, "Out of memory");
- memcpy(dest->s + dest->length, src->s, src->length);
- dest->length += src->length;
- dest->s[dest->length] = 0;
- }
+ if (archive_wstring_append(dest, src->s, src->length) == NULL)
+ __archive_errx(1, "Out of memory");
}
void
-__archive_string_free(struct archive_string *as)
+archive_string_free(struct archive_string *as)
{
as->length = 0;
as->buffer_length = 0;
- if (as->s != NULL) {
- free(as->s);
- as->s = NULL;
- }
+ free(as->s);
+ as->s = NULL;
+}
+
+void
+archive_wstring_free(struct archive_wstring *as)
+{
+ as->length = 0;
+ as->buffer_length = 0;
+ free(as->s);
+ as->s = NULL;
+}
+
+struct archive_wstring *
+archive_wstring_ensure(struct archive_wstring *as, size_t s)
+{
+ return (struct archive_wstring *)
+ archive_string_ensure((struct archive_string *)as,
+ s * sizeof(wchar_t));
}
/* Returns NULL on any allocation failure. */
struct archive_string *
-__archive_string_ensure(struct archive_string *as, size_t s)
+archive_string_ensure(struct archive_string *as, size_t s)
{
+ char *p;
+ size_t new_length;
+
/* If buffer is already big enough, don't reallocate. */
if (as->s && (s <= as->buffer_length))
return (as);
@@ -112,18 +290,18 @@ __archive_string_ensure(struct archive_string *as, size_t s)
*/
if (as->buffer_length < 32)
/* Start with a minimum 32-character buffer. */
- as->buffer_length = 32;
+ new_length = 32;
else if (as->buffer_length < 8192)
/* Buffers under 8k are doubled for speed. */
- as->buffer_length += as->buffer_length;
+ new_length = as->buffer_length + as->buffer_length;
else {
/* Buffers 8k and over grow by at least 25% each time. */
- size_t old_length = as->buffer_length;
- as->buffer_length += as->buffer_length / 4;
- /* Be safe: If size wraps, release buffer and return NULL. */
- if (as->buffer_length < old_length) {
- free(as->s);
- as->s = NULL;
+ new_length = as->buffer_length + as->buffer_length / 4;
+ /* Be safe: If size wraps, fail. */
+ if (new_length < as->buffer_length) {
+ /* On failure, wipe the string and return NULL. */
+ archive_string_free(as);
+ errno = ENOMEM;/* Make sure errno has ENOMEM. */
return (NULL);
}
}
@@ -132,17 +310,31 @@ __archive_string_ensure(struct archive_string *as, size_t s)
* grow the buffer. In any case, we have to grow it enough to
* hold the request.
*/
- if (as->buffer_length < s)
- as->buffer_length = s;
+ if (new_length < s)
+ new_length = s;
/* Now we can reallocate the buffer. */
- as->s = (char *)realloc(as->s, as->buffer_length);
- if (as->s == NULL)
+ p = (char *)realloc(as->s, new_length);
+ if (p == NULL) {
+ /* On failure, wipe the string and return NULL. */
+ archive_string_free(as);
+ errno = ENOMEM;/* Make sure errno has ENOMEM. */
return (NULL);
+ }
+
+ as->s = p;
+ as->buffer_length = new_length;
return (as);
}
+/*
+ * TODO: See if there's a way to avoid scanning
+ * the source string twice. Then test to see
+ * if it actually helps (remember that we're almost
+ * always called with pretty short arguments, so
+ * such an optimization might not help).
+ */
struct archive_string *
-__archive_strncat(struct archive_string *as, const void *_p, size_t n)
+archive_strncat(struct archive_string *as, const void *_p, size_t n)
{
size_t s;
const char *p, *pp;
@@ -156,263 +348,3114 @@ __archive_strncat(struct archive_string *as, const void *_p, size_t n)
pp++;
s++;
}
- return (__archive_string_append(as, p, s));
+ if ((as = archive_string_append(as, p, s)) == NULL)
+ __archive_errx(1, "Out of memory");
+ return (as);
+}
+
+struct archive_wstring *
+archive_wstrncat(struct archive_wstring *as, const wchar_t *p, size_t n)
+{
+ size_t s;
+ const wchar_t *pp;
+
+ /* Like strlen(p), except won't examine positions beyond p[n]. */
+ s = 0;
+ pp = p;
+ while (s < n && *pp) {
+ pp++;
+ s++;
+ }
+ if ((as = archive_wstring_append(as, p, s)) == NULL)
+ __archive_errx(1, "Out of memory");
+ return (as);
}
struct archive_string *
-__archive_strappend_char(struct archive_string *as, char c)
+archive_strcat(struct archive_string *as, const void *p)
+{
+ /* strcat is just strncat without an effective limit.
+ * Assert that we'll never get called with a source
+ * string over 16MB.
+ * TODO: Review all uses of strcat in the source
+ * and try to replace them with strncat().
+ */
+ return archive_strncat(as, p, 0x1000000);
+}
+
+struct archive_wstring *
+archive_wstrcat(struct archive_wstring *as, const wchar_t *p)
{
- return (__archive_string_append(as, &c, 1));
+ /* Ditto. */
+ return archive_wstrncat(as, p, 0x1000000);
+}
+
+struct archive_string *
+archive_strappend_char(struct archive_string *as, char c)
+{
+ if ((as = archive_string_append(as, &c, 1)) == NULL)
+ __archive_errx(1, "Out of memory");
+ return (as);
+}
+
+struct archive_wstring *
+archive_wstrappend_wchar(struct archive_wstring *as, wchar_t c)
+{
+ if ((as = archive_wstring_append(as, &c, 1)) == NULL)
+ __archive_errx(1, "Out of memory");
+ return (as);
}
/*
- * Translates a wide character string into UTF-8 and appends
- * to the archive_string. Note: returns NULL if conversion fails,
- * but still leaves a best-effort conversion in the argument as.
+ * Get the "current character set" name to use with iconv.
+ * On FreeBSD, the empty character set name "" chooses
+ * the correct character encoding for the current locale,
+ * so this isn't necessary.
+ * But iconv on Mac OS 10.6 doesn't seem to handle this correctly;
+ * on that system, we have to explicitly call nl_langinfo()
+ * to get the right name. Not sure about other platforms.
+ *
+ * NOTE: GNU libiconv does not recognize the character-set name
+ * which some platform nl_langinfo(CODESET) returns, so we should
+ * use locale_charset() instead of nl_langinfo(CODESET) for GNU libiconv.
*/
-struct archive_string *
-__archive_strappend_w_utf8(struct archive_string *as, const wchar_t *w)
+static const char *
+default_iconv_charset(const char *charset) {
+ if (charset != NULL && charset[0] != '\0')
+ return charset;
+#if HAVE_LOCALE_CHARSET && !defined(__APPLE__)
+ /* locale_charset() is broken on Mac OS */
+ return locale_charset();
+#elif HAVE_NL_LANGINFO
+ return nl_langinfo(CODESET);
+#else
+ return "";
+#endif
+}
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+
+/*
+ * Convert MBS to WCS.
+ * Note: returns -1 if conversion fails.
+ */
+int
+archive_wstring_append_from_mbs(struct archive_wstring *dest,
+ const char *p, size_t len)
{
- char *p;
- unsigned wc;
- char buff[256];
- struct archive_string *return_val = as;
-
- /*
- * Convert one wide char at a time into 'buff', whenever that
- * fills, append it to the string.
- */
- p = buff;
- while (*w != L'\0') {
- /* Flush the buffer when we have <=16 bytes free. */
- /* (No encoding has a single character >16 bytes.) */
- if ((size_t)(p - buff) >= (size_t)(sizeof(buff) - 16)) {
- *p = '\0';
- archive_strcat(as, buff);
- p = buff;
- }
- wc = *w++;
- /* If this is a surrogate pair, assemble the full code point.*/
- /* Note: wc must not be wchar_t here, because the full code
- * point can be more than 16 bits! */
- if (wc >= 0xD800 && wc <= 0xDBff
- && *w >= 0xDC00 && *w <= 0xDFFF) {
- wc -= 0xD800;
- wc *= 0x400;
- wc += (*w - 0xDC00);
- wc += 0x10000;
- ++w;
- }
- /* Translate code point to UTF8 */
- if (wc <= 0x7f) {
- *p++ = (char)wc;
- } else if (wc <= 0x7ff) {
- *p++ = 0xc0 | ((wc >> 6) & 0x1f);
- *p++ = 0x80 | (wc & 0x3f);
- } else if (wc <= 0xffff) {
- *p++ = 0xe0 | ((wc >> 12) & 0x0f);
- *p++ = 0x80 | ((wc >> 6) & 0x3f);
- *p++ = 0x80 | (wc & 0x3f);
- } else if (wc <= 0x1fffff) {
- *p++ = 0xf0 | ((wc >> 18) & 0x07);
- *p++ = 0x80 | ((wc >> 12) & 0x3f);
- *p++ = 0x80 | ((wc >> 6) & 0x3f);
- *p++ = 0x80 | (wc & 0x3f);
+ int r = archive_wstring_append_from_mbs_in_codepage(dest, p, len, NULL);
+ if (r != 0 && errno == ENOMEM)
+ __archive_errx(1, "No memory");
+ return (r);
+}
+
+static int
+archive_wstring_append_from_mbs_in_codepage(struct archive_wstring *dest,
+ const char *s, size_t length, struct archive_string_conv *sc)
+{
+ int count, ret = 0;
+ UINT from_cp;
+
+ if (sc != NULL)
+ from_cp = sc->from_cp;
+ else
+ from_cp = get_current_codepage();
+
+ if (from_cp == CP_C_LOCALE) {
+ /*
+ * "C" locale special process.
+ */
+ wchar_t *ws;
+ const unsigned char *mp;
+
+ if (NULL == archive_wstring_ensure(dest,
+ dest->length + length + 1))
+ return (-1);
+
+ ws = dest->s + dest->length;
+ mp = (const unsigned char *)s;
+ count = 0;
+ while (count < (int)length && *mp) {
+ *ws++ = (wchar_t)*mp++;
+ count++;
+ }
+ } else if (sc != NULL && (sc->flag & SCONV_NORMALIZATION_C)) {
+ /*
+ * Normalize UTF-8 and UTF-16BE and convert it directly
+ * to UTF-16 as wchar_t.
+ */
+ struct archive_string u16;
+ int saved_flag = sc->flag;/* save current flag. */
+
+ if (is_big_endian())
+ sc->flag |= SCONV_TO_UTF16BE;
+ else
+ sc->flag |= SCONV_TO_UTF16LE;
+
+ if (sc->flag & SCONV_FROM_UTF16) {
+ /*
+ * UTF-16BE/LE NFD ===> UTF-16 NFC
+ */
+ count = utf16nbytes(s, length);
} else {
- /* Unicode has no codes larger than 0x1fffff. */
- /* TODO: use \uXXXX escape here instead of ? */
- *p++ = '?';
- return_val = NULL;
+ /*
+ * UTF-8 NFD ===> UTF-16 NFC
+ */
+ count = mbsnbytes(s, length);
+ }
+ u16.s = (char *)dest->s;
+ u16.length = dest->length << 1;;
+ u16.buffer_length = dest->buffer_length;
+ ret = archive_string_normalize_C(&u16, s, count, sc);
+ dest->s = (wchar_t *)u16.s;
+ dest->length = u16.length >> 1;
+ dest->buffer_length = u16.buffer_length;
+ sc->flag = saved_flag;/* restore the saved flag. */
+ return (ret);
+ } else if (sc != NULL && (sc->flag & SCONV_FROM_UTF16)) {
+ count = utf16nbytes(s, length);
+ count >>= 1; /* to be WCS length */
+ /* Allocate memory for WCS. */
+ if (NULL == archive_wstring_ensure(dest,
+ dest->length + count + 1))
+ return (-1);
+ wmemcpy(dest->s + dest->length, (wchar_t *)s, count);
+ if ((sc->flag & SCONV_FROM_UTF16BE) && !is_big_endian()) {
+ uint16_t *u16 = (uint16_t *)(dest->s + dest->length);
+ int b;
+ for (b = 0; b < count; b++) {
+ uint16_t val = archive_le16dec(u16+b);
+ archive_be16enc(u16+b, val);
+ }
+ } else if ((sc->flag & SCONV_FROM_UTF16LE) && is_big_endian()) {
+ uint16_t *u16 = (uint16_t *)(dest->s + dest->length);
+ int b;
+ for (b = 0; b < count; b++) {
+ uint16_t val = archive_be16dec(u16+b);
+ archive_le16enc(u16+b, val);
+ }
+ }
+ } else {
+ DWORD mbflag;
+
+ if (sc == NULL)
+ mbflag = 0;
+ else if (sc->flag & SCONV_FROM_CHARSET) {
+ /* Do not trust the length which comes from
+ * an archive file. */
+ length = mbsnbytes(s, length);
+ mbflag = 0;
+ } else
+ mbflag = MB_PRECOMPOSED;
+
+ if (length == 0) {
+ /*
+ * We do not need to convert any characters but make
+ * sure `dest' has a valid buffer(no NULL pointer).
+ */
+ if (NULL == archive_wstring_ensure(dest,
+ dest->length + 1))
+ return (-1);
+ dest->s[dest->length] = L'\0';
+ return (0);
+ }
+
+ /*
+ * Count how many bytes are needed for WCS.
+ */
+ count = MultiByteToWideChar(from_cp,
+ mbflag, s, length, NULL, 0);
+ if (count == 0) {
+ if (dest->s == NULL) {
+ if (NULL == archive_wstring_ensure(dest,
+ dest->length + 1))
+ return (-1);
+ }
+ dest->s[dest->length] = L'\0';
+ return (-1);
}
+ /* Allocate memory for WCS. */
+ if (NULL == archive_wstring_ensure(dest,
+ dest->length + count + 1))
+ return (-1);
+ /* Convert MBS to WCS. */
+ count = MultiByteToWideChar(from_cp,
+ mbflag, s, length, dest->s + dest->length, count);
+ if (count == 0)
+ ret = -1;
}
- *p = '\0';
- archive_strcat(as, buff);
- return (return_val);
+ dest->length += count;
+ dest->s[dest->length] = L'\0';
+ return (ret);
}
-static int
-utf8_to_unicode(int *pwc, const char *s, size_t n)
+#elif defined(HAVE_MBSNRTOWCS)
+
+/*
+ * Convert MBS to WCS.
+ * Note: returns -1 if conversion fails.
+ */
+int
+archive_wstring_append_from_mbs(struct archive_wstring *dest,
+ const char *p, size_t len)
{
- int ch;
+ size_t r;
+ /*
+ * No single byte will be more than one wide character,
+ * so this length estimate will always be big enough.
+ */
+ size_t wcs_length = len;
+ size_t mbs_length = len;
+ const char *mbs = p;
+ wchar_t *wcs;
+ mbstate_t shift_state;
- /*
- * Decode 1-4 bytes depending on the value of the first byte.
+ memset(&shift_state, 0, sizeof(shift_state));
+ if (NULL == archive_wstring_ensure(dest, dest->length + wcs_length + 1))
+ __archive_errx(1,
+ "No memory for archive_wstring_append_from_mbs()");
+ wcs = dest->s + dest->length;
+ r = mbsnrtowcs(wcs, &mbs, mbs_length, wcs_length, &shift_state);
+ if (r != (size_t)-1) {
+ dest->length += r;
+ dest->s[dest->length] = L'\0';
+ return (0);
+ }
+ dest->s[dest->length] = L'\0';
+ return (-1);
+}
+
+#else
+
+/*
+ * Convert MBS to WCS.
+ * Note: returns -1 if conversion fails.
+ */
+int
+archive_wstring_append_from_mbs(struct archive_wstring *dest,
+ const char *p, size_t len)
+{
+ size_t r;
+ /*
+ * No single byte will be more than one wide character,
+ * so this length estimate will always be big enough.
*/
- ch = (unsigned char)*s;
- if (ch == 0) {
- return (0); /* Standard: return 0 for end-of-string. */
+ size_t wcs_length = len;
+ size_t mbs_length = len;
+ const char *mbs = p;
+ wchar_t *wcs;
+#if HAVE_MBRTOWC
+ mbstate_t shift_state;
+
+ memset(&shift_state, 0, sizeof(shift_state));
+#endif
+ if (NULL == archive_wstring_ensure(dest, dest->length + wcs_length + 1))
+ __archive_errx(1,
+ "No memory for archive_wstring_append_from_mbs()");
+ wcs = dest->s + dest->length;
+ /*
+ * We cannot use mbsrtowcs/mbstowcs here because those may convert
+ * extra MBS when strlen(p) > len and one wide character consis of
+ * multi bytes.
+ */
+ while (wcs_length > 0 && *mbs && mbs_length > 0) {
+#if HAVE_MBRTOWC
+ r = mbrtowc(wcs, mbs, wcs_length, &shift_state);
+#else
+ r = mbtowc(wcs, mbs, wcs_length);
+#endif
+ if (r == (size_t)-1 || r == (size_t)-2) {
+ dest->s[dest->length] = L'\0';
+ return (-1);
+ }
+ if (r == 0 || r > mbs_length)
+ break;
+ wcs++;
+ wcs_length--;
+ mbs += r;
+ mbs_length -= r;
}
- if ((ch & 0x80) == 0) {
- *pwc = ch & 0x7f;
- return (1);
- }
- if ((ch & 0xe0) == 0xc0) {
- if (n < 2)
+ dest->length = wcs - dest->s;
+ dest->s[dest->length] = L'\0';
+ return (0);
+}
+
+#endif
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+
+/*
+ * WCS ==> MBS.
+ * Note: returns -1 if conversion fails.
+ *
+ * Win32 builds use WideCharToMultiByte from the Windows API.
+ * (Maybe Cygwin should too? WideCharToMultiByte will know a
+ * lot more about local character encodings than the wcrtomb()
+ * wrapper is going to know.)
+ */
+int
+archive_string_append_from_wcs(struct archive_string *as,
+ const wchar_t *w, size_t len)
+{
+ int r = archive_string_append_from_wcs_in_codepage(as, w, len, NULL);
+ if (r != 0 && errno == ENOMEM)
+ __archive_errx(1, "No memory");
+ return (r);
+}
+
+static int
+archive_string_append_from_wcs_in_codepage(struct archive_string *as,
+ const wchar_t *ws, size_t len, struct archive_string_conv *sc)
+{
+ BOOL defchar_used, *dp;
+ int count, ret = 0;
+ UINT to_cp;
+ int wslen = (int)len;
+
+ if (sc != NULL)
+ to_cp = sc->to_cp;
+ else
+ to_cp = get_current_codepage();
+
+ if (to_cp == CP_C_LOCALE) {
+ /*
+ * "C" locale special process.
+ */
+ const wchar_t *wp = ws;
+ char *p;
+
+ if (NULL == archive_string_ensure(as,
+ as->length + wslen +1))
return (-1);
- if ((s[1] & 0xc0) != 0x80) return (-1);
- *pwc = ((ch & 0x1f) << 6) | (s[1] & 0x3f);
- return (2);
- }
- if ((ch & 0xf0) == 0xe0) {
- if (n < 3)
+ p = as->s + as->length;
+ count = 0;
+ defchar_used = 0;
+ while (count < wslen && *wp) {
+ if (*wp > 255) {
+ *p++ = '?';
+ wp++;
+ defchar_used = 1;
+ } else
+ *p++ = (char)*wp++;
+ count++;
+ }
+ } else if (sc != NULL && (sc->flag & SCONV_TO_UTF16)) {
+ uint16_t *u16;
+
+ if (NULL ==
+ archive_string_ensure(as, as->length + len * 2 + 2))
return (-1);
- if ((s[1] & 0xc0) != 0x80) return (-1);
- if ((s[2] & 0xc0) != 0x80) return (-1);
- *pwc = ((ch & 0x0f) << 12)
- | ((s[1] & 0x3f) << 6)
- | (s[2] & 0x3f);
- return (3);
- }
- if ((ch & 0xf8) == 0xf0) {
- if (n < 4)
+ u16 = (uint16_t *)(as->s + as->length);
+ count = 0;
+ defchar_used = 0;
+ if (sc->flag & SCONV_TO_UTF16BE) {
+ while (count < (int)len && *ws) {
+ archive_be16enc(u16+count, *ws);
+ ws++;
+ count++;
+ }
+ } else {
+ while (count < (int)len && *ws) {
+ archive_le16enc(u16+count, *ws);
+ ws++;
+ count++;
+ }
+ }
+ count <<= 1; /* to be byte size */
+ } else {
+ /* Make sure the MBS buffer has plenty to set. */
+ if (NULL ==
+ archive_string_ensure(as, as->length + len * 2 + 1))
return (-1);
- if ((s[1] & 0xc0) != 0x80) return (-1);
- if ((s[2] & 0xc0) != 0x80) return (-1);
- if ((s[3] & 0xc0) != 0x80) return (-1);
- *pwc = ((ch & 0x07) << 18)
- | ((s[1] & 0x3f) << 12)
- | ((s[2] & 0x3f) << 6)
- | (s[3] & 0x3f);
- return (4);
- }
- /* Invalid first byte. */
- return (-1);
+ do {
+ defchar_used = 0;
+ if (to_cp == CP_UTF8 || sc == NULL)
+ dp = NULL;
+ else
+ dp = &defchar_used;
+ count = WideCharToMultiByte(to_cp, 0, ws, wslen,
+ as->s + as->length, as->buffer_length-1, NULL, dp);
+ if (count == 0 &&
+ GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+ /* Expand the MBS buffer and retry. */
+ if (NULL == archive_string_ensure(as,
+ as->buffer_length + len))
+ return (-1);
+ continue;
+ }
+ if (count == 0)
+ ret = -1;
+ } while (0);
+ }
+ as->length += count;
+ as->s[as->length] = '\0';
+ return (defchar_used?-1:ret);
}
+#elif defined(HAVE_WCSNRTOMBS)
+
/*
- * Return a wide-character Unicode string by converting this archive_string
- * from UTF-8. We assume that systems with 16-bit wchar_t always use
- * UTF16 and systems with 32-bit wchar_t can accept UCS4.
+ * Translates a wide character string into current locale character set
+ * and appends to the archive_string. Note: returns -1 if conversion
+ * fails.
*/
-wchar_t *
-__archive_string_utf8_w(struct archive_string *as)
+int
+archive_string_append_from_wcs(struct archive_string *as,
+ const wchar_t *w, size_t len)
{
- wchar_t *ws, *dest;
- int wc, wc2;/* Must be large enough for a 21-bit Unicode code point. */
- const char *src;
- int n;
+ mbstate_t shift_state;
+ size_t r, ndest, nwc;
+ char *dest;
+ const wchar_t *wp, *wpp;
+ int ret_val = 0;
- ws = (wchar_t *)malloc((as->length + 1) * sizeof(wchar_t));
- if (ws == NULL)
- __archive_errx(1, "Out of memory");
- dest = ws;
- src = as->s;
- while (*src != '\0') {
- n = utf8_to_unicode(&wc, src, 8);
- if (n == 0)
+ wp = w;
+ nwc = len;
+ ndest = len * 2;
+ /* Initialize the shift state. */
+ memset(&shift_state, 0, sizeof(shift_state));
+ while (nwc > 0) {
+ /* Allocate buffer for MBS. */
+ if (archive_string_ensure(as, as->length + ndest + 1) == NULL)
+ __archive_errx(1, "Out of memory");
+
+ dest = as->s + as->length;
+ wpp = wp;
+ r = wcsnrtombs(dest, &wp, nwc,
+ as->buffer_length - as->length -1,
+ &shift_state);
+ if (r == (size_t)-1) {
+ if (errno == EILSEQ) {
+ /* Retry conversion just for safe WCS. */
+ size_t xwc = wp - wpp;
+ wp = wpp;
+ r = wcsnrtombs(dest, &wp, xwc,
+ as->buffer_length - as->length -1,
+ &shift_state);
+ if (r == (size_t)-1)
+ /* This would not happen. */
+ return (-1);
+ as->length += r;
+ nwc -= wp - wpp;
+ /* Skip an illegal wide char. */
+ as->s[as->length++] = '?';
+ wp++;
+ nwc--;
+ ret_val = -1;
+ continue;
+ } else {
+ ret_val = -1;
+ break;
+ }
+ }
+ as->length += r;
+ if (wp == NULL || (wp - wpp) >= nwc)
break;
- if (n < 0) {
- free(ws);
- return (NULL);
+ /* Get a remaining WCS lenth. */
+ nwc -= wp - wpp;
+ }
+ /* All wide characters are translated to MBS. */
+ as->s[as->length] = '\0';
+ return (ret_val);
+}
+
+#elif defined(HAVE_WCTOMB) || defined(HAVE_WCRTOMB)
+
+/*
+ * Translates a wide character string into current locale character set
+ * and appends to the archive_string. Note: returns -1 if conversion
+ * fails.
+ */
+int
+archive_string_append_from_wcs(struct archive_string *as,
+ const wchar_t *w, size_t len)
+{
+ /* We cannot use the standard wcstombs() here because it
+ * cannot tell us how big the output buffer should be. So
+ * I've built a loop around wcrtomb() or wctomb() that
+ * converts a character at a time and resizes the string as
+ * needed. We prefer wcrtomb() when it's available because
+ * it's thread-safe. */
+ int n, ret_val = 0;
+ char *p;
+ char *end;
+#if HAVE_WCRTOMB
+ mbstate_t shift_state;
+
+ memset(&shift_state, 0, sizeof(shift_state));
+#else
+ /* Clear the shift state before starting. */
+ wctomb(NULL, L'\0');
+#endif
+ /*
+ * Allocate buffer for MBS.
+ * We need this allocation here since it is possible that
+ * as->s is still NULL.
+ */
+ if (archive_string_ensure(as, as->length + len + 1) == NULL)
+ __archive_errx(1, "Out of memory");
+
+ p = as->s + as->length;
+ end = as->s + as->buffer_length - MB_CUR_MAX -1;
+ while (*w != L'\0' && len > 0) {
+ if (p >= end) {
+ as->length = p - as->s;
+ as->s[as->length] = '\0';
+ /* Re-allocate buffer for MBS. */
+ if (archive_string_ensure(as,
+ as->length + len * 2 + 1) == NULL)
+ __archive_errx(1, "Out of memory");
+ p = as->s + as->length;
+ end = as->s + as->buffer_length - MB_CUR_MAX -1;
}
- src += n;
- if (wc >= 0xDC00 && wc <= 0xDBFF) {
- /* This is a leading surrogate; some idiot
- * has translated UTF16 to UTF8 without combining
- * surrogates; rebuild the full code point before
- * continuing. */
- n = utf8_to_unicode(&wc2, src, 8);
- if (n < 0) {
- free(ws);
- return (NULL);
- }
- if (n == 0) /* Ignore the leading surrogate */
- break;
- if (wc2 < 0xDC00 || wc2 > 0xDFFF) {
- /* If the second character isn't a
- * trailing surrogate, then someone
- * has really screwed up and this is
- * invalid. */
- free(ws);
- return (NULL);
+#if HAVE_WCRTOMB
+ n = wcrtomb(p, *w++, &shift_state);
+#else
+ n = wctomb(p, *w++);
+#endif
+ if (n == -1) {
+ if (errno == EILSEQ) {
+ /* Skip an illegal wide char. */
+ *p++ = '?';
+ ret_val = -1;
} else {
- src += n;
- wc -= 0xD800;
- wc *= 0x400;
- wc += wc2 - 0xDC00;
- wc += 0x10000;
+ ret_val = -1;
+ break;
}
+ } else
+ p += n;
+ len--;
+ }
+ as->length = p - as->s;
+ as->s[as->length] = '\0';
+ return (ret_val);
+}
+
+#else /* HAVE_WCTOMB || HAVE_WCRTOMB */
+
+/*
+ * TODO: Test if __STDC_ISO_10646__ is defined.
+ * Non-Windows uses ISO C wcrtomb() or wctomb() to perform the conversion
+ * one character at a time. If a non-Windows platform doesn't have
+ * either of these, fall back to the built-in UTF8 conversion.
+ */
+int
+archive_string_append_from_wcs(struct archive_string *as,
+ const wchar_t *w, size_t len)
+{
+ (void)as;/* UNUSED */
+ (void)w;/* UNUSED */
+ (void)len;/* UNUSED */
+ return (-1);
+}
+
+#endif /* HAVE_WCTOMB || HAVE_WCRTOMB */
+
+/*
+ * Find a string conversion object by a pair of 'from' charset name
+ * and 'to' charset name from an archive object.
+ * Return NULL if not found.
+ */
+static struct archive_string_conv *
+find_sconv_object(struct archive *a, const char *fc, const char *tc)
+{
+ struct archive_string_conv *sc;
+
+ if (a == NULL)
+ return (NULL);
+
+ for (sc = a->sconv; sc != NULL; sc = sc->next) {
+ if (strcmp(sc->from_charset, fc) == 0 &&
+ strcmp(sc->to_charset, tc) == 0)
+ break;
+ }
+ return (sc);
+}
+
+/*
+ * Register a string object to an archive object.
+ */
+static void
+add_sconv_object(struct archive *a, struct archive_string_conv *sc)
+{
+ struct archive_string_conv **psc;
+
+ /* Add a new sconv to sconv list. */
+ psc = &(a->sconv);
+ while (*psc != NULL)
+ psc = &((*psc)->next);
+ *psc = sc;
+}
+
+#if defined(__APPLE__)
+
+static int
+createUniInfo(struct archive_string_conv *sconv)
+{
+ UnicodeMapping map;
+ OSStatus err;
+
+ map.unicodeEncoding = CreateTextEncoding(kTextEncodingUnicodeDefault,
+ kUnicodeNoSubset, kUnicode16BitFormat);
+ map.otherEncoding = CreateTextEncoding(kTextEncodingUnicodeDefault,
+ kUnicodeHFSPlusDecompVariant, kUnicode16BitFormat);
+ map.mappingVersion = kUnicodeUseLatestMapping;
+
+ sconv->uniInfo = NULL;
+ err = CreateUnicodeToTextInfo(&map, &(sconv->uniInfo));
+ return ((err == noErr)? 0: -1);
+}
+
+#endif /* __APPLE__ */
+
+static void
+add_converter(struct archive_string_conv *sc, int (*converter)
+ (struct archive_string *, const void *, size_t,
+ struct archive_string_conv *))
+{
+ if (sc == NULL || sc->nconverter >= 2)
+ __archive_errx(1, "Programing error");
+ sc->converter[sc->nconverter++] = converter;
+}
+
+static void
+setup_converter(struct archive_string_conv *sc)
+{
+
+ /* Reset. */
+ sc->nconverter = 0;
+
+ /*
+ * Perform special sequence for the incorrect UTF-8 filenames
+ * made by libarchive2.x.
+ */
+ if (sc->flag & SCONV_UTF8_LIBARCHIVE_2) {
+ add_converter(sc, strncat_from_utf8_libarchive2);
+ return;
+ }
+
+ /*
+ * Convert a string to UTF-16BE/LE.
+ */
+ if (sc->flag & SCONV_TO_UTF16) {
+ /*
+ * If the current locale is UTF-8, we can translate
+ * a UTF-8 string into a UTF-16BE string.
+ */
+ if (sc->flag & SCONV_FROM_UTF8) {
+ add_converter(sc, archive_string_append_unicode);
+ return;
+ }
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ if (sc->flag & SCONV_WIN_CP) {
+ if (sc->flag & SCONV_TO_UTF16BE)
+ add_converter(sc, win_strncat_to_utf16be);
+ else
+ add_converter(sc, win_strncat_to_utf16le);
+ return;
+ }
+#endif
+
+#if defined(HAVE_ICONV)
+ if (sc->cd != (iconv_t)-1) {
+ add_converter(sc, iconv_strncat_in_locale);
+ return;
+ }
+#endif
+
+ if (sc->flag & SCONV_BEST_EFFORT) {
+ if (sc->flag & SCONV_TO_UTF16BE)
+ add_converter(sc, best_effort_strncat_to_utf16be);
+ else
+ add_converter(sc, best_effort_strncat_to_utf16le);
+ } else
+ /* Make sure we have no converter. */
+ sc->nconverter = 0;
+ return;
+ }
+
+ /*
+ * Convert a string from UTF-16BE/LE.
+ */
+ if (sc->flag & SCONV_FROM_UTF16) {
+ /*
+ * At least we should normalize a UTF-16BE string.
+ */
+#if defined(__APPLE__)
+ if (sc->flag & SCONV_NORMALIZATION_D)
+ add_converter(sc,archive_string_normalize_D);
+ else
+#endif
+ if (sc->flag & SCONV_NORMALIZATION_C)
+ add_converter(sc, archive_string_normalize_C);
+
+ if (sc->flag & SCONV_TO_UTF8) {
+ /*
+ * If the current locale is UTF-8, we can translate
+ * a UTF-16BE/LE string into a UTF-8 string directly.
+ */
+ if (!(sc->flag &
+ (SCONV_NORMALIZATION_D |SCONV_NORMALIZATION_C)))
+ add_converter(sc,
+ archive_string_append_unicode);
+ return;
+ }
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ if (sc->flag & SCONV_WIN_CP) {
+ if (sc->flag & SCONV_FROM_UTF16BE)
+ add_converter(sc, win_strncat_from_utf16be);
+ else
+ add_converter(sc, win_strncat_from_utf16le);
+ return;
+ }
+#endif
+
+#if defined(HAVE_ICONV)
+ if (sc->cd != (iconv_t)-1) {
+ add_converter(sc, iconv_strncat_in_locale);
+ return;
+ }
+#endif
+
+ if ((sc->flag & (SCONV_BEST_EFFORT | SCONV_FROM_UTF16BE))
+ == (SCONV_BEST_EFFORT | SCONV_FROM_UTF16BE))
+ add_converter(sc, best_effort_strncat_from_utf16be);
+ else if ((sc->flag & (SCONV_BEST_EFFORT | SCONV_FROM_UTF16LE))
+ == (SCONV_BEST_EFFORT | SCONV_FROM_UTF16LE))
+ add_converter(sc, best_effort_strncat_from_utf16le);
+ else
+ /* Make sure we have no converter. */
+ sc->nconverter = 0;
+ return;
+ }
+
+ if (sc->flag & SCONV_FROM_UTF8) {
+ /*
+ * At least we should normalize a UTF-8 string.
+ */
+#if defined(__APPLE__)
+ if (sc->flag & SCONV_NORMALIZATION_D)
+ add_converter(sc,archive_string_normalize_D);
+ else
+#endif
+ if (sc->flag & SCONV_NORMALIZATION_C)
+ add_converter(sc, archive_string_normalize_C);
+
+ /*
+ * Copy UTF-8 string with a check of CESU-8.
+ * Apparently, iconv does not check surrogate pairs in UTF-8
+ * when both from-charset and to-charset are UTF-8, and then
+ * we use our UTF-8 copy code.
+ */
+ if (sc->flag & SCONV_TO_UTF8) {
+ /*
+ * If the current locale is UTF-8, we can translate
+ * a UTF-16BE string into a UTF-8 string directly.
+ */
+ if (!(sc->flag &
+ (SCONV_NORMALIZATION_D |SCONV_NORMALIZATION_C)))
+ add_converter(sc, strncat_from_utf8_to_utf8);
+ return;
}
- if ((sizeof(wchar_t) < 4) && (wc > 0xffff)) {
- /* We have a code point that won't fit into a
- * wchar_t; convert it to a surrogate pair. */
- wc -= 0x10000;
- *dest++ = ((wc >> 10) & 0x3ff) + 0xD800;
- *dest++ = (wc & 0x3ff) + 0xDC00;
+ }
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ /*
+ * On Windows we can use Windows API for a string conversion.
+ */
+ if (sc->flag & SCONV_WIN_CP) {
+ add_converter(sc, strncat_in_codepage);
+ return;
+ }
+#endif
+
+#if HAVE_ICONV
+ if (sc->cd != (iconv_t)-1) {
+ add_converter(sc, iconv_strncat_in_locale);
+ return;
+ }
+#endif
+
+ /*
+ * Try conversion in the best effort or no conversion.
+ */
+ if ((sc->flag & SCONV_BEST_EFFORT) || sc->same)
+ add_converter(sc, best_effort_strncat_in_locale);
+ else
+ /* Make sure we have no converter. */
+ sc->nconverter = 0;
+}
+
+/*
+ * Return canonicalized charset-name but this supports just UTF-8, UTF-16BE
+ * and CP932 which are referenced in create_sconv_object().
+ */
+static const char *
+canonical_charset_name(const char *charset)
+{
+ char cs[16];
+ char *p;
+ const char *s;
+
+ if (charset == NULL || charset[0] == '\0'
+ || strlen(charset) > 15)
+ return (charset);
+
+ /* Copy name to uppercase. */
+ p = cs;
+ s = charset;
+ while (*s) {
+ char c = *s++;
+ if (c >= 'a' && c <= 'z')
+ c -= 'a' - 'A';
+ *p++ = c;
+ }
+ *p++ = '\0';
+
+ if (strcmp(cs, "UTF-8") == 0 ||
+ strcmp(cs, "UTF8") == 0)
+ return ("UTF-8");
+ if (strcmp(cs, "UTF-16BE") == 0 ||
+ strcmp(cs, "UTF16BE") == 0)
+ return ("UTF-16BE");
+ if (strcmp(cs, "UTF-16LE") == 0 ||
+ strcmp(cs, "UTF16LE") == 0)
+ return ("UTF-16LE");
+ if (strcmp(cs, "CP932") == 0)
+ return ("CP932");
+ return (charset);
+}
+
+/*
+ * Create a string conversion object.
+ */
+static struct archive_string_conv *
+create_sconv_object(const char *fc, const char *tc,
+ unsigned current_codepage, int flag)
+{
+ struct archive_string_conv *sc;
+
+ sc = calloc(1, sizeof(*sc));
+ if (sc == NULL)
+ return (NULL);
+ sc->next = NULL;
+ sc->from_charset = strdup(fc);
+ if (sc->from_charset == NULL) {
+ free(sc);
+ return (NULL);
+ }
+ sc->to_charset = strdup(tc);
+ if (sc->to_charset == NULL) {
+ free(sc);
+ free(sc->from_charset);
+ return (NULL);
+ }
+ archive_string_init(&sc->utftmp);
+#if defined(__APPLE__)
+ archive_string_init(&sc->utf16nfc);
+ archive_string_init(&sc->utf16nfd);
+#endif
+
+ if (flag & SCONV_TO_CHARSET) {
+ /*
+ * Convert characters from the current locale charset to
+ * a specified charset.
+ */
+ sc->from_cp = current_codepage;
+ sc->to_cp = make_codepage_from_charset(tc);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ if (IsValidCodePage(sc->to_cp))
+ flag |= SCONV_WIN_CP;
+#endif
+ } else if (flag & SCONV_FROM_CHARSET) {
+ /*
+ * Convert characters from a specified charset to
+ * the current locale charset.
+ */
+ sc->to_cp = current_codepage;
+ sc->from_cp = make_codepage_from_charset(fc);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ if (IsValidCodePage(sc->from_cp))
+ flag |= SCONV_WIN_CP;
+#endif
+ }
+
+ /*
+ * Check if "from charset" and "to charset" are the same.
+ */
+ if (strcmp(fc, tc) == 0 ||
+ (sc->from_cp != -1 && sc->from_cp == sc->to_cp))
+ sc->same = 1;
+ else
+ sc->same = 0;
+
+ /*
+ * Mark if "from charset" or "to charset" are UTF-8 or UTF-16BE/LE.
+ */
+ if (strcmp(tc, "UTF-8") == 0)
+ flag |= SCONV_TO_UTF8;
+ else if (strcmp(tc, "UTF-16BE") == 0)
+ flag |= SCONV_TO_UTF16BE;
+ else if (strcmp(tc, "UTF-16LE") == 0)
+ flag |= SCONV_TO_UTF16LE;
+ if (strcmp(fc, "UTF-8") == 0)
+ flag |= SCONV_FROM_UTF8;
+ else if (strcmp(fc, "UTF-16BE") == 0)
+ flag |= SCONV_FROM_UTF16BE;
+ else if (strcmp(fc, "UTF-16LE") == 0)
+ flag |= SCONV_FROM_UTF16LE;
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ if (sc->to_cp == CP_UTF8)
+ flag |= SCONV_TO_UTF8;
+ else if (sc->to_cp == CP_UTF16BE)
+ flag |= SCONV_TO_UTF16BE | SCONV_WIN_CP;
+ else if (sc->to_cp == CP_UTF16LE)
+ flag |= SCONV_TO_UTF16LE | SCONV_WIN_CP;
+ if (sc->from_cp == CP_UTF8)
+ flag |= SCONV_FROM_UTF8;
+ else if (sc->from_cp == CP_UTF16BE)
+ flag |= SCONV_FROM_UTF16BE | SCONV_WIN_CP;
+ else if (sc->from_cp == CP_UTF16LE)
+ flag |= SCONV_FROM_UTF16LE | SCONV_WIN_CP;
+#endif
+
+ /*
+ * Set a flag for Unicode NFD. Usually iconv cannot correctly
+ * handle it. So we have to translate NFD characters to NFC ones
+ * ourselves before iconv handles. Another reason is to prevent
+ * that the same sight of two filenames, one is NFC and other
+ * is NFD, would be in its directory.
+ * On Mac OS X, although its filesystem layer automatically
+ * convert filenames to NFD, it would be useful for filename
+ * comparing to find out the same filenames that we normalize
+ * that to be NFD ourselves.
+ */
+ if ((flag & SCONV_FROM_CHARSET) &&
+ (flag & (SCONV_FROM_UTF16 | SCONV_FROM_UTF8))) {
+#if defined(__APPLE__)
+ if (flag & SCONV_TO_UTF8) {
+ if (createUniInfo(sc) == 0)
+ flag |= SCONV_NORMALIZATION_D;
} else
- *dest++ = wc;
+#endif
+ flag |= SCONV_NORMALIZATION_C;
}
- *dest = L'\0';
- return (ws);
+
+#if defined(HAVE_ICONV)
+ sc->cd_w = (iconv_t)-1;
+ /*
+ * Create an iconv object.
+ */
+ if (((flag & (SCONV_TO_UTF8 | SCONV_TO_UTF16)) &&
+ (flag & (SCONV_FROM_UTF8 | SCONV_FROM_UTF16))) ||
+ (flag & SCONV_WIN_CP)) {
+ /* This case we won't use iconv. */
+ sc->cd = (iconv_t)-1;
+#if defined(__APPLE__)
+ } else if ((flag & SCONV_FROM_CHARSET) && (flag & SCONV_TO_UTF8)) {
+ /*
+ * In case reading an archive file.
+ * Translate non-Unicode filenames in an archive file to
+ * UTF-8-MAC filenames.
+ */
+ sc->cd = iconv_open("UTF-8-MAC", fc);
+ if (sc->cd == (iconv_t)-1) {
+ if ((sc->flag & SCONV_BEST_EFFORT) &&
+ strcmp(fc, "CP932") == 0) {
+ sc->cd = iconv_open("UTF-8-MAC", "SJIS");
+ if (sc->cd == (iconv_t)-1) {
+ sc->cd = iconv_open(tc, fc);
+ if (sc->cd == (iconv_t)-1)
+ sc->cd = iconv_open(tc, "SJIS");
+ }
+ } else
+ sc->cd = iconv_open(tc, fc);
+ }
+ } else if ((flag & SCONV_TO_CHARSET) && (flag & SCONV_FROM_UTF8)) {
+ /*
+ * In case writing an archive file.
+ * Translate UTF-8-MAC filenames in HFS Plus to non-Unicode
+ * filenames.
+ */
+ sc->cd = iconv_open(tc, "UTF-8-MAC");
+ if (sc->cd == (iconv_t)-1) {
+ if ((sc->flag & SCONV_BEST_EFFORT) &&
+ strcmp(tc, "CP932") == 0) {
+ sc->cd = iconv_open("SJIS", "UTF-8-MAC");
+ if (sc->cd == (iconv_t)-1) {
+ sc->cd = iconv_open(tc, fc);
+ if (sc->cd == (iconv_t)-1)
+ sc->cd = iconv_open("SJIS", fc);
+ }
+ } else
+ sc->cd = iconv_open(tc, fc);
+ }
+#endif
+ } else {
+ sc->cd = iconv_open(tc, fc);
+ if (sc->cd == (iconv_t)-1 && (sc->flag & SCONV_BEST_EFFORT)) {
+ /*
+ * Unfortunaly, all of iconv implements do support
+ * "CP932" character-set, so we should use "SJIS"
+ * instead if iconv_open failed.
+ */
+ if (strcmp(tc, "CP932") == 0)
+ sc->cd = iconv_open("SJIS", fc);
+ else if (strcmp(fc, "CP932") == 0)
+ sc->cd = iconv_open(tc, "SJIS");
+ }
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ /*
+ * archive_mstring on Windows directly convert multi-bytes
+ * into archive_wstring in order not to depend on locale
+ * so that you can do a I18N programing. This will be
+ * used only in archive_mstring_copy_mbs_len_l so far.
+ */
+ if (flag & SCONV_FROM_CHARSET) {
+ sc->cd_w = iconv_open("UTF-8", fc);
+ if (sc->cd_w == (iconv_t)-1 &&
+ (sc->flag & SCONV_BEST_EFFORT)) {
+ if (strcmp(fc, "CP932") == 0)
+ sc->cd_w = iconv_open("UTF-8", "SJIS");
+ }
+ }
+#endif /* _WIN32 && !__CYGWIN__ */
+ }
+#endif /* HAVE_ICONV */
+
+ sc->flag = flag;
+
+ /*
+ * Setup converters.
+ */
+ setup_converter(sc);
+
+ return (sc);
+}
+
+/*
+ * Free a string conversion object.
+ */
+static void
+free_sconv_object(struct archive_string_conv *sc)
+{
+ free(sc->from_charset);
+ free(sc->to_charset);
+ archive_string_free(&sc->utftmp);
+#if HAVE_ICONV
+ if (sc->cd != (iconv_t)-1)
+ iconv_close(sc->cd);
+ if (sc->cd_w != (iconv_t)-1)
+ iconv_close(sc->cd_w);
+#endif
+#if defined(__APPLE__)
+ archive_string_free(&sc->utf16nfc);
+ archive_string_free(&sc->utf16nfd);
+ if (sc->uniInfo != NULL)
+ DisposeUnicodeToTextInfo(&(sc->uniInfo));
+#endif
+ free(sc);
}
#if defined(_WIN32) && !defined(__CYGWIN__)
+static unsigned
+my_atoi(const char *p)
+{
+ unsigned cp;
+
+ cp = 0;
+ while (*p) {
+ if (*p >= '0' && *p <= '9')
+ cp = cp * 10 + (*p - '0');
+ else
+ return (-1);
+ p++;
+ }
+ return (cp);
+}
/*
- * Translates a wide character string into current locale character set
- * and appends to the archive_string. Note: returns NULL if conversion
- * fails.
+ * Translate Charset name (as used by iconv) into CodePage (as used by Windows)
+ * Return -1 if failed.
*
- * Win32 builds use WideCharToMultiByte from the Windows API.
- * (Maybe Cygwin should too? WideCharToMultiByte will know a
- * lot more about local character encodings than the wcrtomb()
- * wrapper is going to know.)
+ * Note: This translation code may be insufficient.
*/
-struct archive_string *
-__archive_strappend_w_mbs(struct archive_string *as, const wchar_t *w)
+static struct charset {
+ const char *name;
+ unsigned cp;
+} charsets[] = {
+ /* MUST BE SORTED! */
+ {"ASCII", 1252},
+ {"ASMO-708", 708},
+ {"BIG5", 950},
+ {"CHINESE", 936},
+ {"CP367", 1252},
+ {"CP819", 1252},
+ {"CP1025", 21025},
+ {"DOS-720", 720},
+ {"DOS-862", 862},
+ {"EUC-CN", 51936},
+ {"EUC-JP", 51932},
+ {"EUC-KR", 949},
+ {"EUCCN", 51936},
+ {"EUCJP", 51932},
+ {"EUCKR", 949},
+ {"GB18030", 54936},
+ {"GB2312", 936},
+ {"HEBREW", 1255},
+ {"HZ-GB-2312", 52936},
+ {"IBM273", 20273},
+ {"IBM277", 20277},
+ {"IBM278", 20278},
+ {"IBM280", 20280},
+ {"IBM284", 20284},
+ {"IBM285", 20285},
+ {"IBM290", 20290},
+ {"IBM297", 20297},
+ {"IBM367", 1252},
+ {"IBM420", 20420},
+ {"IBM423", 20423},
+ {"IBM424", 20424},
+ {"IBM819", 1252},
+ {"IBM871", 20871},
+ {"IBM880", 20880},
+ {"IBM905", 20905},
+ {"IBM924", 20924},
+ {"ISO-8859-1", 28591},
+ {"ISO-8859-13", 28603},
+ {"ISO-8859-15", 28605},
+ {"ISO-8859-2", 28592},
+ {"ISO-8859-3", 28593},
+ {"ISO-8859-4", 28594},
+ {"ISO-8859-5", 28595},
+ {"ISO-8859-6", 28596},
+ {"ISO-8859-7", 28597},
+ {"ISO-8859-8", 28598},
+ {"ISO-8859-9", 28599},
+ {"ISO8859-1", 28591},
+ {"ISO8859-13", 28603},
+ {"ISO8859-15", 28605},
+ {"ISO8859-2", 28592},
+ {"ISO8859-3", 28593},
+ {"ISO8859-4", 28594},
+ {"ISO8859-5", 28595},
+ {"ISO8859-6", 28596},
+ {"ISO8859-7", 28597},
+ {"ISO8859-8", 28598},
+ {"ISO8859-9", 28599},
+ {"JOHAB", 1361},
+ {"KOI8-R", 20866},
+ {"KOI8-U", 21866},
+ {"KS_C_5601-1987", 949},
+ {"LATIN1", 1252},
+ {"LATIN2", 28592},
+ {"MACINTOSH", 10000},
+ {"SHIFT-JIS", 932},
+ {"SHIFT_JIS", 932},
+ {"SJIS", 932},
+ {"US", 1252},
+ {"US-ASCII", 1252},
+ {"UTF-16", 1200},
+ {"UTF-16BE", 1201},
+ {"UTF-16LE", 1200},
+ {"UTF-8", CP_UTF8},
+ {"X-EUROPA", 29001},
+ {"X-MAC-ARABIC", 10004},
+ {"X-MAC-CE", 10029},
+ {"X-MAC-CHINESEIMP", 10008},
+ {"X-MAC-CHINESETRAD", 10002},
+ {"X-MAC-CROATIAN", 10082},
+ {"X-MAC-CYRILLIC", 10007},
+ {"X-MAC-GREEK", 10006},
+ {"X-MAC-HEBREW", 10005},
+ {"X-MAC-ICELANDIC", 10079},
+ {"X-MAC-JAPANESE", 10001},
+ {"X-MAC-KOREAN", 10003},
+ {"X-MAC-ROMANIAN", 10010},
+ {"X-MAC-THAI", 10021},
+ {"X-MAC-TURKISH", 10081},
+ {"X-MAC-UKRAINIAN", 10017},
+};
+static unsigned
+make_codepage_from_charset(const char *charset)
{
+ char cs[16];
char *p;
- int l, wl;
- BOOL useDefaultChar = FALSE;
+ unsigned cp;
+ int a, b;
+
+ if (charset == NULL || strlen(charset) > 15)
+ return -1;
+
+ /* Copy name to uppercase. */
+ p = cs;
+ while (*charset) {
+ char c = *charset++;
+ if (c >= 'a' && c <= 'z')
+ c -= 'a' - 'A';
+ *p++ = c;
+ }
+ *p++ = '\0';
+ cp = -1;
- wl = (int)wcslen(w);
- l = wl * 4 + 4;
- p = malloc(l);
+ /* Look it up in the table first, so that we can easily
+ * override CP367, which we map to 1252 instead of 367. */
+ a = 0;
+ b = sizeof(charsets)/sizeof(charsets[0]);
+ while (b > a) {
+ int c = (b + a) / 2;
+ int r = strcmp(charsets[c].name, cs);
+ if (r < 0)
+ a = c + 1;
+ else if (r > 0)
+ b = c;
+ else
+ return charsets[c].cp;
+ }
+
+ /* If it's not in the table, try to parse it. */
+ switch (*cs) {
+ case 'C':
+ if (cs[1] == 'P' && cs[2] >= '0' && cs[2] <= '9') {
+ cp = my_atoi(cs + 2);
+ } else if (strcmp(cs, "CP_ACP") == 0)
+ cp = get_current_codepage();
+ else if (strcmp(cs, "CP_OEMCP") == 0)
+ cp = get_current_oemcp();
+ break;
+ case 'I':
+ if (cs[1] == 'B' && cs[2] == 'M' &&
+ cs[3] >= '0' && cs[3] <= '9') {
+ cp = my_atoi(cs + 3);
+ }
+ break;
+ case 'W':
+ if (strncmp(cs, "WINDOWS-", 8) == 0) {
+ cp = my_atoi(cs + 8);
+ if (cp != 874 && (cp < 1250 || cp > 1258))
+ cp = -1;/* This may invalid code. */
+ }
+ break;
+ }
+ return (cp);
+}
+
+/*
+ * Return ANSI Code Page of current locale set by setlocale().
+ */
+static unsigned
+get_current_codepage()
+{
+ char *locale, *p;
+ unsigned cp;
+
+ locale = setlocale(LC_CTYPE, NULL);
+ if (locale == NULL)
+ return (GetACP());
+ if (locale[0] == 'C' && locale[1] == '\0')
+ return (CP_C_LOCALE);
+ p = strrchr(locale, '.');
if (p == NULL)
- __archive_errx(1, "Out of memory");
- /* To check a useDefaultChar is to simulate error handling of
- * the my_wcstombs() which is running on non Windows system with
- * wctomb().
- * And to set NULL for last argument is necessary when a codepage
- * is not CP_ACP(current locale).
- */
- l = WideCharToMultiByte(CP_ACP, 0, w, wl, p, l, NULL, &useDefaultChar);
- if (l == 0) {
- free(p);
+ return (GetACP());
+ cp = my_atoi(p+1);
+ if (cp <= 0)
+ return (GetACP());
+ return (cp);
+}
+
+/*
+ * Translation table between Locale Name and ACP/OEMCP.
+ */
+static struct {
+ unsigned acp;
+ unsigned ocp;
+ const char *locale;
+} acp_ocp_map[] = {
+ { 950, 950, "Chinese_Taiwan" },
+ { 936, 936, "Chinese_People's Republic of China" },
+ { 950, 950, "Chinese_Taiwan" },
+ { 1250, 852, "Czech_Czech Republic" },
+ { 1252, 850, "Danish_Denmark" },
+ { 1252, 850, "Dutch_Netherlands" },
+ { 1252, 850, "Dutch_Belgium" },
+ { 1252, 437, "English_United States" },
+ { 1252, 850, "English_Australia" },
+ { 1252, 850, "English_Canada" },
+ { 1252, 850, "English_New Zealand" },
+ { 1252, 850, "English_United Kingdom" },
+ { 1252, 437, "English_United States" },
+ { 1252, 850, "Finnish_Finland" },
+ { 1252, 850, "French_France" },
+ { 1252, 850, "French_Belgium" },
+ { 1252, 850, "French_Canada" },
+ { 1252, 850, "French_Switzerland" },
+ { 1252, 850, "German_Germany" },
+ { 1252, 850, "German_Austria" },
+ { 1252, 850, "German_Switzerland" },
+ { 1253, 737, "Greek_Greece" },
+ { 1250, 852, "Hungarian_Hungary" },
+ { 1252, 850, "Icelandic_Iceland" },
+ { 1252, 850, "Italian_Italy" },
+ { 1252, 850, "Italian_Switzerland" },
+ { 932, 932, "Japanese_Japan" },
+ { 949, 949, "Korean_Korea" },
+ { 1252, 850, "Norwegian (BokmOl)_Norway" },
+ { 1252, 850, "Norwegian (BokmOl)_Norway" },
+ { 1252, 850, "Norwegian-Nynorsk_Norway" },
+ { 1250, 852, "Polish_Poland" },
+ { 1252, 850, "Portuguese_Portugal" },
+ { 1252, 850, "Portuguese_Brazil" },
+ { 1251, 866, "Russian_Russia" },
+ { 1250, 852, "Slovak_Slovakia" },
+ { 1252, 850, "Spanish_Spain" },
+ { 1252, 850, "Spanish_Mexico" },
+ { 1252, 850, "Spanish_Spain" },
+ { 1252, 850, "Swedish_Sweden" },
+ { 1254, 857, "Turkish_Turkey" },
+ { 0, 0, NULL}
+};
+
+/*
+ * Return OEM Code Page of current locale set by setlocale().
+ */
+static unsigned
+get_current_oemcp()
+{
+ int i;
+ char *locale, *p;
+ size_t len;
+
+ locale = setlocale(LC_CTYPE, NULL);
+ if (locale == NULL)
+ return (GetOEMCP());
+ if (locale[0] == 'C' && locale[1] == '\0')
+ return (CP_C_LOCALE);
+
+ p = strrchr(locale, '.');
+ if (p == NULL)
+ return (GetOEMCP());
+ len = p - locale;
+ for (i = 0; acp_ocp_map[i].acp; i++) {
+ if (strncmp(acp_ocp_map[i].locale, locale, len) == 0)
+ return (acp_ocp_map[i].ocp);
+ }
+ return (GetOEMCP());
+}
+#else
+
+/*
+ * POSIX platform does not use CodePage.
+ */
+
+static unsigned
+get_current_codepage()
+{
+ return (-1);/* Unknown */
+}
+static unsigned
+make_codepage_from_charset(const char *charset)
+{
+ (void)charset; /* UNUSED */
+ return (-1);/* Unknown */
+}
+static unsigned
+get_current_oemcp()
+{
+ return (-1);/* Unknown */
+}
+
+#endif /* defined(_WIN32) && !defined(__CYGWIN__) */
+
+/*
+ * Return a string conversion object.
+ */
+static struct archive_string_conv *
+get_sconv_object(struct archive *a, const char *fc, const char *tc, int flag)
+{
+ struct archive_string_conv *sc;
+ unsigned current_codepage;
+
+ /* Check if we have made the sconv object. */
+ sc = find_sconv_object(a, fc, tc);
+ if (sc != NULL)
+ return (sc);
+
+ if (a == NULL)
+ current_codepage = get_current_codepage();
+ else
+ current_codepage = a->current_codepage;
+
+ sc = create_sconv_object(canonical_charset_name(fc),
+ canonical_charset_name(tc), current_codepage, flag);
+ if (sc == NULL) {
+ if (a != NULL)
+ archive_set_error(a, ENOMEM,
+ "Could not allocate memory for "
+ "a string conversion object");
return (NULL);
}
- __archive_string_append(as, p, l);
- free(p);
- return (as);
+
+ /*
+ * If there is no converter for current string conversion object,
+ * we cannot handle this conversion.
+ */
+ if (sc->nconverter == 0) {
+ if (a != NULL) {
+#if HAVE_ICONV
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "iconv_open failed : Cannot handle ``%s''",
+ (flag & SCONV_TO_CHARSET)?tc:fc);
+#else
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "A character-set conversion not fully supported "
+ "on this platform");
+#endif
+ }
+ /* Failed; free a sconv object. */
+ free_sconv_object(sc);
+ return (NULL);
+ }
+
+ /*
+ * Success!
+ */
+ if (a != NULL)
+ add_sconv_object(a, sc);
+ return (sc);
+}
+
+static const char *
+get_current_charset(struct archive *a)
+{
+ const char *cur_charset;
+
+ if (a == NULL)
+ cur_charset = default_iconv_charset("");
+ else {
+ cur_charset = default_iconv_charset(a->current_code);
+ if (a->current_code == NULL) {
+ a->current_code = strdup(cur_charset);
+ a->current_codepage = get_current_codepage();
+ a->current_oemcp = get_current_oemcp();
+ }
+ }
+ return (cur_charset);
+}
+
+/*
+ * Make and Return a string conversion object.
+ * Return NULL if the platform does not support the specified conversion
+ * and best_effort is 0.
+ * If best_effort is set, A string conversion object must be returned
+ * unless memory allocation for the object fails, but the conversion
+ * might fail when non-ASCII code is found.
+ */
+struct archive_string_conv *
+archive_string_conversion_to_charset(struct archive *a, const char *charset,
+ int best_effort)
+{
+ int flag = SCONV_TO_CHARSET;
+
+ if (best_effort)
+ flag |= SCONV_BEST_EFFORT;
+ return (get_sconv_object(a, get_current_charset(a), charset, flag));
+}
+
+struct archive_string_conv *
+archive_string_conversion_from_charset(struct archive *a, const char *charset,
+ int best_effort)
+{
+ int flag = SCONV_FROM_CHARSET;
+
+ if (best_effort)
+ flag |= SCONV_BEST_EFFORT;
+ return (get_sconv_object(a, charset, get_current_charset(a), flag));
+}
+
+/*
+ * archive_string_default_conversion_*_archive() are provided for Windows
+ * platform because other archiver application use CP_OEMCP for
+ * MultiByteToWideChar() and WideCharToMultiByte() for the filenames
+ * in tar or zip files. But mbstowcs/wcstombs(CRT) usually use CP_ACP
+ * unless you use setlocale(LC_ALL, ".OCP")(specify CP_OEMCP).
+ * So we should make a string conversion between CP_ACP and CP_OEMCP
+ * for compatibillty.
+ */
+#if defined(_WIN32) && !defined(__CYGWIN__)
+struct archive_string_conv *
+archive_string_default_conversion_for_read(struct archive *a)
+{
+ const char *cur_charset = get_current_charset(a);
+ char oemcp[16];
+
+ /* NOTE: a check of cur_charset is unneeded but we need
+ * that get_current_charset() has been surely called at
+ * this time whatever C compiler optimized. */
+ if (cur_charset != NULL &&
+ (a->current_codepage == CP_C_LOCALE ||
+ a->current_codepage == a->current_oemcp))
+ return (NULL);/* no conversion. */
+
+ _snprintf(oemcp, sizeof(oemcp)-1, "CP%d", a->current_oemcp);
+ /* Make sure a null termination must be set. */
+ oemcp[sizeof(oemcp)-1] = '\0';
+ return (get_sconv_object(a, oemcp, cur_charset,
+ SCONV_FROM_CHARSET));
+}
+
+struct archive_string_conv *
+archive_string_default_conversion_for_write(struct archive *a)
+{
+ const char *cur_charset = get_current_charset(a);
+ char oemcp[16];
+
+ /* NOTE: a check of cur_charset is unneeded but we need
+ * that get_current_charset() has been surely called at
+ * this time whatever C compiler optimized. */
+ if (cur_charset != NULL &&
+ (a->current_codepage == CP_C_LOCALE ||
+ a->current_codepage == a->current_oemcp))
+ return (NULL);/* no conversion. */
+
+ _snprintf(oemcp, sizeof(oemcp)-1, "CP%d", a->current_oemcp);
+ /* Make sure a null termination must be set. */
+ oemcp[sizeof(oemcp)-1] = '\0';
+ return (get_sconv_object(a, cur_charset, oemcp,
+ SCONV_TO_CHARSET));
+}
+#else
+struct archive_string_conv *
+archive_string_default_conversion_for_read(struct archive *a)
+{
+ (void)a; /* UNUSED */
+ return (NULL);
+}
+
+struct archive_string_conv *
+archive_string_default_conversion_for_write(struct archive *a)
+{
+ (void)a; /* UNUSED */
+ return (NULL);
}
+#endif
+/*
+ * Dispose of all character conversion objects in the archive object.
+ */
+void
+archive_string_conversion_free(struct archive *a)
+{
+ struct archive_string_conv *sc;
+ struct archive_string_conv *sc_next;
+
+ for (sc = a->sconv; sc != NULL; sc = sc_next) {
+ sc_next = sc->next;
+ free_sconv_object(sc);
+ }
+ a->sconv = NULL;
+ free(a->current_code);
+ a->current_code = NULL;
+}
+
+/*
+ * Return a conversion charset name.
+ */
+const char *
+archive_string_conversion_charset_name(struct archive_string_conv *sc)
+{
+ if (sc->flag & SCONV_TO_CHARSET)
+ return (sc->to_charset);
+ else
+ return (sc->from_charset);
+}
+
+/*
+ * Change the behavior of a string conversion.
+ */
+void
+archive_string_conversion_set_opt(struct archive_string_conv *sc, int opt)
+{
+ switch (opt) {
+ /*
+ * A filename in UTF-8 was made with libarchive 2.x in a wrong
+ * assumption that wchar_t was Unicode.
+ * This option enables simulating the assumption in order to read
+ * that filname correctly.
+ */
+ case SCONV_SET_OPT_UTF8_LIBARCHIVE2X:
+#if (defined(_WIN32) && !defined(__CYGWIN__)) \
+ || defined(__STDC_ISO_10646__) || defined(__APPLE__)
+ /*
+ * Nothing to do for it since wchar_t on these platforms
+ * is really Unicode.
+ */
+ (void)sc; /* UNUSED */
#else
+ if ((sc->flag & SCONV_UTF8_LIBARCHIVE_2) == 0) {
+ sc->flag |= SCONV_UTF8_LIBARCHIVE_2;
+ /* Re-setup string converters. */
+ setup_converter(sc);
+ }
+#endif
+ break;
+ default:
+ break;
+ }
+}
/*
- * Translates a wide character string into current locale character set
- * and appends to the archive_string. Note: returns NULL if conversion
- * fails.
*
- * Non-Windows uses ISO C wcrtomb() or wctomb() to perform the conversion
- * one character at a time. If a non-Windows platform doesn't have
- * either of these, fall back to the built-in UTF8 conversion.
+ * Copy one archive_string to another in locale conversion.
+ *
+ * archive_strncpy_in_locale();
+ * archive_strcpy_in_locale();
+ *
*/
-struct archive_string *
-__archive_strappend_w_mbs(struct archive_string *as, const wchar_t *w)
+
+static size_t
+mbsnbytes(const void *_p, size_t n)
{
-#if !defined(HAVE_WCTOMB) && !defined(HAVE_WCRTOMB)
- /* If there's no built-in locale support, fall back to UTF8 always. */
- return __archive_strappend_w_utf8(as, w);
+ size_t s;
+ const char *p, *pp;
+
+ if (_p == NULL)
+ return (0);
+ p = (const char *)_p;
+
+ /* Like strlen(p), except won't examine positions beyond p[n]. */
+ s = 0;
+ pp = p;
+ while (s < n && *pp) {
+ pp++;
+ s++;
+ }
+ return (s);
+}
+
+static size_t
+utf16nbytes(const void *_p, size_t n)
+{
+ size_t s;
+ const char *p, *pp;
+
+ if (_p == NULL)
+ return (0);
+ p = (const char *)_p;
+
+ /* Like strlen(p), except won't examine positions beyond p[n]. */
+ s = 0;
+ pp = p;
+ n >>= 1;
+ while (s < n && (pp[0] || pp[1])) {
+ pp += 2;
+ s++;
+ }
+ return (s<<1);
+}
+
+int
+archive_strncpy_in_locale(struct archive_string *as, const void *_p, size_t n,
+ struct archive_string_conv *sc)
+{
+ as->length = 0;
+ return (archive_strncat_in_locale(as, _p, n, sc));
+}
+
+int
+archive_strncat_in_locale(struct archive_string *as, const void *_p, size_t n,
+ struct archive_string_conv *sc)
+{
+ const void *s;
+ size_t length;
+ int i, r = 0, r2;
+
+ /* We must allocate memory even if there is no data for conversion
+ * or copy. This simulates archive_string_append behavior. */
+ if (_p == NULL || n == 0) {
+ int tn = 1;
+ if (sc != NULL && (sc->flag & SCONV_TO_UTF16))
+ tn = 2;
+ if (archive_string_ensure(as, as->length + tn) == NULL)
+ return (-1);
+ as->s[as->length] = 0;
+ if (tn == 2)
+ as->s[as->length+1] = 0;
+ return (0);
+ }
+
+ /*
+ * If sc is NULL, we just make a copy.
+ */
+ if (sc == NULL) {
+ length = mbsnbytes(_p, n);
+ if (archive_string_append(as, _p, length) == NULL)
+ return (-1);/* No memory */
+ return (0);
+ }
+
+ if (sc->flag & SCONV_FROM_UTF16)
+ length = utf16nbytes(_p, n);
+ else
+ length = mbsnbytes(_p, n);
+ s = _p;
+ i = 0;
+ if (sc->nconverter > 1) {
+ sc->utftmp.length = 0;
+ r2 = sc->converter[0](&(sc->utftmp), s, length, sc);
+ if (r2 != 0 && errno == ENOMEM)
+ return (r2);
+ if (r > r2)
+ r = r2;
+ s = sc->utftmp.s;
+ length = sc->utftmp.length;
+ ++i;
+ }
+ r2 = sc->converter[i](as, s, length, sc);
+ if (r > r2)
+ r = r2;
+ return (r);
+}
+
+#if HAVE_ICONV
+
+/*
+ * Return -1 if conversion failes.
+ */
+static int
+iconv_strncat_in_locale(struct archive_string *as, const void *_p,
+ size_t length, struct archive_string_conv *sc)
+{
+ ICONV_CONST char *inp;
+ size_t remaining;
+ iconv_t cd;
+ char *outp;
+ size_t avail, bs;
+ int return_value = 0; /* success */
+ int to_size, from_size;
+
+ if (sc->flag & SCONV_TO_UTF16)
+ to_size = 2;
+ else
+ to_size = 1;
+ if (sc->flag & SCONV_FROM_UTF16)
+ from_size = 2;
+ else
+ from_size = 1;
+
+ if (archive_string_ensure(as, as->length + length*2+to_size) == NULL)
+ return (-1);
+
+ cd = sc->cd;
+ inp = (char *)(uintptr_t)_p;
+ remaining = length;
+ outp = as->s + as->length;
+ avail = as->buffer_length - as->length - to_size;
+ while (remaining >= (size_t)from_size) {
+ size_t result = iconv(cd, &inp, &remaining, &outp, &avail);
+
+ if (result != (size_t)-1)
+ break; /* Conversion completed. */
+
+ if (errno == EILSEQ || errno == EINVAL) {
+ /*
+ * If an output charset is UTF-8 or UTF-16BE/LE,
+ * unknown character should be U+FFFD
+ * (replacement character).
+ */
+ if (sc->flag & (SCONV_TO_UTF8 | SCONV_TO_UTF16)) {
+ size_t rbytes;
+ if (sc->flag & SCONV_TO_UTF8)
+ rbytes = UTF8_R_CHAR_SIZE;
+ else
+ rbytes = 2;
+
+ if (avail < rbytes) {
+ as->length = outp - as->s;
+ bs = as->buffer_length +
+ (remaining * to_size) + rbytes;
+ if (NULL ==
+ archive_string_ensure(as, bs))
+ return (-1);
+ outp = as->s + as->length;
+ avail = as->buffer_length
+ - as->length - to_size;
+ }
+ if (sc->flag & SCONV_TO_UTF8)
+ UTF8_SET_R_CHAR(outp);
+ else if (sc->flag & SCONV_TO_UTF16BE)
+ archive_be16enc(outp, UNICODE_R_CHAR);
+ else
+ archive_le16enc(outp, UNICODE_R_CHAR);
+ outp += rbytes;
+ avail -= rbytes;
+ } else {
+ /* Skip the illegal input bytes. */
+ *outp++ = '?';
+ avail--;
+ }
+ inp += from_size;
+ remaining -= from_size;
+ return_value = -1; /* failure */
+ } else {
+ /* E2BIG no output buffer,
+ * Increase an output buffer. */
+ as->length = outp - as->s;
+ bs = as->buffer_length + remaining * 2;
+ if (NULL == archive_string_ensure(as, bs))
+ return (-1);
+ outp = as->s + as->length;
+ avail = as->buffer_length - as->length - to_size;
+ }
+ }
+ as->length = outp - as->s;
+ as->s[as->length] = 0;
+ if (to_size == 2)
+ as->s[as->length+1] = 0;
+ return (return_value);
+}
+
+#endif /* HAVE_ICONV */
+
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+
+/*
+ * Translate a string from a some CodePage to an another CodePage by
+ * Windows APIs, and copy the result. Return -1 if conversion failes.
+ */
+static int
+strncat_in_codepage(struct archive_string *as,
+ const void *_p, size_t length, struct archive_string_conv *sc)
+{
+ const char *s = (const char *)_p;
+ struct archive_wstring aws;
+ size_t l;
+ int r, saved_flag;
+
+ archive_string_init(&aws);
+ saved_flag = sc->flag;
+ sc->flag &= ~(SCONV_NORMALIZATION_D | SCONV_NORMALIZATION_C);
+ r = archive_wstring_append_from_mbs_in_codepage(&aws, s, length, sc);
+ sc->flag = saved_flag;
+ if (r != 0) {
+ archive_wstring_free(&aws);
+ if (errno != ENOMEM)
+ archive_string_append(as, s, length);
+ return (-1);
+ }
+
+ l = as->length;
+ r = archive_string_append_from_wcs_in_codepage(
+ as, aws.s, aws.length, sc);
+ if (r != 0 && errno != ENOMEM && l == as->length)
+ archive_string_append(as, s, length);
+ archive_wstring_free(&aws);
+ return (r);
+}
+
+/*
+ * Test whether MBS ==> WCS is okay.
+ */
+static int
+invalid_mbs(const void *_p, size_t n, struct archive_string_conv *sc)
+{
+ const char *p = (const char *)_p;
+ unsigned codepage;
+ DWORD mbflag = MB_ERR_INVALID_CHARS;
+
+ if (sc->flag & SCONV_FROM_CHARSET)
+ codepage = sc->to_cp;
+ else
+ codepage = sc->from_cp;
+
+ if (codepage == CP_C_LOCALE)
+ return (0);
+ if (codepage != CP_UTF8)
+ mbflag |= MB_PRECOMPOSED;
+
+ if (MultiByteToWideChar(codepage, mbflag, p, n, NULL, 0) == 0)
+ return (-1); /* Invalid */
+ return (0); /* Okay */
+}
+
#else
- /* We cannot use the standard wcstombs() here because it
- * cannot tell us how big the output buffer should be. So
- * I've built a loop around wcrtomb() or wctomb() that
- * converts a character at a time and resizes the string as
- * needed. We prefer wcrtomb() when it's available because
- * it's thread-safe. */
+
+/*
+ * Test whether MBS ==> WCS is okay.
+ */
+static int
+invalid_mbs(const void *_p, size_t n, struct archive_string_conv *sc)
+{
+ const char *p = (const char *)_p;
+ size_t r;
+
+ (void)sc; /* UNUSED */
+#if HAVE_MBRTOWC
+ mbstate_t shift_state;
+
+ memset(&shift_state, 0, sizeof(shift_state));
+#else
+ /* Clear the shift state before starting. */
+ mbtowc(NULL, NULL, 0);
+#endif
+ while (n) {
+ wchar_t wc;
+
+#if HAVE_MBRTOWC
+ r = mbrtowc(&wc, p, n, &shift_state);
+#else
+ r = mbtowc(&wc, p, n);
+#endif
+ if (r == (size_t)-1 || r == (size_t)-2)
+ return (-1);/* Invalid. */
+ if (r == 0)
+ break;
+ p += r;
+ n -= r;
+ }
+ return (0); /* All Okey. */
+}
+
+#endif /* defined(_WIN32) && !defined(__CYGWIN__) */
+
+/*
+ * Basically returns -1 because we cannot make a conversion of charset
+ * without iconv but in some cases this would return 0.
+ * Returns 0 if all copied characters are ASCII.
+ * Returns 0 if both from-locale and to-locale are the same and those
+ * can be WCS with no error.
+ */
+static int
+best_effort_strncat_in_locale(struct archive_string *as, const void *_p,
+ size_t length, struct archive_string_conv *sc)
+{
+ size_t remaining;
+ char *outp;
+ const char *inp;
+ size_t avail;
+ int return_value = 0; /* success */
+
+ /*
+ * If both from-locale and to-locale is the same, this makes a copy.
+ * And then this checks all copied MBS can be WCS if so returns 0.
+ */
+ if (sc->same) {
+ if (archive_string_append(as, _p, length) == NULL)
+ return (-1);/* No memory */
+ return (invalid_mbs(_p, length, sc));
+ }
+
+ /*
+ * If a character is ASCII, this just copies it. If not, this
+ * assigns '?' charater instead but in UTF-8 locale this assigns
+ * byte sequence 0xEF 0xBD 0xBD, which are code point U+FFFD,
+ * a Replacement Character in Unicode.
+ */
+ if (archive_string_ensure(as, as->length + length + 1) == NULL)
+ return (-1);
+
+ remaining = length;
+ inp = (const char *)_p;
+ outp = as->s + as->length;
+ avail = as->buffer_length - as->length -1;
+ while (*inp && remaining > 0) {
+ if (*inp < 0 && (sc->flag & SCONV_TO_UTF8)) {
+ if (avail < UTF8_R_CHAR_SIZE) {
+ as->length = outp - as->s;
+ if (NULL == archive_string_ensure(as,
+ as->buffer_length + remaining +
+ UTF8_R_CHAR_SIZE))
+ return (-1);
+ outp = as->s + as->length;
+ avail = as->buffer_length - as->length -1;
+ }
+ /*
+ * When coping a string in UTF-8, unknown character
+ * should be U+FFFD (replacement character).
+ */
+ UTF8_SET_R_CHAR(outp);
+ outp += UTF8_R_CHAR_SIZE;
+ avail -= UTF8_R_CHAR_SIZE;
+ inp++;
+ remaining--;
+ return_value = -1;
+ } else if (*inp < 0) {
+ *outp++ = '?';
+ inp++;
+ remaining--;
+ return_value = -1;
+ } else {
+ *outp++ = *inp++;
+ remaining--;
+ }
+ }
+ as->length = outp - as->s;
+ as->s[as->length] = '\0';
+ return (return_value);
+}
+
+
+/*
+ * Unicode conversion functions.
+ * - UTF-8 <===> UTF-8 in removing surrogate pairs.
+ * - UTF-8 NFD ===> UTF-8 NFC in removing surrogate pairs.
+ * - UTF-8 made by libarchive 2.x ===> UTF-8.
+ * - UTF-16BE <===> UTF-8.
+ *
+ */
+
+/*
+ * Utility to convert a single UTF-8 sequence.
+ *
+ * Usually return used bytes, return used byte in negative value when
+ * a unicode character is replaced with U+FFFD.
+ * See also http://unicode.org/review/pr-121.html Public Review Issue #121
+ * Recommended Practice for Replacement Characters.
+ */
+static int
+_utf8_to_unicode(uint32_t *pwc, const char *s, size_t n)
+{
+ static const char utf8_count[256] = {
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 00 - 0F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 10 - 1F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 20 - 2F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 30 - 3F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40 - 4F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 50 - 5F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 60 - 6F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 70 - 7F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 80 - 8F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 90 - 9F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* A0 - AF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* B0 - BF */
+ 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,/* C0 - CF */
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,/* D0 - DF */
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,/* E0 - EF */
+ 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* F0 - FF */
+ };
+ int ch, i;
+ int cnt;
+ uint32_t wc;
+
+ /* Sanity check. */
+ if (n == 0)
+ return (0);
+ /*
+ * Decode 1-4 bytes depending on the value of the first byte.
+ */
+ ch = (unsigned char)*s;
+ if (ch == 0)
+ return (0); /* Standard: return 0 for end-of-string. */
+ cnt = utf8_count[ch];
+
+ /* Invalide sequence or there are not plenty bytes. */
+ if ((int)n < cnt) {
+ cnt = n;
+ for (i = 1; i < cnt; i++) {
+ if ((s[i] & 0xc0) != 0x80) {
+ cnt = i;
+ break;
+ }
+ }
+ goto invalid_sequence;
+ }
+
+ /* Make a Unicode code point from a single UTF-8 sequence. */
+ switch (cnt) {
+ case 1: /* 1 byte sequence. */
+ *pwc = ch & 0x7f;
+ return (cnt);
+ case 2: /* 2 bytes sequence. */
+ if ((s[1] & 0xc0) != 0x80) {
+ cnt = 1;
+ goto invalid_sequence;
+ }
+ *pwc = ((ch & 0x1f) << 6) | (s[1] & 0x3f);
+ return (cnt);
+ case 3: /* 3 bytes sequence. */
+ if ((s[1] & 0xc0) != 0x80) {
+ cnt = 1;
+ goto invalid_sequence;
+ }
+ if ((s[2] & 0xc0) != 0x80) {
+ cnt = 2;
+ goto invalid_sequence;
+ }
+ wc = ((ch & 0x0f) << 12)
+ | ((s[1] & 0x3f) << 6)
+ | (s[2] & 0x3f);
+ if (wc < 0x800)
+ goto invalid_sequence;/* Overlong sequence. */
+ break;
+ case 4: /* 4 bytes sequence. */
+ if ((s[1] & 0xc0) != 0x80) {
+ cnt = 1;
+ goto invalid_sequence;
+ }
+ if ((s[2] & 0xc0) != 0x80) {
+ cnt = 2;
+ goto invalid_sequence;
+ }
+ if ((s[3] & 0xc0) != 0x80) {
+ cnt = 3;
+ goto invalid_sequence;
+ }
+ wc = ((ch & 0x07) << 18)
+ | ((s[1] & 0x3f) << 12)
+ | ((s[2] & 0x3f) << 6)
+ | (s[3] & 0x3f);
+ if (wc < 0x10000)
+ goto invalid_sequence;/* Overlong sequence. */
+ break;
+ default: /* Others are all invalid sequence. */
+ if (ch == 0xc0 || ch == 0xc1)
+ cnt = 2;
+ else if (ch >= 0xf5 && ch <= 0xf7)
+ cnt = 4;
+ else if (ch >= 0xf8 && ch <= 0xfb)
+ cnt = 5;
+ else if (ch == 0xfc || ch == 0xfd)
+ cnt = 6;
+ else
+ cnt = 1;
+ if ((int)n < cnt)
+ cnt = n;
+ for (i = 1; i < cnt; i++) {
+ if ((s[i] & 0xc0) != 0x80) {
+ cnt = i;
+ break;
+ }
+ }
+ goto invalid_sequence;
+ }
+
+ /* The code point larger than 0x10FFFF is not leagal
+ * Unicode values. */
+ if (wc > UNICODE_MAX)
+ goto invalid_sequence;
+ /* Correctly gets a Unicode, returns used bytes. */
+ *pwc = wc;
+ return (cnt);
+invalid_sequence:
+ *pwc = UNICODE_R_CHAR;/* set the Replacement Character instead. */
+ return (cnt * -1);
+}
+
+static int
+utf8_to_unicode(uint32_t *pwc, const char *s, size_t n)
+{
+ int cnt;
+
+ cnt = _utf8_to_unicode(pwc, s, n);
+ /* Any of Surrogate pair is not leagal Unicode values. */
+ if (cnt == 3 && IS_SURROGATE_PAIR_LA(*pwc))
+ return (-3);
+ return (cnt);
+}
+
+static inline uint32_t
+combine_surrogate_pair(uint32_t uc, uint32_t uc2)
+{
+ uc -= 0xD800;
+ uc *= 0x400;
+ uc += uc2 - 0xDC00;
+ uc += 0x10000;
+ return (uc);
+}
+
+/*
+ * Convert a single UTF-8/CESU-8 sequence to a Unicode code point in
+ * removing surrogate pairs.
+ *
+ * CESU-8: The Compatibility Encoding Scheme for UTF-16.
+ *
+ * Usually return used bytes, return used byte in negative value when
+ * a unicode character is replaced with U+FFFD.
+ */
+static int
+cesu8_to_unicode(uint32_t *pwc, const char *s, size_t n)
+{
+ uint32_t wc, wc2;
+ int cnt;
+
+ cnt = _utf8_to_unicode(&wc, s, n);
+ if (cnt == 3 && IS_HIGH_SURROGATE_LA(wc)) {
+ if (n - 3 < 3) {
+ /* Invalid byte sequence. */
+ goto invalid_sequence;
+ }
+ cnt = _utf8_to_unicode(&wc2, s+3, n-3);
+ if (cnt != 3 || !IS_LOW_SURROGATE_LA(wc2)) {
+ /* Invalid byte sequence. */
+ goto invalid_sequence;
+ }
+ wc = combine_surrogate_pair(wc, wc2);
+ cnt = 6;
+ } else if (cnt == 3 && IS_LOW_SURROGATE_LA(wc)) {
+ /* Invalid byte sequence. */
+ goto invalid_sequence;
+ }
+ *pwc = wc;
+ return (cnt);
+invalid_sequence:
+ *pwc = UNICODE_R_CHAR;/* set the Replacement Character instead. */
+ if (cnt > 0)
+ cnt *= -1;
+ return (cnt);
+}
+
+/*
+ * Convert a Unicode code point to a single UTF-8 sequence.
+ *
+ * NOTE:This function does not check if the Unicode is leagal or not.
+ * Please you definitely check it before calling this.
+ */
+static size_t
+unicode_to_utf8(char *p, size_t remaining, uint32_t uc)
+{
+ char *_p = p;
+
+ /* Translate code point to UTF8 */
+ if (uc <= 0x7f) {
+ if (remaining == 0)
+ return (0);
+ *p++ = (char)uc;
+ } else if (uc <= 0x7ff) {
+ if (remaining < 2)
+ return (0);
+ *p++ = 0xc0 | ((uc >> 6) & 0x1f);
+ *p++ = 0x80 | (uc & 0x3f);
+ } else if (uc <= 0xffff) {
+ if (remaining < 3)
+ return (0);
+ *p++ = 0xe0 | ((uc >> 12) & 0x0f);
+ *p++ = 0x80 | ((uc >> 6) & 0x3f);
+ *p++ = 0x80 | (uc & 0x3f);
+ } else if (uc <= UNICODE_MAX) {
+ if (remaining < 4)
+ return (0);
+ *p++ = 0xf0 | ((uc >> 18) & 0x07);
+ *p++ = 0x80 | ((uc >> 12) & 0x3f);
+ *p++ = 0x80 | ((uc >> 6) & 0x3f);
+ *p++ = 0x80 | (uc & 0x3f);
+ } else {
+ /*
+ * Undescribed code point should be U+FFFD
+ * (replacement character).
+ */
+ if (remaining < UTF8_R_CHAR_SIZE)
+ return (0);
+ UTF8_SET_R_CHAR(p);
+ p += UTF8_R_CHAR_SIZE;
+ }
+ return (p - _p);
+}
+
+static int
+utf16be_to_unicode(uint32_t *pwc, const char *s, size_t n)
+{
+ return (utf16_to_unicode(pwc, s, n, 1));
+}
+
+static int
+utf16le_to_unicode(uint32_t *pwc, const char *s, size_t n)
+{
+ return (utf16_to_unicode(pwc, s, n, 0));
+}
+
+static int
+utf16_to_unicode(uint32_t *pwc, const char *s, size_t n, int be)
+{
+ const char *utf16 = s;
+ unsigned uc;
+
+ if (n == 0)
+ return (0);
+ if (n == 1) {
+ /* set the Replacement Character instead. */
+ *pwc = UNICODE_R_CHAR;
+ return (-1);
+ }
+
+ if (be)
+ uc = archive_be16dec(utf16);
+ else
+ uc = archive_le16dec(utf16);
+ utf16 += 2;
+
+ /* If this is a surrogate pair, assemble the full code point.*/
+ if (IS_HIGH_SURROGATE_LA(uc)) {
+ unsigned uc2;
+
+ if (n >= 4) {
+ if (be)
+ uc2 = archive_be16dec(utf16);
+ else
+ uc2 = archive_le16dec(utf16);
+ } else
+ uc2 = 0;
+ if (IS_LOW_SURROGATE_LA(uc2)) {
+ uc = combine_surrogate_pair(uc, uc2);
+ utf16 += 2;
+ } else {
+ /* Undescribed code point should be U+FFFD
+ * (replacement character). */
+ *pwc = UNICODE_R_CHAR;
+ return (-2);
+ }
+ }
+
+ /*
+ * Surrogate pair values(0xd800 through 0xdfff) are only
+ * used by UTF-16, so, after above culculation, the code
+ * must not be surrogate values, and Unicode has no codes
+ * larger than 0x10ffff. Thus, those are not leagal Unicode
+ * values.
+ */
+ if (IS_SURROGATE_PAIR_LA(uc) || uc > UNICODE_MAX) {
+ /* Undescribed code point should be U+FFFD
+ * (replacement character). */
+ *pwc = UNICODE_R_CHAR;
+ return (((int)(utf16 - s)) * -1);
+ }
+ *pwc = uc;
+ return ((int)(utf16 - s));
+}
+
+static size_t
+unicode_to_utf16be(char *p, size_t remaining, uint32_t uc)
+{
+ char *utf16 = p;
+
+ if (uc > 0xffff) {
+ /* We have a code point that won't fit into a
+ * wchar_t; convert it to a surrogate pair. */
+ if (remaining < 4)
+ return (0);
+ uc -= 0x10000;
+ archive_be16enc(utf16, ((uc >> 10) & 0x3ff) + 0xD800);
+ archive_be16enc(utf16+2, (uc & 0x3ff) + 0xDC00);
+ return (4);
+ } else {
+ if (remaining < 2)
+ return (0);
+ archive_be16enc(utf16, uc);
+ return (2);
+ }
+}
+
+static size_t
+unicode_to_utf16le(char *p, size_t remaining, uint32_t uc)
+{
+ char *utf16 = p;
+
+ if (uc > 0xffff) {
+ /* We have a code point that won't fit into a
+ * wchar_t; convert it to a surrogate pair. */
+ if (remaining < 4)
+ return (0);
+ uc -= 0x10000;
+ archive_le16enc(utf16, ((uc >> 10) & 0x3ff) + 0xD800);
+ archive_le16enc(utf16+2, (uc & 0x3ff) + 0xDC00);
+ return (4);
+ } else {
+ if (remaining < 2)
+ return (0);
+ archive_le16enc(utf16, uc);
+ return (2);
+ }
+}
+
+/*
+ * Copy UTF-8 string in checking surrogate pair.
+ * If any surrogate pair are found, it would be canonicalized.
+ */
+static int
+strncat_from_utf8_to_utf8(struct archive_string *as, const void *_p, size_t len,
+ struct archive_string_conv *sc)
+{
+ const char *s;
+ char *p, *endp;
+ int n, ret = 0;
+
+ (void)sc; /* UNUSED */
+
+ if (archive_string_ensure(as, as->length + len + 1) == NULL)
+ return (-1);
+
+ s = (const char *)_p;
+ p = as->s + as->length;
+ endp = as->s + as->buffer_length -1;
+ do {
+ uint32_t uc;
+ const char *ss = s;
+ size_t w;
+
+ /*
+ * Forward byte sequence until a conversion of that is needed.
+ */
+ while ((n = utf8_to_unicode(&uc, s, len)) > 0) {
+ s += n;
+ len -= n;
+ }
+ if (ss < s) {
+ if (p + (s - ss) > endp) {
+ as->length = p - as->s;
+ if (archive_string_ensure(as,
+ as->buffer_length + len + 1) == NULL)
+ return (-1);
+ p = as->s + as->length;
+ endp = as->s + as->buffer_length -1;
+ }
+
+ memcpy(p, ss, s - ss);
+ p += s - ss;
+ }
+
+ /*
+ * If n is negative, current byte sequence needs a replacement.
+ */
+ if (n < 0) {
+ if (n == -3 && IS_SURROGATE_PAIR_LA(uc)) {
+ /* Current byte sequence may be CESU-8. */
+ n = cesu8_to_unicode(&uc, s, len);
+ }
+ if (n < 0) {
+ ret = -1;
+ n *= -1;/* Use a replaced unicode character. */
+ }
+
+ /* Rebuild UTF-8 byte sequence. */
+ while ((w = unicode_to_utf8(p, endp - p, uc)) == 0) {
+ as->length = p - as->s;
+ if (archive_string_ensure(as,
+ as->buffer_length + len + 1) == NULL)
+ return (-1);
+ p = as->s + as->length;
+ endp = as->s + as->buffer_length -1;
+ }
+ p += w;
+ s += n;
+ len -= n;
+ }
+ } while (n > 0);
+ as->length = p - as->s;
+ as->s[as->length] = '\0';
+ return (ret);
+}
+
+static int
+archive_string_append_unicode(struct archive_string *as, const void *_p,
+ size_t len, struct archive_string_conv *sc)
+{
+ const char *s;
+ char *p, *endp;
+ uint32_t uc;
+ size_t w;
+ int n, ret = 0, ts, tm;
+ int (*parse)(uint32_t *, const char *, size_t);
+ size_t (*unparse)(char *, size_t, uint32_t);
+
+ if (sc->flag & SCONV_TO_UTF16BE) {
+ unparse = unicode_to_utf16be;
+ ts = 2;
+ } else if (sc->flag & SCONV_TO_UTF16LE) {
+ unparse = unicode_to_utf16le;
+ ts = 2;
+ } else if (sc->flag & SCONV_TO_UTF8) {
+ unparse = unicode_to_utf8;
+ ts = 1;
+ } else {
+ /*
+ * This case is going to be converted to another
+ * character-set through iconv.
+ */
+ if (sc->flag & SCONV_FROM_UTF16BE) {
+ unparse = unicode_to_utf16be;
+ ts = 2;
+ } else if (sc->flag & SCONV_FROM_UTF16LE) {
+ unparse = unicode_to_utf16le;
+ ts = 2;
+ } else {
+ unparse = unicode_to_utf8;
+ ts = 1;
+ }
+ }
+
+ if (sc->flag & SCONV_FROM_UTF16BE) {
+ parse = utf16be_to_unicode;
+ tm = 1;
+ } else if (sc->flag & SCONV_FROM_UTF16LE) {
+ parse = utf16le_to_unicode;
+ tm = 1;
+ } else {
+ parse = cesu8_to_unicode;
+ tm = ts;
+ }
+
+ if (archive_string_ensure(as, as->length + len * tm + ts) == NULL)
+ return (-1);
+
+ s = (const char *)_p;
+ p = as->s + as->length;
+ endp = as->s + as->buffer_length - ts;
+ while ((n = parse(&uc, s, len)) != 0) {
+ if (n < 0) {
+ /* Use a replaced unicode character. */
+ n *= -1;
+ ret = -1;
+ }
+ s += n;
+ len -= n;
+ while ((w = unparse(p, endp - p, uc)) == 0) {
+ /* There is not enough output buffer so
+ * we have to expand it. */
+ as->length = p - as->s;
+ if (archive_string_ensure(as,
+ as->buffer_length + len * tm + ts) == NULL)
+ return (-1);
+ p = as->s + as->length;
+ endp = as->s + as->buffer_length - ts;
+ }
+ p += w;
+ }
+ as->length = p - as->s;
+ as->s[as->length] = '\0';
+ if (ts == 2)
+ as->s[as->length+1] = '\0';
+ return (ret);
+}
+
+/*
+ * Following Constants for Hangul compositions this information comes from
+ * Unicode Standard Annex #15 http://unicode.org/reports/tr15/
+ */
+#define HC_SBASE 0xAC00
+#define HC_LBASE 0x1100
+#define HC_VBASE 0x1161
+#define HC_TBASE 0x11A7
+#define HC_LCOUNT 19
+#define HC_VCOUNT 21
+#define HC_TCOUNT 28
+#define HC_NCOUNT (HC_VCOUNT * HC_TCOUNT)
+#define HC_SCOUNT (HC_LCOUNT * HC_NCOUNT)
+
+static uint32_t
+get_nfc(uint32_t uc, uint32_t uc2)
+{
+ int t, b;
+
+ t = 0;
+ b = sizeof(u_composition_table)/sizeof(u_composition_table[0]) -1;
+ while (b >= t) {
+ int m = (t + b) / 2;
+ if (u_composition_table[m].cp1 < uc)
+ t = m + 1;
+ else if (u_composition_table[m].cp1 > uc)
+ b = m - 1;
+ else if (u_composition_table[m].cp2 < uc2)
+ t = m + 1;
+ else if (u_composition_table[m].cp2 > uc2)
+ b = m - 1;
+ else
+ return (u_composition_table[m].nfc);
+ }
+ return (0);
+}
+
+#define FDC_MAX 10 /* The maximum number of Following Decomposable
+ * Characters. */
+
+/*
+ * Update first code point.
+ */
+#define UPDATE_UC(new_uc) do { \
+ uc = new_uc; \
+ ucptr = NULL; \
+} while (0)
+
+/*
+ * Replace first code point with second code point.
+ */
+#define REPLACE_UC_WITH_UC2() do { \
+ uc = uc2; \
+ ucptr = uc2ptr; \
+ n = n2; \
+} while (0)
+
+#define EXPAND_BUFFER() do { \
+ as->length = p - as->s; \
+ if (archive_string_ensure(as, \
+ as->buffer_length + len * tm + ts) == NULL)\
+ return (-1); \
+ p = as->s + as->length; \
+ endp = as->s + as->buffer_length - ts; \
+} while (0)
+
+#define UNPARSE(p, endp, uc) do { \
+ while ((w = unparse(p, (endp) - (p), uc)) == 0) {\
+ EXPAND_BUFFER(); \
+ } \
+ p += w; \
+} while (0)
+
+/*
+ * Write first code point.
+ * If the code point has not be changed from its original code,
+ * this just copies it from its original buffer pointer.
+ * If not, this converts it to UTF-8 byte sequence and copies it.
+ */
+#define WRITE_UC() do { \
+ if (ucptr) { \
+ if (p + n > endp) \
+ EXPAND_BUFFER(); \
+ switch (n) { \
+ case 4: \
+ *p++ = *ucptr++; \
+ /* FALL THROUGH */ \
+ case 3: \
+ *p++ = *ucptr++; \
+ /* FALL THROUGH */ \
+ case 2: \
+ *p++ = *ucptr++; \
+ /* FALL THROUGH */ \
+ case 1: \
+ *p++ = *ucptr; \
+ break; \
+ } \
+ ucptr = NULL; \
+ } else { \
+ UNPARSE(p, endp, uc); \
+ } \
+} while (0)
+
+/*
+ * Collect following decomposable code points.
+ */
+#define COLLECT_CPS(start) do { \
+ int _i; \
+ for (_i = start; _i < FDC_MAX ; _i++) { \
+ nx = parse(&ucx[_i], s, len); \
+ if (nx <= 0) \
+ break; \
+ cx = CCC(ucx[_i]); \
+ if (cl >= cx && cl != 228 && cx != 228)\
+ break; \
+ s += nx; \
+ len -= nx; \
+ cl = cx; \
+ ccx[_i] = cx; \
+ } \
+ if (_i >= FDC_MAX) { \
+ ret = -1; \
+ ucx_size = FDC_MAX; \
+ } else \
+ ucx_size = _i; \
+} while (0)
+
+/*
+ * Normalize UTF-8/UTF-16BE characters to Form C and copy the result.
+ *
+ * TODO: Convert composition exclusions,which are never converted
+ * from NFC,NFD,NFKC and NFKD, to Form C.
+ */
+static int
+archive_string_normalize_C(struct archive_string *as, const void *_p,
+ size_t len, struct archive_string_conv *sc)
+{
+ const char *s = (const char *)_p;
+ char *p, *endp;
+ uint32_t uc, uc2;
+ size_t w;
+ int always_replace, n, n2, ret = 0, spair, ts, tm;
+ int (*parse)(uint32_t *, const char *, size_t);
+ size_t (*unparse)(char *, size_t, uint32_t);
+
+ always_replace = 1;
+ ts = 1;/* text size. */
+ if (sc->flag & SCONV_TO_UTF16BE) {
+ unparse = unicode_to_utf16be;
+ ts = 2;
+ if (sc->flag & SCONV_FROM_UTF16BE)
+ always_replace = 0;
+ } else if (sc->flag & SCONV_TO_UTF16LE) {
+ unparse = unicode_to_utf16le;
+ ts = 2;
+ if (sc->flag & SCONV_FROM_UTF16LE)
+ always_replace = 0;
+ } else if (sc->flag & SCONV_TO_UTF8) {
+ unparse = unicode_to_utf8;
+ if (sc->flag & SCONV_FROM_UTF8)
+ always_replace = 0;
+ } else {
+ /*
+ * This case is going to be converted to another
+ * character-set through iconv.
+ */
+ always_replace = 0;
+ if (sc->flag & SCONV_FROM_UTF16BE) {
+ unparse = unicode_to_utf16be;
+ ts = 2;
+ } else if (sc->flag & SCONV_FROM_UTF16LE) {
+ unparse = unicode_to_utf16le;
+ ts = 2;
+ } else {
+ unparse = unicode_to_utf8;
+ }
+ }
+
+ if (sc->flag & SCONV_FROM_UTF16BE) {
+ parse = utf16be_to_unicode;
+ tm = 1;
+ spair = 4;/* surrogate pair size in UTF-16. */
+ } else if (sc->flag & SCONV_FROM_UTF16LE) {
+ parse = utf16le_to_unicode;
+ tm = 1;
+ spair = 4;/* surrogate pair size in UTF-16. */
+ } else {
+ parse = cesu8_to_unicode;
+ tm = ts;
+ spair = 6;/* surrogate pair size in UTF-8. */
+ }
+
+ if (archive_string_ensure(as, as->length + len * tm + ts) == NULL)
+ return (-1);
+
+ p = as->s + as->length;
+ endp = as->s + as->buffer_length - ts;
+ while ((n = parse(&uc, s, len)) != 0) {
+ const char *ucptr, *uc2ptr;
+
+ if (n < 0) {
+ /* Use a replaced unicode character. */
+ UNPARSE(p, endp, uc);
+ s += n*-1;
+ len -= n*-1;
+ ret = -1;
+ continue;
+ } else if (n == spair || always_replace)
+ /* uc is converted from a surrogate pair.
+ * this should be treated as a changed code. */
+ ucptr = NULL;
+ else
+ ucptr = s;
+ s += n;
+ len -= n;
+
+ /* Read second code point. */
+ while ((n2 = parse(&uc2, s, len)) > 0) {
+ uint32_t ucx[FDC_MAX];
+ int ccx[FDC_MAX];
+ int cl, cx, i, nx, ucx_size;
+ int LIndex,SIndex;
+ uint32_t nfc;
+
+ if (n2 == spair || always_replace)
+ /* uc2 is converted from a surrogate pair.
+ * this should be treated as a changed code. */
+ uc2ptr = NULL;
+ else
+ uc2ptr = s;
+ s += n2;
+ len -= n2;
+
+ /*
+ * If current second code point is out of decomposable
+ * code points, finding compositions is unneeded.
+ */
+ if (!IS_DECOMPOSABLE_BLOCK(uc2)) {
+ WRITE_UC();
+ REPLACE_UC_WITH_UC2();
+ continue;
+ }
+
+ /*
+ * Try to combine current code points.
+ */
+ /*
+ * We have to combine Hangul characters according to
+ * http://uniicode.org/reports/tr15/#Hangul
+ */
+ if (0 <= (LIndex = uc - HC_LBASE) &&
+ LIndex < HC_LCOUNT) {
+ /*
+ * Hangul Composition.
+ * 1. Two current code points are L and V.
+ */
+ int VIndex = uc2 - HC_VBASE;
+ if (0 <= VIndex && VIndex < HC_VCOUNT) {
+ /* Make syllable of form LV. */
+ UPDATE_UC(HC_SBASE +
+ (LIndex * HC_VCOUNT + VIndex) *
+ HC_TCOUNT);
+ } else {
+ WRITE_UC();
+ REPLACE_UC_WITH_UC2();
+ }
+ continue;
+ } else if (0 <= (SIndex = uc - HC_SBASE) &&
+ SIndex < HC_SCOUNT && (SIndex % HC_TCOUNT) == 0) {
+ /*
+ * Hangul Composition.
+ * 2. Two current code points are LV and T.
+ */
+ int TIndex = uc2 - HC_TBASE;
+ if (0 < TIndex && TIndex < HC_TCOUNT) {
+ /* Make syllable of form LVT. */
+ UPDATE_UC(uc + TIndex);
+ } else {
+ WRITE_UC();
+ REPLACE_UC_WITH_UC2();
+ }
+ continue;
+ } else if ((nfc = get_nfc(uc, uc2)) != 0) {
+ /* A composition to current code points
+ * is found. */
+ UPDATE_UC(nfc);
+ continue;
+ } else if ((cl = CCC(uc2)) == 0) {
+ /* Clearly 'uc2' the second code point is not
+ * a decomposable code. */
+ WRITE_UC();
+ REPLACE_UC_WITH_UC2();
+ continue;
+ }
+
+ /*
+ * Collect following decomposable code points.
+ */
+ cx = 0;
+ ucx[0] = uc2;
+ ccx[0] = cl;
+ COLLECT_CPS(1);
+
+ /*
+ * Find a composed code in the collected code points.
+ */
+ i = 1;
+ while (i < ucx_size) {
+ int j;
+
+ if ((nfc = get_nfc(uc, ucx[i])) == 0) {
+ i++;
+ continue;
+ }
+
+ /*
+ * nfc is composed of uc and ucx[i].
+ */
+ UPDATE_UC(nfc);
+
+ /*
+ * Remove ucx[i] by shifting
+ * following code points.
+ */
+ for (j = i; j+1 < ucx_size; j++) {
+ ucx[j] = ucx[j+1];
+ ccx[j] = ccx[j+1];
+ }
+ ucx_size --;
+
+ /*
+ * Collect following code points blocked
+ * by ucx[i] the removed code point.
+ */
+ if (ucx_size > 0 && i == ucx_size &&
+ nx > 0 && cx == cl) {
+ cl = ccx[ucx_size-1];
+ COLLECT_CPS(ucx_size);
+ }
+ /*
+ * Restart finding a composed code with
+ * the updated uc from the top of the
+ * collected code points.
+ */
+ i = 0;
+ }
+
+ /*
+ * Apparently the current code points are not
+ * decomposed characters or already composed.
+ */
+ WRITE_UC();
+ for (i = 0; i < ucx_size; i++)
+ UNPARSE(p, endp, ucx[i]);
+
+ /*
+ * Flush out remaining canonical combining characters.
+ */
+ if (nx > 0 && cx == cl && len > 0) {
+ while ((nx = parse(&ucx[0], s, len))
+ > 0) {
+ cx = CCC(ucx[0]);
+ if (cl > cx)
+ break;
+ s += nx;
+ len -= nx;
+ cl = cx;
+ UNPARSE(p, endp, ucx[0]);
+ }
+ }
+ break;
+ }
+ if (n2 < 0) {
+ WRITE_UC();
+ /* Use a replaced unicode character. */
+ UNPARSE(p, endp, uc2);
+ s += n2*-1;
+ len -= n2*-1;
+ ret = -1;
+ continue;
+ } else if (n2 == 0) {
+ WRITE_UC();
+ break;
+ }
+ }
+ as->length = p - as->s;
+ as->s[as->length] = '\0';
+ if (ts == 2)
+ as->s[as->length+1] = '\0';
+ return (ret);
+}
+
+#if defined(__APPLE__)
+
+/*
+ * Normalize UTF-8 characters to Form D and copy the result.
+ */
+static int
+archive_string_normalize_D(struct archive_string *as, const void *_p,
+ size_t len, struct archive_string_conv *sc)
+{
+ const UniChar *inp;
+ char *outp;
+ size_t newsize;
+ ByteCount inCount, outCount;
+ ByteCount inAvail, outAvail;
+ OSStatus err;
+ int ret, saved_flag;
+
+ /*
+ * Convert the current string to UTF-16LE for normalization.
+ * The character-set of the current string must be UTF-16BE or
+ * UTF-8.
+ */
+ archive_string_empty(&(sc->utf16nfc));
+ saved_flag = sc->flag;/* save a flag. */
+ sc->flag &= ~(SCONV_TO_UTF16BE | SCONV_TO_UTF8);
+ sc->flag |= SCONV_TO_UTF16LE;
+ ret = archive_string_append_unicode(&(sc->utf16nfc), _p, len, sc);
+ sc->flag = saved_flag;/* restore the saved flag */
+ if (archive_strlen(&(sc->utf16nfc)) == 0) {
+ if (archive_string_ensure(as, as->length + 1) == NULL)
+ return (-1);
+ return (ret);
+ }
+
+ /*
+ * Normalize an NFC string to be an NFD(HFS Plus version).
+ */
+ newsize = sc->utf16nfc.length + 2;
+ if (archive_string_ensure(&(sc->utf16nfd), newsize) == NULL)
+ return (-1);
+
+ inp = (UniChar *)sc->utf16nfc.s;
+ inAvail = archive_strlen(&(sc->utf16nfc));
+ sc->utf16nfd.length = 0;
+ outp = sc->utf16nfd.s;
+ outAvail = sc->utf16nfd.buffer_length -2;
+
+ do {
+ /* Reinitialize all state information. */
+ if (ResetUnicodeToTextInfo(sc->uniInfo) != noErr)
+ goto return_no_changed_data;
+
+ inCount = outCount = 0;
+ err = ConvertFromUnicodeToText(sc->uniInfo,
+ inAvail, inp,
+ kUnicodeDefaultDirectionMask, 0, NULL, NULL, NULL,
+ outAvail, &inCount, &outCount, outp);
+
+ if (err == noErr) {
+ sc->utf16nfd.length = outCount;
+ sc->utf16nfd.s[sc->utf16nfd.length] = 0;
+ sc->utf16nfd.s[sc->utf16nfd.length+1] = 0;
+ } else if (err == kTECOutputBufferFullStatus) {
+ newsize = inAvail - inCount;
+ if (newsize > inAvail)
+ newsize = inAvail;
+ newsize += sc->utf16nfd.buffer_length + 2;
+ if (archive_string_ensure(&(sc->utf16nfd), newsize)
+ == NULL)
+ return (-1);
+ outp = sc->utf16nfd.s;
+ outAvail = sc->utf16nfd.buffer_length -2;
+ } else
+ goto return_no_changed_data;
+ } while (err == kTECOutputBufferFullStatus);
+
+ /*
+ * If there is a next-step conversion, we should convert
+ * a UTF-16LE(NFD) string back to the original Unicode type.
+ */
+ saved_flag = sc->flag;/* save a flag. */
+ if (!(sc->flag &
+ (SCONV_TO_UTF16BE | SCONV_TO_UTF16LE | SCONV_TO_UTF8))) {
+ /*
+ * This case is going to be converted to another
+ * character-set through iconv.
+ */
+ if (sc->flag & SCONV_FROM_UTF16BE)
+ sc->flag |= SCONV_TO_UTF16BE;
+ else if (sc->flag & SCONV_FROM_UTF16LE)
+ sc->flag |= SCONV_TO_UTF16LE;
+ else
+ sc->flag |= SCONV_TO_UTF8;
+ }
+ sc->flag &= ~(SCONV_FROM_UTF16BE | SCONV_FROM_UTF8);
+ sc->flag |= SCONV_FROM_UTF16LE;
+ if (archive_string_append_unicode(as, sc->utf16nfd.s,
+ sc->utf16nfd.length, sc) != 0)
+ ret = -1;
+ sc->flag = saved_flag;/* restore the saved flag */
+ return (ret);
+
+return_no_changed_data:
+ /*
+ * Something conversion error happened, so we return a no normalized
+ * string with an error.
+ */
+ (void)archive_string_append_unicode(as, _p, len, sc);
+ return (-1);
+}
+
+#endif /* __APPLE__ */
+
+/*
+ * libarchive 2.x made incorrect UTF-8 strings in the wrong assumption
+ * that WCS is Unicode. It is true for several platforms but some are false.
+ * And then people who did not use UTF-8 locale on the non Unicode WCS
+ * platform and made a tar file with libarchive(mostly bsdtar) 2.x. Those
+ * now cannot get right filename from libarchive 3.x and later since we
+ * fixed the wrong assumption and it is incompatible to older its versions.
+ * So we provide special option, "compat-2x.x", for resolving it.
+ * That option enable the string conversion of libarchive 2.x.
+ *
+ * Translates the wrong UTF-8 string made by libarchive 2.x into current
+ * locale character set and appends to the archive_string.
+ * Note: returns -1 if conversion fails.
+ */
+static int
+strncat_from_utf8_libarchive2(struct archive_string *as,
+ const void *_p, size_t len, struct archive_string_conv *sc)
+{
+ const char *s;
int n;
char *p;
- char buff[256];
+ char *end;
+ uint32_t unicode;
#if HAVE_WCRTOMB
mbstate_t shift_state;
@@ -421,33 +3464,774 @@ __archive_strappend_w_mbs(struct archive_string *as, const wchar_t *w)
/* Clear the shift state before starting. */
wctomb(NULL, L'\0');
#endif
-
+ (void)sc; /* UNUSED */
/*
- * Convert one wide char at a time into 'buff', whenever that
- * fills, append it to the string.
+ * Allocate buffer for MBS.
+ * We need this allocation here since it is possible that
+ * as->s is still NULL.
*/
- p = buff;
- while (*w != L'\0') {
- /* Flush the buffer when we have <=16 bytes free. */
- /* (No encoding has a single character >16 bytes.) */
- if ((size_t)(p - buff) >= (size_t)(sizeof(buff) - MB_CUR_MAX)) {
- *p = '\0';
- archive_strcat(as, buff);
- p = buff;
+ if (archive_string_ensure(as, as->length + len + 1) == NULL)
+ return (-1);
+
+ s = (const char *)_p;
+ p = as->s + as->length;
+ end = as->s + as->buffer_length - MB_CUR_MAX -1;
+ while ((n = _utf8_to_unicode(&unicode, s, len)) != 0) {
+ wchar_t wc;
+
+ if (p >= end) {
+ as->length = p - as->s;
+ /* Re-allocate buffer for MBS. */
+ if (archive_string_ensure(as,
+ as->length + len * 2 + 1) == NULL)
+ return (-1);
+ p = as->s + as->length;
+ end = as->s + as->buffer_length - MB_CUR_MAX -1;
}
+
+ /*
+ * As libarchie 2.x, translates the UTF-8 characters into
+ * wide-characters in the assumption that WCS is Unicode.
+ */
+ if (n < 0) {
+ n *= -1;
+ wc = L'?';
+ } else
+ wc = (wchar_t)unicode;
+
+ s += n;
+ len -= n;
+ /*
+ * Translates the wide-character into the current locale MBS.
+ */
#if HAVE_WCRTOMB
- n = wcrtomb(p, *w++, &shift_state);
+ n = wcrtomb(p, wc, &shift_state);
#else
- n = wctomb(p, *w++);
+ n = wctomb(p, wc);
#endif
if (n == -1)
- return (NULL);
+ return (-1);
p += n;
}
- *p = '\0';
- archive_strcat(as, buff);
- return (as);
+ as->length = p - as->s;
+ as->s[as->length] = '\0';
+ return (0);
+}
+
+
+/*
+ * Conversion functions between current locale dependent MBS and UTF-16BE.
+ * strncat_from_utf16be() : UTF-16BE --> MBS
+ * strncat_to_utf16be() : MBS --> UTF16BE
+ */
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+
+/*
+ * Convert a UTF-16BE/LE string to current locale and copy the result.
+ * Return -1 if conversion failes.
+ */
+static int
+win_strncat_from_utf16(struct archive_string *as, const void *_p, size_t bytes,
+ struct archive_string_conv *sc, int be)
+{
+ struct archive_string tmp;
+ const char *u16;
+ int ll;
+ BOOL defchar;
+ char *mbs;
+ size_t mbs_size, b;
+ int ret = 0;
+
+ bytes &= ~1;
+ if (archive_string_ensure(as, as->length + bytes +1) == NULL)
+ return (-1);
+
+ mbs = as->s + as->length;
+ mbs_size = as->buffer_length - as->length -1;
+
+ if (sc->to_cp == CP_C_LOCALE) {
+ /*
+ * "C" locale special process.
+ */
+ u16 = _p;
+ ll = 0;
+ for (b = 0; b < bytes; b += 2) {
+ uint16_t val;
+ if (be)
+ val = archive_be16dec(u16+b);
+ else
+ val = archive_le16dec(u16+b);
+ if (val > 255) {
+ *mbs++ = '?';
+ ret = -1;
+ } else
+ *mbs++ = (char)(val&0xff);
+ ll++;
+ }
+ as->length += ll;
+ as->s[as->length] = '\0';
+ return (ret);
+ }
+
+ archive_string_init(&tmp);
+ if (be) {
+ if (is_big_endian()) {
+ u16 = _p;
+ } else {
+ if (archive_string_ensure(&tmp, bytes+2) == NULL)
+ return (-1);
+ memcpy(tmp.s, _p, bytes);
+ for (b = 0; b < bytes; b += 2) {
+ uint16_t val = archive_be16dec(tmp.s+b);
+ archive_le16enc(tmp.s+b, val);
+ }
+ u16 = tmp.s;
+ }
+ } else {
+ if (!is_big_endian()) {
+ u16 = _p;
+ } else {
+ if (archive_string_ensure(&tmp, bytes+2) == NULL)
+ return (-1);
+ memcpy(tmp.s, _p, bytes);
+ for (b = 0; b < bytes; b += 2) {
+ uint16_t val = archive_le16dec(tmp.s+b);
+ archive_be16enc(tmp.s+b, val);
+ }
+ u16 = tmp.s;
+ }
+ }
+
+ do {
+ defchar = 0;
+ ll = WideCharToMultiByte(sc->to_cp, 0,
+ (LPCWSTR)u16, bytes>>1, mbs, mbs_size,
+ NULL, &defchar);
+ if (ll == 0 &&
+ GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+ /* Need more buffer for MBS. */
+ ll = WideCharToMultiByte(sc->to_cp, 0,
+ (LPCWSTR)u16, bytes, NULL, 0, NULL, NULL);
+ if (archive_string_ensure(as, ll +1) == NULL)
+ return (-1);
+ mbs = as->s + as->length;
+ mbs_size = as->buffer_length - as->length -1;
+ continue;
+ }
+ } while (0);
+ archive_string_free(&tmp);
+ as->length += ll;
+ as->s[as->length] = '\0';
+ if (ll == 0 || defchar)
+ ret = -1;
+ return (ret);
+}
+
+static int
+win_strncat_from_utf16be(struct archive_string *as, const void *_p, size_t bytes,
+ struct archive_string_conv *sc)
+{
+ return (win_strncat_from_utf16(as, _p, bytes, sc, 1));
+}
+
+static int
+win_strncat_from_utf16le(struct archive_string *as, const void *_p, size_t bytes,
+ struct archive_string_conv *sc)
+{
+ return (win_strncat_from_utf16(as, _p, bytes, sc, 0));
+}
+
+static int
+is_big_endian(void)
+{
+ uint16_t d = 1;
+
+ return (archive_be16dec(&d) == 1);
+}
+
+/*
+ * Convert a current locale string to UTF-16BE/LE and copy the result.
+ * Return -1 if conversion failes.
+ */
+static int
+win_strncat_to_utf16(struct archive_string *as16, const void *_p, size_t length,
+ struct archive_string_conv *sc, int bigendian)
+{
+ const char *s = (const char *)_p;
+ char *u16;
+ size_t count, avail;
+
+ if (archive_string_ensure(as16,
+ as16->length + (length + 1) * 2) == NULL)
+ return (-1);
+
+ u16 = as16->s + as16->length;
+ avail = as16->buffer_length - 2;
+ if (sc->from_cp == CP_C_LOCALE) {
+ /*
+ * "C" locale special process.
+ */
+ count = 0;
+ while (count < length && *s) {
+ if (bigendian)
+ archive_be16enc(u16, *s);
+ else
+ archive_le16enc(u16, *s);
+ u16 += 2;
+ s++;
+ count++;
+ }
+ as16->length += count << 1;
+ as16->s[as16->length] = 0;
+ as16->s[as16->length+1] = 0;
+ return (0);
+ }
+ do {
+ count = MultiByteToWideChar(sc->from_cp,
+ MB_PRECOMPOSED, s, length, (LPWSTR)u16, (int)avail>>1);
+ if (count == 0 &&
+ GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+ /* Need more buffer for UTF-16 string */
+ count = MultiByteToWideChar(sc->from_cp,
+ MB_PRECOMPOSED, s, length, NULL, 0);
+ if (archive_string_ensure(as16, (count +1) * 2)
+ == NULL)
+ return (-1);
+ u16 = as16->s + as16->length;
+ avail = as16->buffer_length - 2;
+ continue;
+ }
+ } while (0);
+ as16->length += count * 2;
+ as16->s[as16->length] = 0;
+ as16->s[as16->length+1] = 0;
+ if (count == 0)
+ return (-1);
+
+ if (is_big_endian()) {
+ if (!bigendian) {
+ while (count > 0) {
+ uint16_t v = archive_be16dec(u16);
+ archive_le16enc(u16, v);
+ u16 += 2;
+ count--;
+ }
+ }
+ } else {
+ if (bigendian) {
+ while (count > 0) {
+ uint16_t v = archive_le16dec(u16);
+ archive_be16enc(u16, v);
+ u16 += 2;
+ count--;
+ }
+ }
+ }
+ return (0);
+}
+
+static int
+win_strncat_to_utf16be(struct archive_string *as16, const void *_p, size_t length,
+ struct archive_string_conv *sc)
+{
+ return (win_strncat_to_utf16(as16, _p, length, sc, 1));
+}
+
+static int
+win_strncat_to_utf16le(struct archive_string *as16, const void *_p, size_t length,
+ struct archive_string_conv *sc)
+{
+ return (win_strncat_to_utf16(as16, _p, length, sc, 0));
+}
+
+#endif /* _WIN32 && !__CYGWIN__ */
+
+/*
+ * Do the best effort for conversions.
+ * We cannot handle UTF-16BE character-set without such iconv,
+ * but there is a chance if a string consists just ASCII code or
+ * a current locale is UTF-8.
+ */
+
+/*
+ * Convert a UTF-16BE string to current locale and copy the result.
+ * Return -1 if conversion failes.
+ */
+static int
+best_effort_strncat_from_utf16(struct archive_string *as, const void *_p,
+ size_t bytes, struct archive_string_conv *sc, int be)
+{
+ const char *utf16 = (const char *)_p;
+ char *mbs;
+ uint32_t uc;
+ int n, ret;
+
+ (void)sc; /* UNUSED */
+ /*
+ * Other case, we should do the best effort.
+ * If all character are ASCII(<0x7f), we can convert it.
+ * if not , we set a alternative character and return -1.
+ */
+ ret = 0;
+ if (archive_string_ensure(as, as->length + bytes +1) == NULL)
+ return (-1);
+ mbs = as->s + as->length;
+
+ while ((n = utf16_to_unicode(&uc, utf16, bytes, be)) != 0) {
+ if (n < 0) {
+ n *= -1;
+ ret = -1;
+ }
+ bytes -= n;
+ utf16 += n;
+
+ if (uc > 127) {
+ /* We cannot handle it. */
+ *mbs++ = '?';
+ ret = -1;
+ } else
+ *mbs++ = (char)uc;
+ }
+ as->length = mbs - as->s;
+ as->s[as->length] = '\0';
+ return (ret);
+}
+
+static int
+best_effort_strncat_from_utf16be(struct archive_string *as, const void *_p,
+ size_t bytes, struct archive_string_conv *sc)
+{
+ return (best_effort_strncat_from_utf16(as, _p, bytes, sc, 1));
+}
+
+static int
+best_effort_strncat_from_utf16le(struct archive_string *as, const void *_p,
+ size_t bytes, struct archive_string_conv *sc)
+{
+ return (best_effort_strncat_from_utf16(as, _p, bytes, sc, 0));
+}
+
+/*
+ * Convert a current locale string to UTF-16BE/LE and copy the result.
+ * Return -1 if conversion failes.
+ */
+static int
+best_effort_strncat_to_utf16(struct archive_string *as16, const void *_p,
+ size_t length, struct archive_string_conv *sc, int bigendian)
+{
+ const char *s = (const char *)_p;
+ char *utf16;
+ size_t remaining;
+ int ret;
+
+ (void)sc; /* UNUSED */
+ /*
+ * Other case, we should do the best effort.
+ * If all character are ASCII(<0x7f), we can convert it.
+ * if not , we set a alternative character and return -1.
+ */
+ ret = 0;
+ remaining = length;
+
+ if (archive_string_ensure(as16,
+ as16->length + (length + 1) * 2) == NULL)
+ return (-1);
+
+ utf16 = as16->s + as16->length;
+ while (remaining--) {
+ unsigned c = *s++;
+ if (c > 127) {
+ /* We cannot handle it. */
+ c = UNICODE_R_CHAR;
+ ret = -1;
+ }
+ if (bigendian)
+ archive_be16enc(utf16, c);
+ else
+ archive_le16enc(utf16, c);
+ utf16 += 2;
+ }
+ as16->length = utf16 - as16->s;
+ as16->s[as16->length] = 0;
+ as16->s[as16->length+1] = 0;
+ return (ret);
+}
+
+static int
+best_effort_strncat_to_utf16be(struct archive_string *as16, const void *_p,
+ size_t length, struct archive_string_conv *sc)
+{
+ return (best_effort_strncat_to_utf16(as16, _p, length, sc, 1));
+}
+
+static int
+best_effort_strncat_to_utf16le(struct archive_string *as16, const void *_p,
+ size_t length, struct archive_string_conv *sc)
+{
+ return (best_effort_strncat_to_utf16(as16, _p, length, sc, 0));
+}
+
+
+/*
+ * Multistring operations.
+ */
+
+void
+archive_mstring_clean(struct archive_mstring *aes)
+{
+ archive_wstring_free(&(aes->aes_wcs));
+ archive_string_free(&(aes->aes_mbs));
+ archive_string_free(&(aes->aes_utf8));
+ archive_string_free(&(aes->aes_mbs_in_locale));
+ aes->aes_set = 0;
+}
+
+void
+archive_mstring_copy(struct archive_mstring *dest, struct archive_mstring *src)
+{
+ dest->aes_set = src->aes_set;
+ archive_string_copy(&(dest->aes_mbs), &(src->aes_mbs));
+ archive_string_copy(&(dest->aes_utf8), &(src->aes_utf8));
+ archive_wstring_copy(&(dest->aes_wcs), &(src->aes_wcs));
+}
+
+int
+archive_mstring_get_utf8(struct archive *a, struct archive_mstring *aes,
+ const char **p)
+{
+ struct archive_string_conv *sc;
+ int r;
+
+ /* If we already have a UTF8 form, return that immediately. */
+ if (aes->aes_set & AES_SET_UTF8) {
+ *p = aes->aes_utf8.s;
+ return (0);
+ }
+
+ *p = NULL;
+ if (aes->aes_set & AES_SET_MBS) {
+ sc = archive_string_conversion_to_charset(a, "UTF-8", 1);
+ if (sc == NULL)
+ return (-1);/* Couldn't allocate memory for sc. */
+ r = archive_strncpy_in_locale(&(aes->aes_mbs), aes->aes_mbs.s,
+ aes->aes_mbs.length, sc);
+ if (a == NULL)
+ free_sconv_object(sc);
+ if (r == 0) {
+ aes->aes_set |= AES_SET_UTF8;
+ *p = aes->aes_utf8.s;
+ return (0);/* success. */
+ } else
+ return (-1);/* failure. */
+ }
+ return (0);/* success. */
+}
+
+int
+archive_mstring_get_mbs(struct archive *a, struct archive_mstring *aes,
+ const char **p)
+{
+ int r, ret = 0;
+
+ (void)a; /* UNUSED */
+ /* If we already have an MBS form, return that immediately. */
+ if (aes->aes_set & AES_SET_MBS) {
+ *p = aes->aes_mbs.s;
+ return (ret);
+ }
+
+ *p = NULL;
+ /* If there's a WCS form, try converting with the native locale. */
+ if (aes->aes_set & AES_SET_WCS) {
+ archive_string_empty(&(aes->aes_mbs));
+ r = archive_string_append_from_wcs(&(aes->aes_mbs),
+ aes->aes_wcs.s, aes->aes_wcs.length);
+ *p = aes->aes_mbs.s;
+ if (r == 0) {
+ aes->aes_set |= AES_SET_MBS;
+ return (ret);
+ } else
+ ret = -1;
+ }
+
+ /*
+ * Only a UTF-8 form cannot avail because its conversion already
+ * failed at archive_mstring_update_utf8().
+ */
+ return (ret);
+}
+
+int
+archive_mstring_get_wcs(struct archive *a, struct archive_mstring *aes,
+ const wchar_t **wp)
+{
+ int r, ret = 0;
+
+ (void)a;/* UNUSED */
+ /* Return WCS form if we already have it. */
+ if (aes->aes_set & AES_SET_WCS) {
+ *wp = aes->aes_wcs.s;
+ return (ret);
+ }
+
+ *wp = NULL;
+ /* Try converting MBS to WCS using native locale. */
+ if (aes->aes_set & AES_SET_MBS) {
+ archive_wstring_empty(&(aes->aes_wcs));
+ r = archive_wstring_append_from_mbs(&(aes->aes_wcs),
+ aes->aes_mbs.s, aes->aes_mbs.length);
+ if (r == 0) {
+ aes->aes_set |= AES_SET_WCS;
+ *wp = aes->aes_wcs.s;
+ } else
+ ret = -1;/* failure. */
+ }
+ return (ret);
+}
+
+int
+archive_mstring_get_mbs_l(struct archive_mstring *aes,
+ const char **p, size_t *length, struct archive_string_conv *sc)
+{
+ int r, ret = 0;
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ /*
+ * Internationalization programing on Windows must use Wide
+ * characters because Windows platform cannot make locale UTF-8.
+ */
+ if (sc != NULL && (aes->aes_set & AES_SET_WCS) != 0) {
+ archive_string_empty(&(aes->aes_mbs_in_locale));
+ r = archive_string_append_from_wcs_in_codepage(
+ &(aes->aes_mbs_in_locale), aes->aes_wcs.s,
+ aes->aes_wcs.length, sc);
+ if (r == 0) {
+ *p = aes->aes_mbs_in_locale.s;
+ if (length != NULL)
+ *length = aes->aes_mbs_in_locale.length;
+ return (0);
+ } else if (errno == ENOMEM)
+ return (-1);
+ else
+ ret = -1;
+ }
+#endif
+
+ /* If there is not an MBS form but is a WCS form, try converting
+ * with the native locale to be used for translating it to specified
+ * character-set. */
+ if ((aes->aes_set & AES_SET_MBS) == 0 &&
+ (aes->aes_set & AES_SET_WCS) != 0) {
+ archive_string_empty(&(aes->aes_mbs));
+ r = archive_string_append_from_wcs(&(aes->aes_mbs),
+ aes->aes_wcs.s, aes->aes_wcs.length);
+ if (r == 0)
+ aes->aes_set |= AES_SET_MBS;
+ else if (errno == ENOMEM)
+ return (-1);
+ else
+ ret = -1;
+ }
+ /* If we already have an MBS form, use it to be translated to
+ * specified character-set. */
+ if (aes->aes_set & AES_SET_MBS) {
+ if (sc == NULL) {
+ /* Conversion is unneeded. */
+ *p = aes->aes_mbs.s;
+ if (length != NULL)
+ *length = aes->aes_mbs.length;
+ return (0);
+ }
+ ret = archive_strncpy_in_locale(&(aes->aes_mbs_in_locale),
+ aes->aes_mbs.s, aes->aes_mbs.length, sc);
+ *p = aes->aes_mbs_in_locale.s;
+ if (length != NULL)
+ *length = aes->aes_mbs_in_locale.length;
+ } else {
+ *p = NULL;
+ if (length != NULL)
+ *length = 0;
+ }
+ return (ret);
+}
+
+int
+archive_mstring_copy_mbs(struct archive_mstring *aes, const char *mbs)
+{
+ if (mbs == NULL) {
+ aes->aes_set = 0;
+ return (0);
+ }
+ return (archive_mstring_copy_mbs_len(aes, mbs, strlen(mbs)));
+}
+
+int
+archive_mstring_copy_mbs_len(struct archive_mstring *aes, const char *mbs,
+ size_t len)
+{
+ if (mbs == NULL) {
+ aes->aes_set = 0;
+ return (0);
+ }
+ aes->aes_set = AES_SET_MBS; /* Only MBS form is set now. */
+ archive_strncpy(&(aes->aes_mbs), mbs, len);
+ archive_string_empty(&(aes->aes_utf8));
+ archive_wstring_empty(&(aes->aes_wcs));
+ return (0);
+}
+
+int
+archive_mstring_copy_wcs(struct archive_mstring *aes, const wchar_t *wcs)
+{
+ return archive_mstring_copy_wcs_len(aes, wcs, wcs == NULL ? 0 : wcslen(wcs));
+}
+
+int
+archive_mstring_copy_wcs_len(struct archive_mstring *aes, const wchar_t *wcs,
+ size_t len)
+{
+ if (wcs == NULL) {
+ aes->aes_set = 0;
+ }
+ aes->aes_set = AES_SET_WCS; /* Only WCS form set. */
+ archive_string_empty(&(aes->aes_mbs));
+ archive_string_empty(&(aes->aes_utf8));
+ archive_wstrncpy(&(aes->aes_wcs), wcs, len);
+ return (0);
+}
+
+int
+archive_mstring_copy_mbs_len_l(struct archive_mstring *aes,
+ const char *mbs, size_t len, struct archive_string_conv *sc)
+{
+ int r;
+
+ if (mbs == NULL) {
+ aes->aes_set = 0;
+ return (0);
+ }
+ archive_string_empty(&(aes->aes_mbs));
+ archive_wstring_empty(&(aes->aes_wcs));
+ archive_string_empty(&(aes->aes_utf8));
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ /*
+ * Internationalization programing on Windows must use Wide
+ * characters because Windows platform cannot make locale UTF-8.
+ */
+ if (sc == NULL) {
+ if (archive_string_append(&(aes->aes_mbs),
+ mbs, mbsnbytes(mbs, len)) == NULL) {
+ aes->aes_set = 0;
+ r = -1;
+ } else {
+ aes->aes_set = AES_SET_MBS;
+ r = 0;
+ }
+#if defined(HAVE_ICONV)
+ } else if (sc != NULL && sc->cd_w != (iconv_t)-1) {
+ /*
+ * This case happens only when MultiByteToWideChar() cannot
+ * handle sc->from_cp, and we have to iconv in order to
+ * translate character-set to wchar_t,UTF-16.
+ */
+ iconv_t cd = sc->cd;
+ unsigned from_cp;
+ int flag;
+
+ /*
+ * Translate multi-bytes from some character-set to UTF-8.
+ */
+ sc->cd = sc->cd_w;
+ r = archive_strncpy_in_locale(&(aes->aes_utf8), mbs, len, sc);
+ sc->cd = cd;
+ if (r != 0) {
+ aes->aes_set = 0;
+ return (r);
+ }
+ aes->aes_set = AES_SET_UTF8;
+
+ /*
+ * Append the UTF-8 string into wstring.
+ */
+ flag = sc->flag;
+ sc->flag &= ~(SCONV_NORMALIZATION_C
+ | SCONV_TO_UTF16| SCONV_FROM_UTF16);
+ from_cp = sc->from_cp;
+ sc->from_cp = CP_UTF8;
+ r = archive_wstring_append_from_mbs_in_codepage(&(aes->aes_wcs),
+ aes->aes_utf8.s, aes->aes_utf8.length, sc);
+ sc->flag = flag;
+ sc->from_cp = from_cp;
+ if (r == 0)
+ aes->aes_set |= AES_SET_WCS;
+#endif
+ } else {
+ r = archive_wstring_append_from_mbs_in_codepage(
+ &(aes->aes_wcs), mbs, len, sc);
+ if (r == 0)
+ aes->aes_set = AES_SET_WCS;
+ else
+ aes->aes_set = 0;
+ }
+#else
+ r = archive_strncpy_in_locale(&(aes->aes_mbs), mbs, len, sc);
+ if (r == 0)
+ aes->aes_set = AES_SET_MBS; /* Only MBS form is set now. */
+ else
+ aes->aes_set = 0;
#endif
+ return (r);
}
-#endif /* _WIN32 && ! __CYGWIN__ */
+/*
+ * The 'update' form tries to proactively update all forms of
+ * this string (WCS and MBS) and returns an error if any of
+ * them fail. This is used by the 'pax' handler, for instance,
+ * to detect and report character-conversion failures early while
+ * still allowing clients to get potentially useful values from
+ * the more tolerant lazy conversions. (get_mbs and get_wcs will
+ * strive to give the user something useful, so you can get hopefully
+ * usable values even if some of the character conversions are failing.)
+ */
+int
+archive_mstring_update_utf8(struct archive *a, struct archive_mstring *aes,
+ const char *utf8)
+{
+ struct archive_string_conv *sc;
+ int r;
+
+ if (utf8 == NULL) {
+ aes->aes_set = 0;
+ return (0); /* Succeeded in clearing everything. */
+ }
+
+ /* Save the UTF8 string. */
+ archive_strcpy(&(aes->aes_utf8), utf8);
+
+ /* Empty the mbs and wcs strings. */
+ archive_string_empty(&(aes->aes_mbs));
+ archive_wstring_empty(&(aes->aes_wcs));
+
+ aes->aes_set = AES_SET_UTF8; /* Only UTF8 is set now. */
+
+ /* Try converting UTF-8 to MBS, return false on failure. */
+ sc = archive_string_conversion_from_charset(a, "UTF-8", 1);
+ if (sc == NULL)
+ return (-1);/* Couldn't allocate memory for sc. */
+ r = archive_strcpy_in_locale(&(aes->aes_mbs), utf8, sc);
+ if (a == NULL)
+ free_sconv_object(sc);
+ if (r != 0)
+ return (-1);
+ aes->aes_set = AES_SET_UTF8 | AES_SET_MBS; /* Both UTF8 and MBS set. */
+
+ /* Try converting MBS to WCS, return false on failure. */
+ if (archive_wstring_append_from_mbs(&(aes->aes_wcs), aes->aes_mbs.s,
+ aes->aes_mbs.length))
+ return (-1);
+ aes->aes_set = AES_SET_UTF8 | AES_SET_WCS | AES_SET_MBS;
+
+ /* All conversions succeeded. */
+ return (0);
+}
diff --git a/libarchive/archive_string.h b/libarchive/archive_string.h
index 782c1b162a7d..0e4c9b9041e3 100644
--- a/libarchive/archive_string.h
+++ b/libarchive/archive_string.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2003-2010 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,8 +27,10 @@
*/
#ifndef __LIBARCHIVE_BUILD
+#ifndef __LIBARCHIVE_TEST
#error This header is only to be used internally to libarchive.
#endif
+#endif
#ifndef ARCHIVE_STRING_H_INCLUDED
#define ARCHIVE_STRING_H_INCLUDED
@@ -47,62 +49,97 @@
#include "archive.h"
/*
- * Basic resizable/reusable string support a la Java's "StringBuffer."
+ * Basic resizable/reusable string support similar to Java's "StringBuffer."
*
* Unlike sbuf(9), the buffers here are fully reusable and track the
* length throughout.
- *
- * Note that all visible symbols here begin with "__archive" as they
- * are internal symbols not intended for anyone outside of this library
- * to see or use.
*/
struct archive_string {
char *s; /* Pointer to the storage */
- size_t length; /* Length of 's' */
- size_t buffer_length; /* Length of malloc-ed storage */
+ size_t length; /* Length of 's' in characters */
+ size_t buffer_length; /* Length of malloc-ed storage in bytes. */
+};
+
+struct archive_wstring {
+ wchar_t *s; /* Pointer to the storage */
+ size_t length; /* Length of 's' in characters */
+ size_t buffer_length; /* Length of malloc-ed storage in bytes. */
};
+struct archive_string_conv;
+
/* Initialize an archive_string object on the stack or elsewhere. */
#define archive_string_init(a) \
do { (a)->s = NULL; (a)->length = 0; (a)->buffer_length = 0; } while(0)
/* Append a C char to an archive_string, resizing as necessary. */
struct archive_string *
-__archive_strappend_char(struct archive_string *, char);
-#define archive_strappend_char __archive_strappend_char
+archive_strappend_char(struct archive_string *, char);
+
+/* Ditto for a wchar_t and an archive_wstring. */
+struct archive_wstring *
+archive_wstrappend_wchar(struct archive_wstring *, wchar_t);
+
+/* Convert a Unicode string to current locale and append the result. */
+/* Returns -1 if conversion fails. */
+int
+archive_string_append_from_wcs(struct archive_string *, const wchar_t *, size_t);
+
+
+/* Create a string conversion object.
+ * Return NULL and set a error message if the conversion is not supported
+ * on the platform. */
+struct archive_string_conv *
+archive_string_conversion_to_charset(struct archive *, const char *, int);
+struct archive_string_conv *
+archive_string_conversion_from_charset(struct archive *, const char *, int);
+/* Create the default string conversion object for reading/writing an archive.
+ * Return NULL if the conversion is unneeded.
+ * Note: On non Windows platform this always returns NULL.
+ */
+struct archive_string_conv *
+archive_string_default_conversion_for_read(struct archive *);
+struct archive_string_conv *
+archive_string_default_conversion_for_write(struct archive *);
+/* Dispose of a string conversion object. */
+void
+archive_string_conversion_free(struct archive *);
+const char *
+archive_string_conversion_charset_name(struct archive_string_conv *);
+void
+archive_string_conversion_set_opt(struct archive_string_conv *, int);
+#define SCONV_SET_OPT_UTF8_LIBARCHIVE2X 1
-/* Convert a wide-char string to UTF-8 and append the result. */
-struct archive_string *
-__archive_strappend_w_utf8(struct archive_string *, const wchar_t *);
-#define archive_strappend_w_utf8 __archive_strappend_w_utf8
-/* Convert a wide-char string to current locale and append the result. */
-/* Returns NULL if conversion fails. */
-struct archive_string *
-__archive_strappend_w_mbs(struct archive_string *, const wchar_t *);
-#define archive_strappend_w_mbs __archive_strappend_w_mbs
+/* Copy one archive_string to another in locale conversion.
+ * Return -1 if conversion failes. */
+int
+archive_strncpy_in_locale(struct archive_string *, const void *, size_t,
+ struct archive_string_conv *);
+
+/* Copy one archive_string to another in locale conversion.
+ * Return -1 if conversion failes. */
+int
+archive_strncat_in_locale(struct archive_string *, const void *, size_t,
+ struct archive_string_conv *);
-/* Basic append operation. */
-struct archive_string *
-__archive_string_append(struct archive_string *as, const char *p, size_t s);
/* Copy one archive_string to another */
-void
-__archive_string_copy(struct archive_string *dest, struct archive_string *src);
-#define archive_string_copy(dest, src) \
- __archive_string_copy(dest, src)
+#define archive_string_copy(dest, src) \
+ ((dest)->length = 0, archive_string_concat((dest), (src)))
+#define archive_wstring_copy(dest, src) \
+ ((dest)->length = 0, archive_wstring_concat((dest), (src)))
/* Concatenate one archive_string to another */
-void
-__archive_string_concat(struct archive_string *dest, struct archive_string *src);
-#define archive_string_concat(dest, src) \
- __archive_string_concat(dest, src)
+void archive_string_concat(struct archive_string *dest, struct archive_string *src);
+void archive_wstring_concat(struct archive_wstring *dest, struct archive_wstring *src);
/* Ensure that the underlying buffer is at least as large as the request. */
struct archive_string *
-__archive_string_ensure(struct archive_string *, size_t);
-#define archive_string_ensure __archive_string_ensure
+archive_string_ensure(struct archive_string *, size_t);
+struct archive_wstring *
+archive_wstring_ensure(struct archive_wstring *, size_t);
/* Append C string, which may lack trailing \0. */
/* The source is declared void * here because this gets used with
@@ -110,42 +147,91 @@ __archive_string_ensure(struct archive_string *, size_t);
* Declaring it "char *" as with some of the other functions just
* leads to a lot of extra casts. */
struct archive_string *
-__archive_strncat(struct archive_string *, const void *, size_t);
-#define archive_strncat __archive_strncat
+archive_strncat(struct archive_string *, const void *, size_t);
+struct archive_wstring *
+archive_wstrncat(struct archive_wstring *, const wchar_t *, size_t);
/* Append a C string to an archive_string, resizing as necessary. */
-#define archive_strcat(as,p) __archive_string_append((as),(p),strlen(p))
+struct archive_string *
+archive_strcat(struct archive_string *, const void *);
+struct archive_wstring *
+archive_wstrcat(struct archive_wstring *, const wchar_t *);
/* Copy a C string to an archive_string, resizing as necessary. */
#define archive_strcpy(as,p) \
- ((as)->length = 0, __archive_string_append((as), (p), p == NULL ? 0 : strlen(p)))
+ archive_strncpy((as), (p), ((p) == NULL ? 0 : strlen(p)))
+#define archive_wstrcpy(as,p) \
+ archive_wstrncpy((as), (p), ((p) == NULL ? 0 : wcslen(p)))
+#define archive_strcpy_in_locale(as,p,lo) \
+ archive_strncpy_in_locale((as), (p), ((p) == NULL ? 0 : strlen(p)), (lo))
/* Copy a C string to an archive_string with limit, resizing as necessary. */
#define archive_strncpy(as,p,l) \
((as)->length=0, archive_strncat((as), (p), (l)))
+#define archive_wstrncpy(as,p,l) \
+ ((as)->length = 0, archive_wstrncat((as), (p), (l)))
/* Return length of string. */
#define archive_strlen(a) ((a)->length)
/* Set string length to zero. */
#define archive_string_empty(a) ((a)->length = 0)
+#define archive_wstring_empty(a) ((a)->length = 0)
/* Release any allocated storage resources. */
-void __archive_string_free(struct archive_string *);
-#define archive_string_free __archive_string_free
+void archive_string_free(struct archive_string *);
+void archive_wstring_free(struct archive_wstring *);
/* Like 'vsprintf', but resizes the underlying string as necessary. */
-void __archive_string_vsprintf(struct archive_string *, const char *,
+/* Note: This only implements a small subset of standard printf functionality. */
+void archive_string_vsprintf(struct archive_string *, const char *,
va_list) __LA_PRINTF(2, 0);
-#define archive_string_vsprintf __archive_string_vsprintf
-
-void __archive_string_sprintf(struct archive_string *, const char *, ...)
+void archive_string_sprintf(struct archive_string *, const char *, ...)
__LA_PRINTF(2, 3);
-#define archive_string_sprintf __archive_string_sprintf
-/* Allocates a fresh buffer and converts as (assumed to be UTF-8) into it.
- * Returns NULL if conversion failed in any way. */
-wchar_t *__archive_string_utf8_w(struct archive_string *as);
+/* Translates from MBS to Unicode. */
+/* Returns non-zero if conversion failed in any way. */
+int archive_wstring_append_from_mbs(struct archive_wstring *dest,
+ const char *, size_t);
+
+
+/* A "multistring" can hold Unicode, UTF8, or MBS versions of
+ * the string. If you set and read the same version, no translation
+ * is done. If you set and read different versions, the library
+ * will attempt to transparently convert.
+ */
+struct archive_mstring {
+ struct archive_string aes_mbs;
+ struct archive_string aes_utf8;
+ struct archive_wstring aes_wcs;
+ struct archive_string aes_mbs_in_locale;
+ /* Bitmap of which of the above are valid. Because we're lazy
+ * about malloc-ing and reusing the underlying storage, we
+ * can't rely on NULL pointers to indicate whether a string
+ * has been set. */
+ int aes_set;
+#define AES_SET_MBS 1
+#define AES_SET_UTF8 2
+#define AES_SET_WCS 4
+};
+
+void archive_mstring_clean(struct archive_mstring *);
+void archive_mstring_copy(struct archive_mstring *dest, struct archive_mstring *src);
+int archive_mstring_get_mbs(struct archive *, struct archive_mstring *, const char **);
+int archive_mstring_get_utf8(struct archive *, struct archive_mstring *, const char **);
+int archive_mstring_get_wcs(struct archive *, struct archive_mstring *, const wchar_t **);
+int archive_mstring_get_mbs_l(struct archive_mstring *, const char **,
+ size_t *, struct archive_string_conv *);
+int archive_mstring_copy_mbs(struct archive_mstring *, const char *mbs);
+int archive_mstring_copy_mbs_len(struct archive_mstring *, const char *mbs,
+ size_t);
+int archive_mstring_copy_utf8(struct archive_mstring *, const char *utf8);
+int archive_mstring_copy_wcs(struct archive_mstring *, const wchar_t *wcs);
+int archive_mstring_copy_wcs_len(struct archive_mstring *,
+ const wchar_t *wcs, size_t);
+int archive_mstring_copy_mbs_len_l(struct archive_mstring *,
+ const char *mbs, size_t, struct archive_string_conv *);
+int archive_mstring_update_utf8(struct archive *, struct archive_mstring *aes, const char *utf8);
#endif
diff --git a/libarchive/archive_string_composition.h b/libarchive/archive_string_composition.h
new file mode 100644
index 000000000000..cc4bf46c0e15
--- /dev/null
+++ b/libarchive/archive_string_composition.h
@@ -0,0 +1,1351 @@
+/*-
+ * Copyright (c) 2011 libarchive Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+
+/*
+ * ATTENTION!
+ * This file is generated by build/utils/gen_archive_string_composition_h.sh
+ * from http://unicode.org/Public/UNIDATA/UnicodeData.txt
+ *
+ * See also http://unicode.org/report/tr15/
+ */
+
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
+#ifndef ARCHIVE_STRING_COMPOSITION_H_INCLUDED
+#define ARCHIVE_STRING_COMPOSITION_H_INCLUDED
+
+struct unicode_composition_table {
+ uint32_t cp1;
+ uint32_t cp2;
+ uint32_t nfc;
+};
+
+static const struct unicode_composition_table u_composition_table[] = {
+ { 0x0003C , 0x00338 , 0x0226E },
+ { 0x0003D , 0x00338 , 0x02260 },
+ { 0x0003E , 0x00338 , 0x0226F },
+ { 0x00041 , 0x00300 , 0x000C0 },
+ { 0x00041 , 0x00301 , 0x000C1 },
+ { 0x00041 , 0x00302 , 0x000C2 },
+ { 0x00041 , 0x00303 , 0x000C3 },
+ { 0x00041 , 0x00304 , 0x00100 },
+ { 0x00041 , 0x00306 , 0x00102 },
+ { 0x00041 , 0x00307 , 0x00226 },
+ { 0x00041 , 0x00308 , 0x000C4 },
+ { 0x00041 , 0x00309 , 0x01EA2 },
+ { 0x00041 , 0x0030A , 0x000C5 },
+ { 0x00041 , 0x0030C , 0x001CD },
+ { 0x00041 , 0x0030F , 0x00200 },
+ { 0x00041 , 0x00311 , 0x00202 },
+ { 0x00041 , 0x00323 , 0x01EA0 },
+ { 0x00041 , 0x00325 , 0x01E00 },
+ { 0x00041 , 0x00328 , 0x00104 },
+ { 0x00042 , 0x00307 , 0x01E02 },
+ { 0x00042 , 0x00323 , 0x01E04 },
+ { 0x00042 , 0x00331 , 0x01E06 },
+ { 0x00043 , 0x00301 , 0x00106 },
+ { 0x00043 , 0x00302 , 0x00108 },
+ { 0x00043 , 0x00307 , 0x0010A },
+ { 0x00043 , 0x0030C , 0x0010C },
+ { 0x00043 , 0x00327 , 0x000C7 },
+ { 0x00044 , 0x00307 , 0x01E0A },
+ { 0x00044 , 0x0030C , 0x0010E },
+ { 0x00044 , 0x00323 , 0x01E0C },
+ { 0x00044 , 0x00327 , 0x01E10 },
+ { 0x00044 , 0x0032D , 0x01E12 },
+ { 0x00044 , 0x00331 , 0x01E0E },
+ { 0x00045 , 0x00300 , 0x000C8 },
+ { 0x00045 , 0x00301 , 0x000C9 },
+ { 0x00045 , 0x00302 , 0x000CA },
+ { 0x00045 , 0x00303 , 0x01EBC },
+ { 0x00045 , 0x00304 , 0x00112 },
+ { 0x00045 , 0x00306 , 0x00114 },
+ { 0x00045 , 0x00307 , 0x00116 },
+ { 0x00045 , 0x00308 , 0x000CB },
+ { 0x00045 , 0x00309 , 0x01EBA },
+ { 0x00045 , 0x0030C , 0x0011A },
+ { 0x00045 , 0x0030F , 0x00204 },
+ { 0x00045 , 0x00311 , 0x00206 },
+ { 0x00045 , 0x00323 , 0x01EB8 },
+ { 0x00045 , 0x00327 , 0x00228 },
+ { 0x00045 , 0x00328 , 0x00118 },
+ { 0x00045 , 0x0032D , 0x01E18 },
+ { 0x00045 , 0x00330 , 0x01E1A },
+ { 0x00046 , 0x00307 , 0x01E1E },
+ { 0x00047 , 0x00301 , 0x001F4 },
+ { 0x00047 , 0x00302 , 0x0011C },
+ { 0x00047 , 0x00304 , 0x01E20 },
+ { 0x00047 , 0x00306 , 0x0011E },
+ { 0x00047 , 0x00307 , 0x00120 },
+ { 0x00047 , 0x0030C , 0x001E6 },
+ { 0x00047 , 0x00327 , 0x00122 },
+ { 0x00048 , 0x00302 , 0x00124 },
+ { 0x00048 , 0x00307 , 0x01E22 },
+ { 0x00048 , 0x00308 , 0x01E26 },
+ { 0x00048 , 0x0030C , 0x0021E },
+ { 0x00048 , 0x00323 , 0x01E24 },
+ { 0x00048 , 0x00327 , 0x01E28 },
+ { 0x00048 , 0x0032E , 0x01E2A },
+ { 0x00049 , 0x00300 , 0x000CC },
+ { 0x00049 , 0x00301 , 0x000CD },
+ { 0x00049 , 0x00302 , 0x000CE },
+ { 0x00049 , 0x00303 , 0x00128 },
+ { 0x00049 , 0x00304 , 0x0012A },
+ { 0x00049 , 0x00306 , 0x0012C },
+ { 0x00049 , 0x00307 , 0x00130 },
+ { 0x00049 , 0x00308 , 0x000CF },
+ { 0x00049 , 0x00309 , 0x01EC8 },
+ { 0x00049 , 0x0030C , 0x001CF },
+ { 0x00049 , 0x0030F , 0x00208 },
+ { 0x00049 , 0x00311 , 0x0020A },
+ { 0x00049 , 0x00323 , 0x01ECA },
+ { 0x00049 , 0x00328 , 0x0012E },
+ { 0x00049 , 0x00330 , 0x01E2C },
+ { 0x0004A , 0x00302 , 0x00134 },
+ { 0x0004B , 0x00301 , 0x01E30 },
+ { 0x0004B , 0x0030C , 0x001E8 },
+ { 0x0004B , 0x00323 , 0x01E32 },
+ { 0x0004B , 0x00327 , 0x00136 },
+ { 0x0004B , 0x00331 , 0x01E34 },
+ { 0x0004C , 0x00301 , 0x00139 },
+ { 0x0004C , 0x0030C , 0x0013D },
+ { 0x0004C , 0x00323 , 0x01E36 },
+ { 0x0004C , 0x00327 , 0x0013B },
+ { 0x0004C , 0x0032D , 0x01E3C },
+ { 0x0004C , 0x00331 , 0x01E3A },
+ { 0x0004D , 0x00301 , 0x01E3E },
+ { 0x0004D , 0x00307 , 0x01E40 },
+ { 0x0004D , 0x00323 , 0x01E42 },
+ { 0x0004E , 0x00300 , 0x001F8 },
+ { 0x0004E , 0x00301 , 0x00143 },
+ { 0x0004E , 0x00303 , 0x000D1 },
+ { 0x0004E , 0x00307 , 0x01E44 },
+ { 0x0004E , 0x0030C , 0x00147 },
+ { 0x0004E , 0x00323 , 0x01E46 },
+ { 0x0004E , 0x00327 , 0x00145 },
+ { 0x0004E , 0x0032D , 0x01E4A },
+ { 0x0004E , 0x00331 , 0x01E48 },
+ { 0x0004F , 0x00300 , 0x000D2 },
+ { 0x0004F , 0x00301 , 0x000D3 },
+ { 0x0004F , 0x00302 , 0x000D4 },
+ { 0x0004F , 0x00303 , 0x000D5 },
+ { 0x0004F , 0x00304 , 0x0014C },
+ { 0x0004F , 0x00306 , 0x0014E },
+ { 0x0004F , 0x00307 , 0x0022E },
+ { 0x0004F , 0x00308 , 0x000D6 },
+ { 0x0004F , 0x00309 , 0x01ECE },
+ { 0x0004F , 0x0030B , 0x00150 },
+ { 0x0004F , 0x0030C , 0x001D1 },
+ { 0x0004F , 0x0030F , 0x0020C },
+ { 0x0004F , 0x00311 , 0x0020E },
+ { 0x0004F , 0x0031B , 0x001A0 },
+ { 0x0004F , 0x00323 , 0x01ECC },
+ { 0x0004F , 0x00328 , 0x001EA },
+ { 0x00050 , 0x00301 , 0x01E54 },
+ { 0x00050 , 0x00307 , 0x01E56 },
+ { 0x00052 , 0x00301 , 0x00154 },
+ { 0x00052 , 0x00307 , 0x01E58 },
+ { 0x00052 , 0x0030C , 0x00158 },
+ { 0x00052 , 0x0030F , 0x00210 },
+ { 0x00052 , 0x00311 , 0x00212 },
+ { 0x00052 , 0x00323 , 0x01E5A },
+ { 0x00052 , 0x00327 , 0x00156 },
+ { 0x00052 , 0x00331 , 0x01E5E },
+ { 0x00053 , 0x00301 , 0x0015A },
+ { 0x00053 , 0x00302 , 0x0015C },
+ { 0x00053 , 0x00307 , 0x01E60 },
+ { 0x00053 , 0x0030C , 0x00160 },
+ { 0x00053 , 0x00323 , 0x01E62 },
+ { 0x00053 , 0x00326 , 0x00218 },
+ { 0x00053 , 0x00327 , 0x0015E },
+ { 0x00054 , 0x00307 , 0x01E6A },
+ { 0x00054 , 0x0030C , 0x00164 },
+ { 0x00054 , 0x00323 , 0x01E6C },
+ { 0x00054 , 0x00326 , 0x0021A },
+ { 0x00054 , 0x00327 , 0x00162 },
+ { 0x00054 , 0x0032D , 0x01E70 },
+ { 0x00054 , 0x00331 , 0x01E6E },
+ { 0x00055 , 0x00300 , 0x000D9 },
+ { 0x00055 , 0x00301 , 0x000DA },
+ { 0x00055 , 0x00302 , 0x000DB },
+ { 0x00055 , 0x00303 , 0x00168 },
+ { 0x00055 , 0x00304 , 0x0016A },
+ { 0x00055 , 0x00306 , 0x0016C },
+ { 0x00055 , 0x00308 , 0x000DC },
+ { 0x00055 , 0x00309 , 0x01EE6 },
+ { 0x00055 , 0x0030A , 0x0016E },
+ { 0x00055 , 0x0030B , 0x00170 },
+ { 0x00055 , 0x0030C , 0x001D3 },
+ { 0x00055 , 0x0030F , 0x00214 },
+ { 0x00055 , 0x00311 , 0x00216 },
+ { 0x00055 , 0x0031B , 0x001AF },
+ { 0x00055 , 0x00323 , 0x01EE4 },
+ { 0x00055 , 0x00324 , 0x01E72 },
+ { 0x00055 , 0x00328 , 0x00172 },
+ { 0x00055 , 0x0032D , 0x01E76 },
+ { 0x00055 , 0x00330 , 0x01E74 },
+ { 0x00056 , 0x00303 , 0x01E7C },
+ { 0x00056 , 0x00323 , 0x01E7E },
+ { 0x00057 , 0x00300 , 0x01E80 },
+ { 0x00057 , 0x00301 , 0x01E82 },
+ { 0x00057 , 0x00302 , 0x00174 },
+ { 0x00057 , 0x00307 , 0x01E86 },
+ { 0x00057 , 0x00308 , 0x01E84 },
+ { 0x00057 , 0x00323 , 0x01E88 },
+ { 0x00058 , 0x00307 , 0x01E8A },
+ { 0x00058 , 0x00308 , 0x01E8C },
+ { 0x00059 , 0x00300 , 0x01EF2 },
+ { 0x00059 , 0x00301 , 0x000DD },
+ { 0x00059 , 0x00302 , 0x00176 },
+ { 0x00059 , 0x00303 , 0x01EF8 },
+ { 0x00059 , 0x00304 , 0x00232 },
+ { 0x00059 , 0x00307 , 0x01E8E },
+ { 0x00059 , 0x00308 , 0x00178 },
+ { 0x00059 , 0x00309 , 0x01EF6 },
+ { 0x00059 , 0x00323 , 0x01EF4 },
+ { 0x0005A , 0x00301 , 0x00179 },
+ { 0x0005A , 0x00302 , 0x01E90 },
+ { 0x0005A , 0x00307 , 0x0017B },
+ { 0x0005A , 0x0030C , 0x0017D },
+ { 0x0005A , 0x00323 , 0x01E92 },
+ { 0x0005A , 0x00331 , 0x01E94 },
+ { 0x00061 , 0x00300 , 0x000E0 },
+ { 0x00061 , 0x00301 , 0x000E1 },
+ { 0x00061 , 0x00302 , 0x000E2 },
+ { 0x00061 , 0x00303 , 0x000E3 },
+ { 0x00061 , 0x00304 , 0x00101 },
+ { 0x00061 , 0x00306 , 0x00103 },
+ { 0x00061 , 0x00307 , 0x00227 },
+ { 0x00061 , 0x00308 , 0x000E4 },
+ { 0x00061 , 0x00309 , 0x01EA3 },
+ { 0x00061 , 0x0030A , 0x000E5 },
+ { 0x00061 , 0x0030C , 0x001CE },
+ { 0x00061 , 0x0030F , 0x00201 },
+ { 0x00061 , 0x00311 , 0x00203 },
+ { 0x00061 , 0x00323 , 0x01EA1 },
+ { 0x00061 , 0x00325 , 0x01E01 },
+ { 0x00061 , 0x00328 , 0x00105 },
+ { 0x00062 , 0x00307 , 0x01E03 },
+ { 0x00062 , 0x00323 , 0x01E05 },
+ { 0x00062 , 0x00331 , 0x01E07 },
+ { 0x00063 , 0x00301 , 0x00107 },
+ { 0x00063 , 0x00302 , 0x00109 },
+ { 0x00063 , 0x00307 , 0x0010B },
+ { 0x00063 , 0x0030C , 0x0010D },
+ { 0x00063 , 0x00327 , 0x000E7 },
+ { 0x00064 , 0x00307 , 0x01E0B },
+ { 0x00064 , 0x0030C , 0x0010F },
+ { 0x00064 , 0x00323 , 0x01E0D },
+ { 0x00064 , 0x00327 , 0x01E11 },
+ { 0x00064 , 0x0032D , 0x01E13 },
+ { 0x00064 , 0x00331 , 0x01E0F },
+ { 0x00065 , 0x00300 , 0x000E8 },
+ { 0x00065 , 0x00301 , 0x000E9 },
+ { 0x00065 , 0x00302 , 0x000EA },
+ { 0x00065 , 0x00303 , 0x01EBD },
+ { 0x00065 , 0x00304 , 0x00113 },
+ { 0x00065 , 0x00306 , 0x00115 },
+ { 0x00065 , 0x00307 , 0x00117 },
+ { 0x00065 , 0x00308 , 0x000EB },
+ { 0x00065 , 0x00309 , 0x01EBB },
+ { 0x00065 , 0x0030C , 0x0011B },
+ { 0x00065 , 0x0030F , 0x00205 },
+ { 0x00065 , 0x00311 , 0x00207 },
+ { 0x00065 , 0x00323 , 0x01EB9 },
+ { 0x00065 , 0x00327 , 0x00229 },
+ { 0x00065 , 0x00328 , 0x00119 },
+ { 0x00065 , 0x0032D , 0x01E19 },
+ { 0x00065 , 0x00330 , 0x01E1B },
+ { 0x00066 , 0x00307 , 0x01E1F },
+ { 0x00067 , 0x00301 , 0x001F5 },
+ { 0x00067 , 0x00302 , 0x0011D },
+ { 0x00067 , 0x00304 , 0x01E21 },
+ { 0x00067 , 0x00306 , 0x0011F },
+ { 0x00067 , 0x00307 , 0x00121 },
+ { 0x00067 , 0x0030C , 0x001E7 },
+ { 0x00067 , 0x00327 , 0x00123 },
+ { 0x00068 , 0x00302 , 0x00125 },
+ { 0x00068 , 0x00307 , 0x01E23 },
+ { 0x00068 , 0x00308 , 0x01E27 },
+ { 0x00068 , 0x0030C , 0x0021F },
+ { 0x00068 , 0x00323 , 0x01E25 },
+ { 0x00068 , 0x00327 , 0x01E29 },
+ { 0x00068 , 0x0032E , 0x01E2B },
+ { 0x00068 , 0x00331 , 0x01E96 },
+ { 0x00069 , 0x00300 , 0x000EC },
+ { 0x00069 , 0x00301 , 0x000ED },
+ { 0x00069 , 0x00302 , 0x000EE },
+ { 0x00069 , 0x00303 , 0x00129 },
+ { 0x00069 , 0x00304 , 0x0012B },
+ { 0x00069 , 0x00306 , 0x0012D },
+ { 0x00069 , 0x00308 , 0x000EF },
+ { 0x00069 , 0x00309 , 0x01EC9 },
+ { 0x00069 , 0x0030C , 0x001D0 },
+ { 0x00069 , 0x0030F , 0x00209 },
+ { 0x00069 , 0x00311 , 0x0020B },
+ { 0x00069 , 0x00323 , 0x01ECB },
+ { 0x00069 , 0x00328 , 0x0012F },
+ { 0x00069 , 0x00330 , 0x01E2D },
+ { 0x0006A , 0x00302 , 0x00135 },
+ { 0x0006A , 0x0030C , 0x001F0 },
+ { 0x0006B , 0x00301 , 0x01E31 },
+ { 0x0006B , 0x0030C , 0x001E9 },
+ { 0x0006B , 0x00323 , 0x01E33 },
+ { 0x0006B , 0x00327 , 0x00137 },
+ { 0x0006B , 0x00331 , 0x01E35 },
+ { 0x0006C , 0x00301 , 0x0013A },
+ { 0x0006C , 0x0030C , 0x0013E },
+ { 0x0006C , 0x00323 , 0x01E37 },
+ { 0x0006C , 0x00327 , 0x0013C },
+ { 0x0006C , 0x0032D , 0x01E3D },
+ { 0x0006C , 0x00331 , 0x01E3B },
+ { 0x0006D , 0x00301 , 0x01E3F },
+ { 0x0006D , 0x00307 , 0x01E41 },
+ { 0x0006D , 0x00323 , 0x01E43 },
+ { 0x0006E , 0x00300 , 0x001F9 },
+ { 0x0006E , 0x00301 , 0x00144 },
+ { 0x0006E , 0x00303 , 0x000F1 },
+ { 0x0006E , 0x00307 , 0x01E45 },
+ { 0x0006E , 0x0030C , 0x00148 },
+ { 0x0006E , 0x00323 , 0x01E47 },
+ { 0x0006E , 0x00327 , 0x00146 },
+ { 0x0006E , 0x0032D , 0x01E4B },
+ { 0x0006E , 0x00331 , 0x01E49 },
+ { 0x0006F , 0x00300 , 0x000F2 },
+ { 0x0006F , 0x00301 , 0x000F3 },
+ { 0x0006F , 0x00302 , 0x000F4 },
+ { 0x0006F , 0x00303 , 0x000F5 },
+ { 0x0006F , 0x00304 , 0x0014D },
+ { 0x0006F , 0x00306 , 0x0014F },
+ { 0x0006F , 0x00307 , 0x0022F },
+ { 0x0006F , 0x00308 , 0x000F6 },
+ { 0x0006F , 0x00309 , 0x01ECF },
+ { 0x0006F , 0x0030B , 0x00151 },
+ { 0x0006F , 0x0030C , 0x001D2 },
+ { 0x0006F , 0x0030F , 0x0020D },
+ { 0x0006F , 0x00311 , 0x0020F },
+ { 0x0006F , 0x0031B , 0x001A1 },
+ { 0x0006F , 0x00323 , 0x01ECD },
+ { 0x0006F , 0x00328 , 0x001EB },
+ { 0x00070 , 0x00301 , 0x01E55 },
+ { 0x00070 , 0x00307 , 0x01E57 },
+ { 0x00072 , 0x00301 , 0x00155 },
+ { 0x00072 , 0x00307 , 0x01E59 },
+ { 0x00072 , 0x0030C , 0x00159 },
+ { 0x00072 , 0x0030F , 0x00211 },
+ { 0x00072 , 0x00311 , 0x00213 },
+ { 0x00072 , 0x00323 , 0x01E5B },
+ { 0x00072 , 0x00327 , 0x00157 },
+ { 0x00072 , 0x00331 , 0x01E5F },
+ { 0x00073 , 0x00301 , 0x0015B },
+ { 0x00073 , 0x00302 , 0x0015D },
+ { 0x00073 , 0x00307 , 0x01E61 },
+ { 0x00073 , 0x0030C , 0x00161 },
+ { 0x00073 , 0x00323 , 0x01E63 },
+ { 0x00073 , 0x00326 , 0x00219 },
+ { 0x00073 , 0x00327 , 0x0015F },
+ { 0x00074 , 0x00307 , 0x01E6B },
+ { 0x00074 , 0x00308 , 0x01E97 },
+ { 0x00074 , 0x0030C , 0x00165 },
+ { 0x00074 , 0x00323 , 0x01E6D },
+ { 0x00074 , 0x00326 , 0x0021B },
+ { 0x00074 , 0x00327 , 0x00163 },
+ { 0x00074 , 0x0032D , 0x01E71 },
+ { 0x00074 , 0x00331 , 0x01E6F },
+ { 0x00075 , 0x00300 , 0x000F9 },
+ { 0x00075 , 0x00301 , 0x000FA },
+ { 0x00075 , 0x00302 , 0x000FB },
+ { 0x00075 , 0x00303 , 0x00169 },
+ { 0x00075 , 0x00304 , 0x0016B },
+ { 0x00075 , 0x00306 , 0x0016D },
+ { 0x00075 , 0x00308 , 0x000FC },
+ { 0x00075 , 0x00309 , 0x01EE7 },
+ { 0x00075 , 0x0030A , 0x0016F },
+ { 0x00075 , 0x0030B , 0x00171 },
+ { 0x00075 , 0x0030C , 0x001D4 },
+ { 0x00075 , 0x0030F , 0x00215 },
+ { 0x00075 , 0x00311 , 0x00217 },
+ { 0x00075 , 0x0031B , 0x001B0 },
+ { 0x00075 , 0x00323 , 0x01EE5 },
+ { 0x00075 , 0x00324 , 0x01E73 },
+ { 0x00075 , 0x00328 , 0x00173 },
+ { 0x00075 , 0x0032D , 0x01E77 },
+ { 0x00075 , 0x00330 , 0x01E75 },
+ { 0x00076 , 0x00303 , 0x01E7D },
+ { 0x00076 , 0x00323 , 0x01E7F },
+ { 0x00077 , 0x00300 , 0x01E81 },
+ { 0x00077 , 0x00301 , 0x01E83 },
+ { 0x00077 , 0x00302 , 0x00175 },
+ { 0x00077 , 0x00307 , 0x01E87 },
+ { 0x00077 , 0x00308 , 0x01E85 },
+ { 0x00077 , 0x0030A , 0x01E98 },
+ { 0x00077 , 0x00323 , 0x01E89 },
+ { 0x00078 , 0x00307 , 0x01E8B },
+ { 0x00078 , 0x00308 , 0x01E8D },
+ { 0x00079 , 0x00300 , 0x01EF3 },
+ { 0x00079 , 0x00301 , 0x000FD },
+ { 0x00079 , 0x00302 , 0x00177 },
+ { 0x00079 , 0x00303 , 0x01EF9 },
+ { 0x00079 , 0x00304 , 0x00233 },
+ { 0x00079 , 0x00307 , 0x01E8F },
+ { 0x00079 , 0x00308 , 0x000FF },
+ { 0x00079 , 0x00309 , 0x01EF7 },
+ { 0x00079 , 0x0030A , 0x01E99 },
+ { 0x00079 , 0x00323 , 0x01EF5 },
+ { 0x0007A , 0x00301 , 0x0017A },
+ { 0x0007A , 0x00302 , 0x01E91 },
+ { 0x0007A , 0x00307 , 0x0017C },
+ { 0x0007A , 0x0030C , 0x0017E },
+ { 0x0007A , 0x00323 , 0x01E93 },
+ { 0x0007A , 0x00331 , 0x01E95 },
+ { 0x000A8 , 0x00300 , 0x01FED },
+ { 0x000A8 , 0x00301 , 0x00385 },
+ { 0x000A8 , 0x00342 , 0x01FC1 },
+ { 0x000C2 , 0x00300 , 0x01EA6 },
+ { 0x000C2 , 0x00301 , 0x01EA4 },
+ { 0x000C2 , 0x00303 , 0x01EAA },
+ { 0x000C2 , 0x00309 , 0x01EA8 },
+ { 0x000C4 , 0x00304 , 0x001DE },
+ { 0x000C5 , 0x00301 , 0x001FA },
+ { 0x000C6 , 0x00301 , 0x001FC },
+ { 0x000C6 , 0x00304 , 0x001E2 },
+ { 0x000C7 , 0x00301 , 0x01E08 },
+ { 0x000CA , 0x00300 , 0x01EC0 },
+ { 0x000CA , 0x00301 , 0x01EBE },
+ { 0x000CA , 0x00303 , 0x01EC4 },
+ { 0x000CA , 0x00309 , 0x01EC2 },
+ { 0x000CF , 0x00301 , 0x01E2E },
+ { 0x000D4 , 0x00300 , 0x01ED2 },
+ { 0x000D4 , 0x00301 , 0x01ED0 },
+ { 0x000D4 , 0x00303 , 0x01ED6 },
+ { 0x000D4 , 0x00309 , 0x01ED4 },
+ { 0x000D5 , 0x00301 , 0x01E4C },
+ { 0x000D5 , 0x00304 , 0x0022C },
+ { 0x000D5 , 0x00308 , 0x01E4E },
+ { 0x000D6 , 0x00304 , 0x0022A },
+ { 0x000D8 , 0x00301 , 0x001FE },
+ { 0x000DC , 0x00300 , 0x001DB },
+ { 0x000DC , 0x00301 , 0x001D7 },
+ { 0x000DC , 0x00304 , 0x001D5 },
+ { 0x000DC , 0x0030C , 0x001D9 },
+ { 0x000E2 , 0x00300 , 0x01EA7 },
+ { 0x000E2 , 0x00301 , 0x01EA5 },
+ { 0x000E2 , 0x00303 , 0x01EAB },
+ { 0x000E2 , 0x00309 , 0x01EA9 },
+ { 0x000E4 , 0x00304 , 0x001DF },
+ { 0x000E5 , 0x00301 , 0x001FB },
+ { 0x000E6 , 0x00301 , 0x001FD },
+ { 0x000E6 , 0x00304 , 0x001E3 },
+ { 0x000E7 , 0x00301 , 0x01E09 },
+ { 0x000EA , 0x00300 , 0x01EC1 },
+ { 0x000EA , 0x00301 , 0x01EBF },
+ { 0x000EA , 0x00303 , 0x01EC5 },
+ { 0x000EA , 0x00309 , 0x01EC3 },
+ { 0x000EF , 0x00301 , 0x01E2F },
+ { 0x000F4 , 0x00300 , 0x01ED3 },
+ { 0x000F4 , 0x00301 , 0x01ED1 },
+ { 0x000F4 , 0x00303 , 0x01ED7 },
+ { 0x000F4 , 0x00309 , 0x01ED5 },
+ { 0x000F5 , 0x00301 , 0x01E4D },
+ { 0x000F5 , 0x00304 , 0x0022D },
+ { 0x000F5 , 0x00308 , 0x01E4F },
+ { 0x000F6 , 0x00304 , 0x0022B },
+ { 0x000F8 , 0x00301 , 0x001FF },
+ { 0x000FC , 0x00300 , 0x001DC },
+ { 0x000FC , 0x00301 , 0x001D8 },
+ { 0x000FC , 0x00304 , 0x001D6 },
+ { 0x000FC , 0x0030C , 0x001DA },
+ { 0x00102 , 0x00300 , 0x01EB0 },
+ { 0x00102 , 0x00301 , 0x01EAE },
+ { 0x00102 , 0x00303 , 0x01EB4 },
+ { 0x00102 , 0x00309 , 0x01EB2 },
+ { 0x00103 , 0x00300 , 0x01EB1 },
+ { 0x00103 , 0x00301 , 0x01EAF },
+ { 0x00103 , 0x00303 , 0x01EB5 },
+ { 0x00103 , 0x00309 , 0x01EB3 },
+ { 0x00112 , 0x00300 , 0x01E14 },
+ { 0x00112 , 0x00301 , 0x01E16 },
+ { 0x00113 , 0x00300 , 0x01E15 },
+ { 0x00113 , 0x00301 , 0x01E17 },
+ { 0x0014C , 0x00300 , 0x01E50 },
+ { 0x0014C , 0x00301 , 0x01E52 },
+ { 0x0014D , 0x00300 , 0x01E51 },
+ { 0x0014D , 0x00301 , 0x01E53 },
+ { 0x0015A , 0x00307 , 0x01E64 },
+ { 0x0015B , 0x00307 , 0x01E65 },
+ { 0x00160 , 0x00307 , 0x01E66 },
+ { 0x00161 , 0x00307 , 0x01E67 },
+ { 0x00168 , 0x00301 , 0x01E78 },
+ { 0x00169 , 0x00301 , 0x01E79 },
+ { 0x0016A , 0x00308 , 0x01E7A },
+ { 0x0016B , 0x00308 , 0x01E7B },
+ { 0x0017F , 0x00307 , 0x01E9B },
+ { 0x001A0 , 0x00300 , 0x01EDC },
+ { 0x001A0 , 0x00301 , 0x01EDA },
+ { 0x001A0 , 0x00303 , 0x01EE0 },
+ { 0x001A0 , 0x00309 , 0x01EDE },
+ { 0x001A0 , 0x00323 , 0x01EE2 },
+ { 0x001A1 , 0x00300 , 0x01EDD },
+ { 0x001A1 , 0x00301 , 0x01EDB },
+ { 0x001A1 , 0x00303 , 0x01EE1 },
+ { 0x001A1 , 0x00309 , 0x01EDF },
+ { 0x001A1 , 0x00323 , 0x01EE3 },
+ { 0x001AF , 0x00300 , 0x01EEA },
+ { 0x001AF , 0x00301 , 0x01EE8 },
+ { 0x001AF , 0x00303 , 0x01EEE },
+ { 0x001AF , 0x00309 , 0x01EEC },
+ { 0x001AF , 0x00323 , 0x01EF0 },
+ { 0x001B0 , 0x00300 , 0x01EEB },
+ { 0x001B0 , 0x00301 , 0x01EE9 },
+ { 0x001B0 , 0x00303 , 0x01EEF },
+ { 0x001B0 , 0x00309 , 0x01EED },
+ { 0x001B0 , 0x00323 , 0x01EF1 },
+ { 0x001B7 , 0x0030C , 0x001EE },
+ { 0x001EA , 0x00304 , 0x001EC },
+ { 0x001EB , 0x00304 , 0x001ED },
+ { 0x00226 , 0x00304 , 0x001E0 },
+ { 0x00227 , 0x00304 , 0x001E1 },
+ { 0x00228 , 0x00306 , 0x01E1C },
+ { 0x00229 , 0x00306 , 0x01E1D },
+ { 0x0022E , 0x00304 , 0x00230 },
+ { 0x0022F , 0x00304 , 0x00231 },
+ { 0x00292 , 0x0030C , 0x001EF },
+ { 0x00391 , 0x00300 , 0x01FBA },
+ { 0x00391 , 0x00301 , 0x00386 },
+ { 0x00391 , 0x00304 , 0x01FB9 },
+ { 0x00391 , 0x00306 , 0x01FB8 },
+ { 0x00391 , 0x00313 , 0x01F08 },
+ { 0x00391 , 0x00314 , 0x01F09 },
+ { 0x00391 , 0x00345 , 0x01FBC },
+ { 0x00395 , 0x00300 , 0x01FC8 },
+ { 0x00395 , 0x00301 , 0x00388 },
+ { 0x00395 , 0x00313 , 0x01F18 },
+ { 0x00395 , 0x00314 , 0x01F19 },
+ { 0x00397 , 0x00300 , 0x01FCA },
+ { 0x00397 , 0x00301 , 0x00389 },
+ { 0x00397 , 0x00313 , 0x01F28 },
+ { 0x00397 , 0x00314 , 0x01F29 },
+ { 0x00397 , 0x00345 , 0x01FCC },
+ { 0x00399 , 0x00300 , 0x01FDA },
+ { 0x00399 , 0x00301 , 0x0038A },
+ { 0x00399 , 0x00304 , 0x01FD9 },
+ { 0x00399 , 0x00306 , 0x01FD8 },
+ { 0x00399 , 0x00308 , 0x003AA },
+ { 0x00399 , 0x00313 , 0x01F38 },
+ { 0x00399 , 0x00314 , 0x01F39 },
+ { 0x0039F , 0x00300 , 0x01FF8 },
+ { 0x0039F , 0x00301 , 0x0038C },
+ { 0x0039F , 0x00313 , 0x01F48 },
+ { 0x0039F , 0x00314 , 0x01F49 },
+ { 0x003A1 , 0x00314 , 0x01FEC },
+ { 0x003A5 , 0x00300 , 0x01FEA },
+ { 0x003A5 , 0x00301 , 0x0038E },
+ { 0x003A5 , 0x00304 , 0x01FE9 },
+ { 0x003A5 , 0x00306 , 0x01FE8 },
+ { 0x003A5 , 0x00308 , 0x003AB },
+ { 0x003A5 , 0x00314 , 0x01F59 },
+ { 0x003A9 , 0x00300 , 0x01FFA },
+ { 0x003A9 , 0x00301 , 0x0038F },
+ { 0x003A9 , 0x00313 , 0x01F68 },
+ { 0x003A9 , 0x00314 , 0x01F69 },
+ { 0x003A9 , 0x00345 , 0x01FFC },
+ { 0x003AC , 0x00345 , 0x01FB4 },
+ { 0x003AE , 0x00345 , 0x01FC4 },
+ { 0x003B1 , 0x00300 , 0x01F70 },
+ { 0x003B1 , 0x00301 , 0x003AC },
+ { 0x003B1 , 0x00304 , 0x01FB1 },
+ { 0x003B1 , 0x00306 , 0x01FB0 },
+ { 0x003B1 , 0x00313 , 0x01F00 },
+ { 0x003B1 , 0x00314 , 0x01F01 },
+ { 0x003B1 , 0x00342 , 0x01FB6 },
+ { 0x003B1 , 0x00345 , 0x01FB3 },
+ { 0x003B5 , 0x00300 , 0x01F72 },
+ { 0x003B5 , 0x00301 , 0x003AD },
+ { 0x003B5 , 0x00313 , 0x01F10 },
+ { 0x003B5 , 0x00314 , 0x01F11 },
+ { 0x003B7 , 0x00300 , 0x01F74 },
+ { 0x003B7 , 0x00301 , 0x003AE },
+ { 0x003B7 , 0x00313 , 0x01F20 },
+ { 0x003B7 , 0x00314 , 0x01F21 },
+ { 0x003B7 , 0x00342 , 0x01FC6 },
+ { 0x003B7 , 0x00345 , 0x01FC3 },
+ { 0x003B9 , 0x00300 , 0x01F76 },
+ { 0x003B9 , 0x00301 , 0x003AF },
+ { 0x003B9 , 0x00304 , 0x01FD1 },
+ { 0x003B9 , 0x00306 , 0x01FD0 },
+ { 0x003B9 , 0x00308 , 0x003CA },
+ { 0x003B9 , 0x00313 , 0x01F30 },
+ { 0x003B9 , 0x00314 , 0x01F31 },
+ { 0x003B9 , 0x00342 , 0x01FD6 },
+ { 0x003BF , 0x00300 , 0x01F78 },
+ { 0x003BF , 0x00301 , 0x003CC },
+ { 0x003BF , 0x00313 , 0x01F40 },
+ { 0x003BF , 0x00314 , 0x01F41 },
+ { 0x003C1 , 0x00313 , 0x01FE4 },
+ { 0x003C1 , 0x00314 , 0x01FE5 },
+ { 0x003C5 , 0x00300 , 0x01F7A },
+ { 0x003C5 , 0x00301 , 0x003CD },
+ { 0x003C5 , 0x00304 , 0x01FE1 },
+ { 0x003C5 , 0x00306 , 0x01FE0 },
+ { 0x003C5 , 0x00308 , 0x003CB },
+ { 0x003C5 , 0x00313 , 0x01F50 },
+ { 0x003C5 , 0x00314 , 0x01F51 },
+ { 0x003C5 , 0x00342 , 0x01FE6 },
+ { 0x003C9 , 0x00300 , 0x01F7C },
+ { 0x003C9 , 0x00301 , 0x003CE },
+ { 0x003C9 , 0x00313 , 0x01F60 },
+ { 0x003C9 , 0x00314 , 0x01F61 },
+ { 0x003C9 , 0x00342 , 0x01FF6 },
+ { 0x003C9 , 0x00345 , 0x01FF3 },
+ { 0x003CA , 0x00300 , 0x01FD2 },
+ { 0x003CA , 0x00301 , 0x00390 },
+ { 0x003CA , 0x00342 , 0x01FD7 },
+ { 0x003CB , 0x00300 , 0x01FE2 },
+ { 0x003CB , 0x00301 , 0x003B0 },
+ { 0x003CB , 0x00342 , 0x01FE7 },
+ { 0x003CE , 0x00345 , 0x01FF4 },
+ { 0x003D2 , 0x00301 , 0x003D3 },
+ { 0x003D2 , 0x00308 , 0x003D4 },
+ { 0x00406 , 0x00308 , 0x00407 },
+ { 0x00410 , 0x00306 , 0x004D0 },
+ { 0x00410 , 0x00308 , 0x004D2 },
+ { 0x00413 , 0x00301 , 0x00403 },
+ { 0x00415 , 0x00300 , 0x00400 },
+ { 0x00415 , 0x00306 , 0x004D6 },
+ { 0x00415 , 0x00308 , 0x00401 },
+ { 0x00416 , 0x00306 , 0x004C1 },
+ { 0x00416 , 0x00308 , 0x004DC },
+ { 0x00417 , 0x00308 , 0x004DE },
+ { 0x00418 , 0x00300 , 0x0040D },
+ { 0x00418 , 0x00304 , 0x004E2 },
+ { 0x00418 , 0x00306 , 0x00419 },
+ { 0x00418 , 0x00308 , 0x004E4 },
+ { 0x0041A , 0x00301 , 0x0040C },
+ { 0x0041E , 0x00308 , 0x004E6 },
+ { 0x00423 , 0x00304 , 0x004EE },
+ { 0x00423 , 0x00306 , 0x0040E },
+ { 0x00423 , 0x00308 , 0x004F0 },
+ { 0x00423 , 0x0030B , 0x004F2 },
+ { 0x00427 , 0x00308 , 0x004F4 },
+ { 0x0042B , 0x00308 , 0x004F8 },
+ { 0x0042D , 0x00308 , 0x004EC },
+ { 0x00430 , 0x00306 , 0x004D1 },
+ { 0x00430 , 0x00308 , 0x004D3 },
+ { 0x00433 , 0x00301 , 0x00453 },
+ { 0x00435 , 0x00300 , 0x00450 },
+ { 0x00435 , 0x00306 , 0x004D7 },
+ { 0x00435 , 0x00308 , 0x00451 },
+ { 0x00436 , 0x00306 , 0x004C2 },
+ { 0x00436 , 0x00308 , 0x004DD },
+ { 0x00437 , 0x00308 , 0x004DF },
+ { 0x00438 , 0x00300 , 0x0045D },
+ { 0x00438 , 0x00304 , 0x004E3 },
+ { 0x00438 , 0x00306 , 0x00439 },
+ { 0x00438 , 0x00308 , 0x004E5 },
+ { 0x0043A , 0x00301 , 0x0045C },
+ { 0x0043E , 0x00308 , 0x004E7 },
+ { 0x00443 , 0x00304 , 0x004EF },
+ { 0x00443 , 0x00306 , 0x0045E },
+ { 0x00443 , 0x00308 , 0x004F1 },
+ { 0x00443 , 0x0030B , 0x004F3 },
+ { 0x00447 , 0x00308 , 0x004F5 },
+ { 0x0044B , 0x00308 , 0x004F9 },
+ { 0x0044D , 0x00308 , 0x004ED },
+ { 0x00456 , 0x00308 , 0x00457 },
+ { 0x00474 , 0x0030F , 0x00476 },
+ { 0x00475 , 0x0030F , 0x00477 },
+ { 0x004D8 , 0x00308 , 0x004DA },
+ { 0x004D9 , 0x00308 , 0x004DB },
+ { 0x004E8 , 0x00308 , 0x004EA },
+ { 0x004E9 , 0x00308 , 0x004EB },
+ { 0x00627 , 0x00653 , 0x00622 },
+ { 0x00627 , 0x00654 , 0x00623 },
+ { 0x00627 , 0x00655 , 0x00625 },
+ { 0x00648 , 0x00654 , 0x00624 },
+ { 0x0064A , 0x00654 , 0x00626 },
+ { 0x006C1 , 0x00654 , 0x006C2 },
+ { 0x006D2 , 0x00654 , 0x006D3 },
+ { 0x006D5 , 0x00654 , 0x006C0 },
+ { 0x00928 , 0x0093C , 0x00929 },
+ { 0x00930 , 0x0093C , 0x00931 },
+ { 0x00933 , 0x0093C , 0x00934 },
+ { 0x009C7 , 0x009BE , 0x009CB },
+ { 0x009C7 , 0x009D7 , 0x009CC },
+ { 0x00B47 , 0x00B3E , 0x00B4B },
+ { 0x00B47 , 0x00B56 , 0x00B48 },
+ { 0x00B47 , 0x00B57 , 0x00B4C },
+ { 0x00B92 , 0x00BD7 , 0x00B94 },
+ { 0x00BC6 , 0x00BBE , 0x00BCA },
+ { 0x00BC6 , 0x00BD7 , 0x00BCC },
+ { 0x00BC7 , 0x00BBE , 0x00BCB },
+ { 0x00C46 , 0x00C56 , 0x00C48 },
+ { 0x00CBF , 0x00CD5 , 0x00CC0 },
+ { 0x00CC6 , 0x00CC2 , 0x00CCA },
+ { 0x00CC6 , 0x00CD5 , 0x00CC7 },
+ { 0x00CC6 , 0x00CD6 , 0x00CC8 },
+ { 0x00CCA , 0x00CD5 , 0x00CCB },
+ { 0x00D46 , 0x00D3E , 0x00D4A },
+ { 0x00D46 , 0x00D57 , 0x00D4C },
+ { 0x00D47 , 0x00D3E , 0x00D4B },
+ { 0x00DD9 , 0x00DCA , 0x00DDA },
+ { 0x00DD9 , 0x00DCF , 0x00DDC },
+ { 0x00DD9 , 0x00DDF , 0x00DDE },
+ { 0x00DDC , 0x00DCA , 0x00DDD },
+ { 0x01025 , 0x0102E , 0x01026 },
+ { 0x01B05 , 0x01B35 , 0x01B06 },
+ { 0x01B07 , 0x01B35 , 0x01B08 },
+ { 0x01B09 , 0x01B35 , 0x01B0A },
+ { 0x01B0B , 0x01B35 , 0x01B0C },
+ { 0x01B0D , 0x01B35 , 0x01B0E },
+ { 0x01B11 , 0x01B35 , 0x01B12 },
+ { 0x01B3A , 0x01B35 , 0x01B3B },
+ { 0x01B3C , 0x01B35 , 0x01B3D },
+ { 0x01B3E , 0x01B35 , 0x01B40 },
+ { 0x01B3F , 0x01B35 , 0x01B41 },
+ { 0x01B42 , 0x01B35 , 0x01B43 },
+ { 0x01E36 , 0x00304 , 0x01E38 },
+ { 0x01E37 , 0x00304 , 0x01E39 },
+ { 0x01E5A , 0x00304 , 0x01E5C },
+ { 0x01E5B , 0x00304 , 0x01E5D },
+ { 0x01E62 , 0x00307 , 0x01E68 },
+ { 0x01E63 , 0x00307 , 0x01E69 },
+ { 0x01EA0 , 0x00302 , 0x01EAC },
+ { 0x01EA0 , 0x00306 , 0x01EB6 },
+ { 0x01EA1 , 0x00302 , 0x01EAD },
+ { 0x01EA1 , 0x00306 , 0x01EB7 },
+ { 0x01EB8 , 0x00302 , 0x01EC6 },
+ { 0x01EB9 , 0x00302 , 0x01EC7 },
+ { 0x01ECC , 0x00302 , 0x01ED8 },
+ { 0x01ECD , 0x00302 , 0x01ED9 },
+ { 0x01F00 , 0x00300 , 0x01F02 },
+ { 0x01F00 , 0x00301 , 0x01F04 },
+ { 0x01F00 , 0x00342 , 0x01F06 },
+ { 0x01F00 , 0x00345 , 0x01F80 },
+ { 0x01F01 , 0x00300 , 0x01F03 },
+ { 0x01F01 , 0x00301 , 0x01F05 },
+ { 0x01F01 , 0x00342 , 0x01F07 },
+ { 0x01F01 , 0x00345 , 0x01F81 },
+ { 0x01F02 , 0x00345 , 0x01F82 },
+ { 0x01F03 , 0x00345 , 0x01F83 },
+ { 0x01F04 , 0x00345 , 0x01F84 },
+ { 0x01F05 , 0x00345 , 0x01F85 },
+ { 0x01F06 , 0x00345 , 0x01F86 },
+ { 0x01F07 , 0x00345 , 0x01F87 },
+ { 0x01F08 , 0x00300 , 0x01F0A },
+ { 0x01F08 , 0x00301 , 0x01F0C },
+ { 0x01F08 , 0x00342 , 0x01F0E },
+ { 0x01F08 , 0x00345 , 0x01F88 },
+ { 0x01F09 , 0x00300 , 0x01F0B },
+ { 0x01F09 , 0x00301 , 0x01F0D },
+ { 0x01F09 , 0x00342 , 0x01F0F },
+ { 0x01F09 , 0x00345 , 0x01F89 },
+ { 0x01F0A , 0x00345 , 0x01F8A },
+ { 0x01F0B , 0x00345 , 0x01F8B },
+ { 0x01F0C , 0x00345 , 0x01F8C },
+ { 0x01F0D , 0x00345 , 0x01F8D },
+ { 0x01F0E , 0x00345 , 0x01F8E },
+ { 0x01F0F , 0x00345 , 0x01F8F },
+ { 0x01F10 , 0x00300 , 0x01F12 },
+ { 0x01F10 , 0x00301 , 0x01F14 },
+ { 0x01F11 , 0x00300 , 0x01F13 },
+ { 0x01F11 , 0x00301 , 0x01F15 },
+ { 0x01F18 , 0x00300 , 0x01F1A },
+ { 0x01F18 , 0x00301 , 0x01F1C },
+ { 0x01F19 , 0x00300 , 0x01F1B },
+ { 0x01F19 , 0x00301 , 0x01F1D },
+ { 0x01F20 , 0x00300 , 0x01F22 },
+ { 0x01F20 , 0x00301 , 0x01F24 },
+ { 0x01F20 , 0x00342 , 0x01F26 },
+ { 0x01F20 , 0x00345 , 0x01F90 },
+ { 0x01F21 , 0x00300 , 0x01F23 },
+ { 0x01F21 , 0x00301 , 0x01F25 },
+ { 0x01F21 , 0x00342 , 0x01F27 },
+ { 0x01F21 , 0x00345 , 0x01F91 },
+ { 0x01F22 , 0x00345 , 0x01F92 },
+ { 0x01F23 , 0x00345 , 0x01F93 },
+ { 0x01F24 , 0x00345 , 0x01F94 },
+ { 0x01F25 , 0x00345 , 0x01F95 },
+ { 0x01F26 , 0x00345 , 0x01F96 },
+ { 0x01F27 , 0x00345 , 0x01F97 },
+ { 0x01F28 , 0x00300 , 0x01F2A },
+ { 0x01F28 , 0x00301 , 0x01F2C },
+ { 0x01F28 , 0x00342 , 0x01F2E },
+ { 0x01F28 , 0x00345 , 0x01F98 },
+ { 0x01F29 , 0x00300 , 0x01F2B },
+ { 0x01F29 , 0x00301 , 0x01F2D },
+ { 0x01F29 , 0x00342 , 0x01F2F },
+ { 0x01F29 , 0x00345 , 0x01F99 },
+ { 0x01F2A , 0x00345 , 0x01F9A },
+ { 0x01F2B , 0x00345 , 0x01F9B },
+ { 0x01F2C , 0x00345 , 0x01F9C },
+ { 0x01F2D , 0x00345 , 0x01F9D },
+ { 0x01F2E , 0x00345 , 0x01F9E },
+ { 0x01F2F , 0x00345 , 0x01F9F },
+ { 0x01F30 , 0x00300 , 0x01F32 },
+ { 0x01F30 , 0x00301 , 0x01F34 },
+ { 0x01F30 , 0x00342 , 0x01F36 },
+ { 0x01F31 , 0x00300 , 0x01F33 },
+ { 0x01F31 , 0x00301 , 0x01F35 },
+ { 0x01F31 , 0x00342 , 0x01F37 },
+ { 0x01F38 , 0x00300 , 0x01F3A },
+ { 0x01F38 , 0x00301 , 0x01F3C },
+ { 0x01F38 , 0x00342 , 0x01F3E },
+ { 0x01F39 , 0x00300 , 0x01F3B },
+ { 0x01F39 , 0x00301 , 0x01F3D },
+ { 0x01F39 , 0x00342 , 0x01F3F },
+ { 0x01F40 , 0x00300 , 0x01F42 },
+ { 0x01F40 , 0x00301 , 0x01F44 },
+ { 0x01F41 , 0x00300 , 0x01F43 },
+ { 0x01F41 , 0x00301 , 0x01F45 },
+ { 0x01F48 , 0x00300 , 0x01F4A },
+ { 0x01F48 , 0x00301 , 0x01F4C },
+ { 0x01F49 , 0x00300 , 0x01F4B },
+ { 0x01F49 , 0x00301 , 0x01F4D },
+ { 0x01F50 , 0x00300 , 0x01F52 },
+ { 0x01F50 , 0x00301 , 0x01F54 },
+ { 0x01F50 , 0x00342 , 0x01F56 },
+ { 0x01F51 , 0x00300 , 0x01F53 },
+ { 0x01F51 , 0x00301 , 0x01F55 },
+ { 0x01F51 , 0x00342 , 0x01F57 },
+ { 0x01F59 , 0x00300 , 0x01F5B },
+ { 0x01F59 , 0x00301 , 0x01F5D },
+ { 0x01F59 , 0x00342 , 0x01F5F },
+ { 0x01F60 , 0x00300 , 0x01F62 },
+ { 0x01F60 , 0x00301 , 0x01F64 },
+ { 0x01F60 , 0x00342 , 0x01F66 },
+ { 0x01F60 , 0x00345 , 0x01FA0 },
+ { 0x01F61 , 0x00300 , 0x01F63 },
+ { 0x01F61 , 0x00301 , 0x01F65 },
+ { 0x01F61 , 0x00342 , 0x01F67 },
+ { 0x01F61 , 0x00345 , 0x01FA1 },
+ { 0x01F62 , 0x00345 , 0x01FA2 },
+ { 0x01F63 , 0x00345 , 0x01FA3 },
+ { 0x01F64 , 0x00345 , 0x01FA4 },
+ { 0x01F65 , 0x00345 , 0x01FA5 },
+ { 0x01F66 , 0x00345 , 0x01FA6 },
+ { 0x01F67 , 0x00345 , 0x01FA7 },
+ { 0x01F68 , 0x00300 , 0x01F6A },
+ { 0x01F68 , 0x00301 , 0x01F6C },
+ { 0x01F68 , 0x00342 , 0x01F6E },
+ { 0x01F68 , 0x00345 , 0x01FA8 },
+ { 0x01F69 , 0x00300 , 0x01F6B },
+ { 0x01F69 , 0x00301 , 0x01F6D },
+ { 0x01F69 , 0x00342 , 0x01F6F },
+ { 0x01F69 , 0x00345 , 0x01FA9 },
+ { 0x01F6A , 0x00345 , 0x01FAA },
+ { 0x01F6B , 0x00345 , 0x01FAB },
+ { 0x01F6C , 0x00345 , 0x01FAC },
+ { 0x01F6D , 0x00345 , 0x01FAD },
+ { 0x01F6E , 0x00345 , 0x01FAE },
+ { 0x01F6F , 0x00345 , 0x01FAF },
+ { 0x01F70 , 0x00345 , 0x01FB2 },
+ { 0x01F74 , 0x00345 , 0x01FC2 },
+ { 0x01F7C , 0x00345 , 0x01FF2 },
+ { 0x01FB6 , 0x00345 , 0x01FB7 },
+ { 0x01FBF , 0x00300 , 0x01FCD },
+ { 0x01FBF , 0x00301 , 0x01FCE },
+ { 0x01FBF , 0x00342 , 0x01FCF },
+ { 0x01FC6 , 0x00345 , 0x01FC7 },
+ { 0x01FF6 , 0x00345 , 0x01FF7 },
+ { 0x01FFE , 0x00300 , 0x01FDD },
+ { 0x01FFE , 0x00301 , 0x01FDE },
+ { 0x01FFE , 0x00342 , 0x01FDF },
+ { 0x02190 , 0x00338 , 0x0219A },
+ { 0x02192 , 0x00338 , 0x0219B },
+ { 0x02194 , 0x00338 , 0x021AE },
+ { 0x021D0 , 0x00338 , 0x021CD },
+ { 0x021D2 , 0x00338 , 0x021CF },
+ { 0x021D4 , 0x00338 , 0x021CE },
+ { 0x02203 , 0x00338 , 0x02204 },
+ { 0x02208 , 0x00338 , 0x02209 },
+ { 0x0220B , 0x00338 , 0x0220C },
+ { 0x02223 , 0x00338 , 0x02224 },
+ { 0x02225 , 0x00338 , 0x02226 },
+ { 0x0223C , 0x00338 , 0x02241 },
+ { 0x02243 , 0x00338 , 0x02244 },
+ { 0x02245 , 0x00338 , 0x02247 },
+ { 0x02248 , 0x00338 , 0x02249 },
+ { 0x0224D , 0x00338 , 0x0226D },
+ { 0x02261 , 0x00338 , 0x02262 },
+ { 0x02264 , 0x00338 , 0x02270 },
+ { 0x02265 , 0x00338 , 0x02271 },
+ { 0x02272 , 0x00338 , 0x02274 },
+ { 0x02273 , 0x00338 , 0x02275 },
+ { 0x02276 , 0x00338 , 0x02278 },
+ { 0x02277 , 0x00338 , 0x02279 },
+ { 0x0227A , 0x00338 , 0x02280 },
+ { 0x0227B , 0x00338 , 0x02281 },
+ { 0x0227C , 0x00338 , 0x022E0 },
+ { 0x0227D , 0x00338 , 0x022E1 },
+ { 0x02282 , 0x00338 , 0x02284 },
+ { 0x02283 , 0x00338 , 0x02285 },
+ { 0x02286 , 0x00338 , 0x02288 },
+ { 0x02287 , 0x00338 , 0x02289 },
+ { 0x02291 , 0x00338 , 0x022E2 },
+ { 0x02292 , 0x00338 , 0x022E3 },
+ { 0x022A2 , 0x00338 , 0x022AC },
+ { 0x022A8 , 0x00338 , 0x022AD },
+ { 0x022A9 , 0x00338 , 0x022AE },
+ { 0x022AB , 0x00338 , 0x022AF },
+ { 0x022B2 , 0x00338 , 0x022EA },
+ { 0x022B3 , 0x00338 , 0x022EB },
+ { 0x022B4 , 0x00338 , 0x022EC },
+ { 0x022B5 , 0x00338 , 0x022ED },
+ { 0x03046 , 0x03099 , 0x03094 },
+ { 0x0304B , 0x03099 , 0x0304C },
+ { 0x0304D , 0x03099 , 0x0304E },
+ { 0x0304F , 0x03099 , 0x03050 },
+ { 0x03051 , 0x03099 , 0x03052 },
+ { 0x03053 , 0x03099 , 0x03054 },
+ { 0x03055 , 0x03099 , 0x03056 },
+ { 0x03057 , 0x03099 , 0x03058 },
+ { 0x03059 , 0x03099 , 0x0305A },
+ { 0x0305B , 0x03099 , 0x0305C },
+ { 0x0305D , 0x03099 , 0x0305E },
+ { 0x0305F , 0x03099 , 0x03060 },
+ { 0x03061 , 0x03099 , 0x03062 },
+ { 0x03064 , 0x03099 , 0x03065 },
+ { 0x03066 , 0x03099 , 0x03067 },
+ { 0x03068 , 0x03099 , 0x03069 },
+ { 0x0306F , 0x03099 , 0x03070 },
+ { 0x0306F , 0x0309A , 0x03071 },
+ { 0x03072 , 0x03099 , 0x03073 },
+ { 0x03072 , 0x0309A , 0x03074 },
+ { 0x03075 , 0x03099 , 0x03076 },
+ { 0x03075 , 0x0309A , 0x03077 },
+ { 0x03078 , 0x03099 , 0x03079 },
+ { 0x03078 , 0x0309A , 0x0307A },
+ { 0x0307B , 0x03099 , 0x0307C },
+ { 0x0307B , 0x0309A , 0x0307D },
+ { 0x0309D , 0x03099 , 0x0309E },
+ { 0x030A6 , 0x03099 , 0x030F4 },
+ { 0x030AB , 0x03099 , 0x030AC },
+ { 0x030AD , 0x03099 , 0x030AE },
+ { 0x030AF , 0x03099 , 0x030B0 },
+ { 0x030B1 , 0x03099 , 0x030B2 },
+ { 0x030B3 , 0x03099 , 0x030B4 },
+ { 0x030B5 , 0x03099 , 0x030B6 },
+ { 0x030B7 , 0x03099 , 0x030B8 },
+ { 0x030B9 , 0x03099 , 0x030BA },
+ { 0x030BB , 0x03099 , 0x030BC },
+ { 0x030BD , 0x03099 , 0x030BE },
+ { 0x030BF , 0x03099 , 0x030C0 },
+ { 0x030C1 , 0x03099 , 0x030C2 },
+ { 0x030C4 , 0x03099 , 0x030C5 },
+ { 0x030C6 , 0x03099 , 0x030C7 },
+ { 0x030C8 , 0x03099 , 0x030C9 },
+ { 0x030CF , 0x03099 , 0x030D0 },
+ { 0x030CF , 0x0309A , 0x030D1 },
+ { 0x030D2 , 0x03099 , 0x030D3 },
+ { 0x030D2 , 0x0309A , 0x030D4 },
+ { 0x030D5 , 0x03099 , 0x030D6 },
+ { 0x030D5 , 0x0309A , 0x030D7 },
+ { 0x030D8 , 0x03099 , 0x030D9 },
+ { 0x030D8 , 0x0309A , 0x030DA },
+ { 0x030DB , 0x03099 , 0x030DC },
+ { 0x030DB , 0x0309A , 0x030DD },
+ { 0x030EF , 0x03099 , 0x030F7 },
+ { 0x030F0 , 0x03099 , 0x030F8 },
+ { 0x030F1 , 0x03099 , 0x030F9 },
+ { 0x030F2 , 0x03099 , 0x030FA },
+ { 0x030FD , 0x03099 , 0x030FE },
+ { 0x11099 , 0x110BA , 0x1109A },
+ { 0x1109B , 0x110BA , 0x1109C },
+ { 0x110A5 , 0x110BA , 0x110AB },
+};
+
+#define CANONICAL_CLASS_MIN 0x0300
+#define CANONICAL_CLASS_MAX 0x1D244
+
+#define IS_DECOMPOSABLE_BLOCK(uc) \
+ (((uc)>>8) <= 0x1D2 && u_decomposable_blocks[(uc)>>8])
+static const char u_decomposable_blocks[0x1D2+1] = {
+ 0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,1,1,1,1,1,1,1,0,0,
+ 1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,
+ 0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,
+};
+
+/* Get Canonical Combining Class(CCC). */
+#define CCC(uc) \
+ (((uc) > 0x1D244)?0:\
+ ccc_val[ccc_val_index[ccc_index[(uc)>>8]][((uc)>>4)&0x0F]][(uc)&0x0F])
+
+/* The table of the value of Canonical Cimbining Class */
+static const unsigned char ccc_val[][16] = {
+ /* idx=0: XXXX0 - XXXXF */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=1: 00300 - 0030F */
+ {230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230 },
+ /* idx=2: 00310 - 0031F */
+ {230, 230, 230, 230, 230, 232, 220, 220, 220, 220, 232, 216, 220, 220, 220, 220 },
+ /* idx=3: 00320 - 0032F */
+ {220, 202, 202, 220, 220, 220, 220, 202, 202, 220, 220, 220, 220, 220, 220, 220 },
+ /* idx=4: 00330 - 0033F */
+ {220, 220, 220, 220, 1, 1, 1, 1, 1, 220, 220, 220, 220, 230, 230, 230 },
+ /* idx=5: 00340 - 0034F */
+ {230, 230, 230, 230, 230, 240, 230, 220, 220, 220, 230, 230, 230, 220, 220, 0 },
+ /* idx=6: 00350 - 0035F */
+ {230, 230, 230, 220, 220, 220, 220, 230, 232, 220, 220, 230, 233, 234, 234, 233 },
+ /* idx=7: 00360 - 0036F */
+ {234, 234, 233, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230 },
+ /* idx=8: 00480 - 0048F */
+ {0, 0, 0, 230, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=9: 00590 - 0059F */
+ {0, 220, 230, 230, 230, 230, 220, 230, 230, 230, 222, 220, 230, 230, 230, 230 },
+ /* idx=10: 005A0 - 005AF */
+ {230, 230, 220, 220, 220, 220, 220, 220, 230, 230, 220, 230, 230, 222, 228, 230 },
+ /* idx=11: 005B0 - 005BF */
+ {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 0, 23 },
+ /* idx=12: 005C0 - 005CF */
+ {0, 24, 25, 0, 230, 220, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=13: 00610 - 0061F */
+ {230, 230, 230, 230, 230, 230, 230, 230, 30, 31, 32, 0, 0, 0, 0, 0 },
+ /* idx=14: 00640 - 0064F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 28, 29, 30, 31 },
+ /* idx=15: 00650 - 0065F */
+ {32, 33, 34, 230, 230, 220, 220, 230, 230, 230, 230, 230, 220, 230, 230, 220 },
+ /* idx=16: 00670 - 0067F */
+ {35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=17: 006D0 - 006DF */
+ {0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 230, 230, 230, 0, 0, 230 },
+ /* idx=18: 006E0 - 006EF */
+ {230, 230, 230, 220, 230, 0, 0, 230, 230, 0, 220, 230, 230, 220, 0, 0 },
+ /* idx=19: 00710 - 0071F */
+ {0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=20: 00730 - 0073F */
+ {230, 220, 230, 230, 220, 230, 230, 220, 220, 220, 230, 220, 220, 230, 220, 230 },
+ /* idx=21: 00740 - 0074F */
+ {230, 230, 220, 230, 220, 230, 220, 230, 220, 230, 230, 0, 0, 0, 0, 0 },
+ /* idx=22: 007E0 - 007EF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 230 },
+ /* idx=23: 007F0 - 007FF */
+ {230, 230, 220, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=24: 00810 - 0081F */
+ {0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 0, 230, 230, 230, 230, 230 },
+ /* idx=25: 00820 - 0082F */
+ {230, 230, 230, 230, 0, 230, 230, 230, 0, 230, 230, 230, 230, 230, 0, 0 },
+ /* idx=26: 00850 - 0085F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 220, 0, 0, 0, 0 },
+ /* idx=27: 00930 - 0093F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0 },
+ /* idx=28: 00940 - 0094F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 },
+ /* idx=29: 00950 - 0095F */
+ {0, 230, 220, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=30: 009B0 - 009BF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0 },
+ /* idx=31: 009C0 - 009CF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 },
+ /* idx=32: 00A30 - 00A3F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0 },
+ /* idx=33: 00A40 - 00A4F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 },
+ /* idx=34: 00AB0 - 00ABF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0 },
+ /* idx=35: 00AC0 - 00ACF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 },
+ /* idx=36: 00B30 - 00B3F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0 },
+ /* idx=37: 00B40 - 00B4F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 },
+ /* idx=38: 00BC0 - 00BCF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 },
+ /* idx=39: 00C40 - 00C4F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 },
+ /* idx=40: 00C50 - 00C5F */
+ {0, 0, 0, 0, 0, 84, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=41: 00CB0 - 00CBF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0 },
+ /* idx=42: 00CC0 - 00CCF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 },
+ /* idx=43: 00D40 - 00D4F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 },
+ /* idx=44: 00DC0 - 00DCF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0 },
+ /* idx=45: 00E30 - 00E3F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 103, 103, 9, 0, 0, 0, 0, 0 },
+ /* idx=46: 00E40 - 00E4F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 0, 0, 0, 0 },
+ /* idx=47: 00EB0 - 00EBF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 118, 118, 0, 0, 0, 0, 0, 0 },
+ /* idx=48: 00EC0 - 00ECF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 122, 122, 122, 122, 0, 0, 0, 0 },
+ /* idx=49: 00F10 - 00F1F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 0, 0, 0, 0, 0, 0 },
+ /* idx=50: 00F30 - 00F3F */
+ {0, 0, 0, 0, 0, 220, 0, 220, 0, 216, 0, 0, 0, 0, 0, 0 },
+ /* idx=51: 00F70 - 00F7F */
+ {0, 129, 130, 0, 132, 0, 0, 0, 0, 0, 130, 130, 130, 130, 0, 0 },
+ /* idx=52: 00F80 - 00F8F */
+ {130, 0, 230, 230, 9, 0, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=53: 00FC0 - 00FCF */
+ {0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=54: 01030 - 0103F */
+ {0, 0, 0, 0, 0, 0, 0, 7, 0, 9, 9, 0, 0, 0, 0, 0 },
+ /* idx=55: 01080 - 0108F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0 },
+ /* idx=56: 01350 - 0135F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230 },
+ /* idx=57: 01710 - 0171F */
+ {0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=58: 01730 - 0173F */
+ {0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=59: 017D0 - 017DF */
+ {0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 0, 0 },
+ /* idx=60: 018A0 - 018AF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0 },
+ /* idx=61: 01930 - 0193F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 222, 230, 220, 0, 0, 0, 0 },
+ /* idx=62: 01A10 - 01A1F */
+ {0, 0, 0, 0, 0, 0, 0, 230, 220, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=63: 01A60 - 01A6F */
+ {9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=64: 01A70 - 01A7F */
+ {0, 0, 0, 0, 0, 230, 230, 230, 230, 230, 230, 230, 230, 0, 0, 220 },
+ /* idx=65: 01B30 - 01B3F */
+ {0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=66: 01B40 - 01B4F */
+ {0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=67: 01B60 - 01B6F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 220, 230, 230, 230 },
+ /* idx=68: 01B70 - 01B7F */
+ {230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=69: 01BA0 - 01BAF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0 },
+ /* idx=70: 01BE0 - 01BEF */
+ {0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=71: 01BF0 - 01BFF */
+ {0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=72: 01C30 - 01C3F */
+ {0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=73: 01CD0 - 01CDF */
+ {230, 230, 230, 0, 1, 220, 220, 220, 220, 220, 230, 230, 220, 220, 220, 220 },
+ /* idx=74: 01CE0 - 01CEF */
+ {230, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 220, 0, 0 },
+ /* idx=75: 01DC0 - 01DCF */
+ {230, 230, 220, 230, 230, 230, 230, 230, 230, 230, 220, 230, 230, 234, 214, 220 },
+ /* idx=76: 01DD0 - 01DDF */
+ {202, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230 },
+ /* idx=77: 01DE0 - 01DEF */
+ {230, 230, 230, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=78: 01DF0 - 01DFF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 233, 220, 230, 220 },
+ /* idx=79: 020D0 - 020DF */
+ {230, 230, 1, 1, 230, 230, 230, 230, 1, 1, 1, 230, 230, 0, 0, 0 },
+ /* idx=80: 020E0 - 020EF */
+ {0, 230, 0, 0, 0, 1, 1, 230, 220, 230, 1, 1, 220, 220, 220, 220 },
+ /* idx=81: 020F0 - 020FF */
+ {230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=82: 02CE0 - 02CEF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230 },
+ /* idx=83: 02CF0 - 02CFF */
+ {230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=84: 02D70 - 02D7F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9 },
+ /* idx=85: 02DE0 - 02DEF */
+ {230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230 },
+ /* idx=86: 02DF0 - 02DFF */
+ {230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230 },
+ /* idx=87: 03020 - 0302F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 218, 228, 232, 222, 224, 224 },
+ /* idx=88: 03090 - 0309F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0 },
+ /* idx=89: 0A660 - 0A66F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230 },
+ /* idx=90: 0A670 - 0A67F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 0, 0 },
+ /* idx=91: 0A6F0 - 0A6FF */
+ {230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=92: 0A800 - 0A80F */
+ {0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=93: 0A8C0 - 0A8CF */
+ {0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=94: 0A8E0 - 0A8EF */
+ {230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230 },
+ /* idx=95: 0A8F0 - 0A8FF */
+ {230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=96: 0A920 - 0A92F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 220, 0, 0 },
+ /* idx=97: 0A950 - 0A95F */
+ {0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=98: 0A9B0 - 0A9BF */
+ {0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=99: 0A9C0 - 0A9CF */
+ {9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=100: 0AAB0 - 0AABF */
+ {230, 0, 230, 230, 220, 0, 0, 230, 230, 0, 0, 0, 0, 0, 230, 230 },
+ /* idx=101: 0AAC0 - 0AACF */
+ {0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=102: 0ABE0 - 0ABEF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 },
+ /* idx=103: 0FB10 - 0FB1F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0 },
+ /* idx=104: 0FE20 - 0FE2F */
+ {230, 230, 230, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=105: 101F0 - 101FF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0 },
+ /* idx=106: 10A00 - 10A0F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 230 },
+ /* idx=107: 10A30 - 10A3F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 230, 1, 220, 0, 0, 0, 0, 9 },
+ /* idx=108: 11040 - 1104F */
+ {0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=109: 110B0 - 110BF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 7, 0, 0, 0, 0, 0 },
+ /* idx=110: 1D160 - 1D16F */
+ {0, 0, 0, 0, 0, 216, 216, 1, 1, 1, 0, 0, 0, 226, 216, 216 },
+ /* idx=111: 1D170 - 1D17F */
+ {216, 216, 216, 0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 220, 220, 220 },
+ /* idx=112: 1D180 - 1D18F */
+ {220, 220, 220, 0, 0, 230, 230, 230, 230, 230, 220, 220, 0, 0, 0, 0 },
+ /* idx=113: 1D1A0 - 1D1AF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 0, 0 },
+ /* idx=114: 1D240 - 1D24F */
+ {0, 0, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+};
+
+/* The index table to ccc_val[*][16] */
+static const unsigned char ccc_val_index[][16] = {
+ /* idx=0: XXX00 - XXXFF */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=1: 00300 - 003FF */
+ { 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=2: 00400 - 004FF */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=3: 00500 - 005FF */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,10,11,12, 0, 0, 0 },
+ /* idx=4: 00600 - 006FF */
+ { 0,13, 0, 0,14,15, 0,16, 0, 0, 0, 0, 0,17,18, 0 },
+ /* idx=5: 00700 - 007FF */
+ { 0,19, 0,20,21, 0, 0, 0, 0, 0, 0, 0, 0, 0,22,23 },
+ /* idx=6: 00800 - 008FF */
+ { 0,24,25, 0, 0,26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=7: 00900 - 009FF */
+ { 0, 0, 0,27,28,29, 0, 0, 0, 0, 0,30,31, 0, 0, 0 },
+ /* idx=8: 00A00 - 00AFF */
+ { 0, 0, 0,32,33, 0, 0, 0, 0, 0, 0,34,35, 0, 0, 0 },
+ /* idx=9: 00B00 - 00BFF */
+ { 0, 0, 0,36,37, 0, 0, 0, 0, 0, 0, 0,38, 0, 0, 0 },
+ /* idx=10: 00C00 - 00CFF */
+ { 0, 0, 0, 0,39,40, 0, 0, 0, 0, 0,41,42, 0, 0, 0 },
+ /* idx=11: 00D00 - 00DFF */
+ { 0, 0, 0, 0,43, 0, 0, 0, 0, 0, 0, 0,44, 0, 0, 0 },
+ /* idx=12: 00E00 - 00EFF */
+ { 0, 0, 0,45,46, 0, 0, 0, 0, 0, 0,47,48, 0, 0, 0 },
+ /* idx=13: 00F00 - 00FFF */
+ { 0,49, 0,50, 0, 0, 0,51,52, 0, 0, 0,53, 0, 0, 0 },
+ /* idx=14: 01000 - 010FF */
+ { 0, 0, 0,54, 0, 0, 0, 0,55, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=15: 01300 - 013FF */
+ { 0, 0, 0, 0, 0,56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=16: 01700 - 017FF */
+ { 0,57, 0,58, 0, 0, 0, 0, 0, 0, 0, 0, 0,59, 0, 0 },
+ /* idx=17: 01800 - 018FF */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,60, 0, 0, 0, 0, 0 },
+ /* idx=18: 01900 - 019FF */
+ { 0, 0, 0,61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=19: 01A00 - 01AFF */
+ { 0,62, 0, 0, 0, 0,63,64, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=20: 01B00 - 01BFF */
+ { 0, 0, 0,65,66, 0,67,68, 0, 0,69, 0, 0, 0,70,71 },
+ /* idx=21: 01C00 - 01CFF */
+ { 0, 0, 0,72, 0, 0, 0, 0, 0, 0, 0, 0, 0,73,74, 0 },
+ /* idx=22: 01D00 - 01DFF */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,75,76,77,78 },
+ /* idx=23: 02000 - 020FF */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,79,80,81 },
+ /* idx=24: 02C00 - 02CFF */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,82,83 },
+ /* idx=25: 02D00 - 02DFF */
+ { 0, 0, 0, 0, 0, 0, 0,84, 0, 0, 0, 0, 0, 0,85,86 },
+ /* idx=26: 03000 - 030FF */
+ { 0, 0,87, 0, 0, 0, 0, 0, 0,88, 0, 0, 0, 0, 0, 0 },
+ /* idx=27: 0A600 - 0A6FF */
+ { 0, 0, 0, 0, 0, 0,89,90, 0, 0, 0, 0, 0, 0, 0,91 },
+ /* idx=28: 0A800 - 0A8FF */
+ {92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,93, 0,94,95 },
+ /* idx=29: 0A900 - 0A9FF */
+ { 0, 0,96, 0, 0,97, 0, 0, 0, 0, 0,98,99, 0, 0, 0 },
+ /* idx=30: 0AA00 - 0AAFF */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,100,101, 0, 0, 0 },
+ /* idx=31: 0AB00 - 0ABFF */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,102, 0 },
+ /* idx=32: 0FB00 - 0FBFF */
+ { 0,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=33: 0FE00 - 0FEFF */
+ { 0, 0,104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=34: 10100 - 101FF */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105 },
+ /* idx=35: 10A00 - 10AFF */
+ {106, 0, 0,107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=36: 11000 - 110FF */
+ { 0, 0, 0, 0,108, 0, 0, 0, 0, 0, 0,109, 0, 0, 0, 0 },
+ /* idx=37: 1D100 - 1D1FF */
+ { 0, 0, 0, 0, 0, 0,110,111,112, 0,113, 0, 0, 0, 0, 0 },
+ /* idx=38: 1D200 - 1D2FF */
+ { 0, 0, 0, 0,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+};
+
+/* The index table to ccc_val_index[*][16] */
+static const unsigned char ccc_index[] = {
+ 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, 0, 0,15, 0, 0, 0,16,
+ 17,18,19,20,21,22, 0, 0,23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,24,25, 0, 0,
+ 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,27, 0,
+ 28,29,30,31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,32, 0, 0,33, 0, 0,34, 0, 0, 0, 0, 0, 0,
+ 0, 0,35, 0, 0, 0, 0, 0,36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,37,38,};
+
+#endif /* ARCHIVE_STRING_COMPOSITION_H_INCLUDED */
diff --git a/libarchive/archive_string_sprintf.c b/libarchive/archive_string_sprintf.c
index 6d3d8edded88..7d7d9713ca9b 100644
--- a/libarchive/archive_string_sprintf.c
+++ b/libarchive/archive_string_sprintf.c
@@ -60,16 +60,19 @@ append_uint(struct archive_string *as, uintmax_t d, unsigned base)
static void
append_int(struct archive_string *as, intmax_t d, unsigned base)
{
+ uintmax_t ud;
+
if (d < 0) {
archive_strappend_char(as, '-');
- d = -d;
- }
- append_uint(as, d, base);
+ ud = (d == INTMAX_MIN) ? (uintmax_t)(INTMAX_MAX) + 1 : (uintmax_t)(-d);
+ } else
+ ud = d;
+ append_uint(as, ud, base);
}
void
-__archive_string_sprintf(struct archive_string *as, const char *fmt, ...)
+archive_string_sprintf(struct archive_string *as, const char *fmt, ...)
{
va_list ap;
@@ -83,15 +86,16 @@ __archive_string_sprintf(struct archive_string *as, const char *fmt, ...)
* necessary.
*/
void
-__archive_string_vsprintf(struct archive_string *as, const char *fmt,
+archive_string_vsprintf(struct archive_string *as, const char *fmt,
va_list ap)
{
char long_flag;
intmax_t s; /* Signed integer temp. */
uintmax_t u; /* Unsigned integer temp. */
const char *p, *p2;
+ const wchar_t *pw;
- if (__archive_string_ensure(as, 64) == NULL)
+ if (archive_string_ensure(as, 64) == NULL)
__archive_errx(1, "Out of memory");
if (fmt == NULL) {
@@ -112,40 +116,58 @@ __archive_string_vsprintf(struct archive_string *as, const char *fmt,
long_flag = '\0';
switch(*p) {
case 'j':
- long_flag = 'j';
- p++;
- break;
case 'l':
- long_flag = 'l';
+ case 'z':
+ long_flag = *p;
p++;
break;
}
switch (*p) {
case '%':
- __archive_strappend_char(as, '%');
+ archive_strappend_char(as, '%');
break;
case 'c':
s = va_arg(ap, int);
- __archive_strappend_char(as, s);
+ archive_strappend_char(as, s);
break;
case 'd':
switch(long_flag) {
case 'j': s = va_arg(ap, intmax_t); break;
case 'l': s = va_arg(ap, long); break;
+ case 'z': s = va_arg(ap, ssize_t); break;
default: s = va_arg(ap, int); break;
}
append_int(as, s, 10);
break;
case 's':
- p2 = va_arg(ap, char *);
- archive_strcat(as, p2);
+ switch(long_flag) {
+ case 'l':
+ pw = va_arg(ap, wchar_t *);
+ if (pw == NULL)
+ pw = L"(null)";
+ archive_string_append_from_wcs(as, pw, wcslen(pw));
+ break;
+ default:
+ p2 = va_arg(ap, char *);
+ if (p2 == NULL)
+ p2 = "(null)";
+ archive_strcat(as, p2);
+ break;
+ }
+ break;
+ case 'S':
+ pw = va_arg(ap, wchar_t *);
+ if (pw == NULL)
+ pw = L"(null)";
+ archive_string_append_from_wcs(as, pw, wcslen(pw));
break;
case 'o': case 'u': case 'x': case 'X':
/* Common handling for unsigned integer formats. */
switch(long_flag) {
case 'j': u = va_arg(ap, uintmax_t); break;
case 'l': u = va_arg(ap, unsigned long); break;
+ case 'z': u = va_arg(ap, size_t); break;
default: u = va_arg(ap, unsigned int); break;
}
/* Format it in the correct base. */
diff --git a/libarchive/archive_util.3 b/libarchive/archive_util.3
index 6570902c39af..cd05d03f11b5 100644
--- a/libarchive/archive_util.3
+++ b/libarchive/archive_util.3
@@ -35,8 +35,12 @@
.Nm archive_errno ,
.Nm archive_error_string ,
.Nm archive_file_count ,
+.Nm archive_filter_code ,
+.Nm archive_filter_count ,
+.Nm archive_filter_name ,
.Nm archive_format ,
.Nm archive_format_name ,
+.Nm archive_position ,
.Nm archive_set_error
.Nd libarchive utility functions
.Sh SYNOPSIS
@@ -56,9 +60,17 @@
.Ft int
.Fn archive_file_count "struct archive *"
.Ft int
+.Fn archive_filter_code "struct archive *" "int"
+.Ft int
+.Fn archive_filter_count "struct archive *" "int"
+.Ft const char *
+.Fn archive_filter_name "struct archive *" "int"
+.Ft int
.Fn archive_format "struct archive *"
.Ft const char *
.Fn archive_format_name "struct archive *"
+.Ft int64_t
+.Fn archive_position "struct archive *" "int"
.Ft void
.Fo archive_set_error
.Fa "struct archive *"
@@ -77,17 +89,21 @@ library.
Clears any error information left over from a previous call.
Not generally used in client code.
.It Fn archive_compression
-Returns a numeric code indicating the current compression.
-This value is set by
-.Fn archive_read_open .
+Synonym for
+.Fn archive_filter_code(a, 0) .
.It Fn archive_compression_name
-Returns a text description of the current compression suitable for display.
+Synonym for
+.Fn archive_filter_name(a, 0) .
.It Fn archive_copy_error
Copies error information from one archive to another.
.It Fn archive_errno
Returns a numeric error code (see
.Xr errno 2 )
indicating the reason for the most recent error return.
+Note that this can not be reliably used to detect whether an
+error has occurred.
+It should be used only after another libarchive function
+has returned an error status.
.It Fn archive_error_string
Returns a textual error message suitable for display.
The error message here is usually more specific than that
@@ -98,9 +114,45 @@ to
.It Fn archive_file_count
Returns a count of the number of files processed by this archive object.
The count is incremented by calls to
-.Xr archive_write_header
+.Xr archive_write_header 3
or
-.Xr archive_read_next_header .
+.Xr archive_read_next_header 3 .
+.It Fn archive_filter_code
+Returns a numeric code identifying the indicated filter.
+See
+.Fn archive_filter_count
+for details of the numbering.
+.It Fn archive_filter_count
+Returns the number of filters in the current pipeline.
+For read archive handles, these filters are added automatically
+by the automatic format detection.
+For write archive handles, these filters are added by calls to the various
+.Fn archive_write_add_filter_XXX
+functions.
+Filters in the resulting pipeline are numbered so that filter 0
+is the filter closest to the format handler.
+As a convenience, functions that expect a filter number will
+accept -1 as a synonym for the highest-numbered filter.
+.Pp
+For example, when reading a uuencoded gzipped tar archive, there
+are three filters:
+filter 0 is the gunzip filter,
+filter 1 is the uudecode filter,
+and filter 2 is the pseudo-filter that wraps the archive read functions.
+In this case, requesting
+.Fn archive_position(a, -1)
+would be a synonym for
+.Fn archive_position(a, 2)
+which would return the number of bytes currently read from the archive, while
+.Fn archive_position(a, 1)
+would return the number of bytes after uudecoding, and
+.Fn archive_position(a, 0)
+would return the number of bytes after decompression.
+.It Fn archive_filter_name
+Returns a textual name identifying the indicated filter.
+See
+.Fn archive_filter_count
+for details of the numbering.
.It Fn archive_format
Returns a numeric code indicating the format of the current
archive entry.
@@ -113,6 +165,16 @@ utilize GNU tar extensions and several entries that do not.
These entries will have different format codes.
.It Fn archive_format_name
A textual description of the format of the current entry.
+.It Fn archive_position
+Returns the number of bytes read from or written to the indicated filter.
+In particular,
+.Fn archive_position(a, 0)
+returns the number of bytes read or written by the format handler, while
+.Fn archive_position(a, -1)
+returns the number of bytes read or written to the archive.
+See
+.Fn archive_filter_count
+for details of the numbering here.
.It Fn archive_set_error
Sets the numeric error code and error description that will be returned
by
diff --git a/libarchive/archive_util.c b/libarchive/archive_util.c
index c8156846a127..e0852a3b58ba 100644
--- a/libarchive/archive_util.c
+++ b/libarchive/archive_util.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2009 Michihiro NAKAJIMA
+ * Copyright (c) 2009,2010 Michihiro NAKAJIMA
* Copyright (c) 2003-2007 Tim Kientzle
* All rights reserved.
*
@@ -30,47 +30,33 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_util.c 201098 2009-12-28 02:58:1
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
+#if defined(HAVE_WINCRYPT_H) && !defined(__CYGWIN__)
+#include <wincrypt.h>
+#endif
#include "archive.h"
#include "archive_private.h"
#include "archive_string.h"
-#if ARCHIVE_VERSION_NUMBER < 3000000
-/* These disappear in libarchive 3.0 */
-/* Deprecated. */
-int
-archive_api_feature(void)
-{
- return (ARCHIVE_API_FEATURE);
-}
-
-/* Deprecated. */
-int
-archive_api_version(void)
-{
- return (ARCHIVE_API_VERSION);
-}
-
-/* Deprecated synonym for archive_version_number() */
+/* Generic initialization of 'struct archive' objects. */
int
-archive_version_stamp(void)
-{
- return (archive_version_number());
-}
-
-/* Deprecated synonym for archive_version_string() */
-const char *
-archive_version(void)
+__archive_clean(struct archive *a)
{
- return (archive_version_string());
+ archive_string_conversion_free(a);
+ return (ARCHIVE_OK);
}
-#endif
int
archive_version_number(void)
@@ -97,7 +83,7 @@ archive_error_string(struct archive *a)
if (a->error != NULL && *a->error != '\0')
return (a->error);
else
- return ("(Empty error message)");
+ return (NULL);
}
int
@@ -122,13 +108,13 @@ archive_format_name(struct archive *a)
int
archive_compression(struct archive *a)
{
- return (a->compression_code);
+ return archive_filter_code(a, 0);
}
const char *
archive_compression_name(struct archive *a)
{
- return (a->compression_name);
+ return archive_filter_name(a, 0);
}
@@ -138,7 +124,7 @@ archive_compression_name(struct archive *a)
int64_t
archive_position_compressed(struct archive *a)
{
- return (a->raw_position);
+ return archive_filter_bytes(a, -1);
}
/*
@@ -147,7 +133,7 @@ archive_position_compressed(struct archive *a)
int64_t
archive_position_uncompressed(struct archive *a)
{
- return (a->file_position);
+ return archive_filter_bytes(a, 0);
}
void
@@ -169,6 +155,7 @@ archive_set_error(struct archive *a, int error_number, const char *fmt, ...)
return;
}
+ archive_string_empty(&(a->error_string));
va_start(ap, fmt);
archive_string_vsprintf(&(a->error_string), fmt, ap);
va_end(ap);
@@ -200,193 +187,279 @@ __archive_errx(int retvalue, const char *msg)
}
/*
- * Parse option strings
- * Detail of option format.
- * - The option can accept:
- * "opt-name", "!opt-name", "opt-name=value".
- *
- * - The option entries are separated by comma.
- * e.g "compression=9,opt=XXX,opt-b=ZZZ"
- *
- * - The name of option string consist of '-' and alphabet
- * but character '-' cannot be used for the first character.
- * (Regular expression is [a-z][-a-z]+)
- *
- * - For a specfic format/filter, using the format name with ':'.
- * e.g "zip:compression=9"
- * (This "compression=9" option entry is for "zip" format only)
- *
- * If another entries follow it, those are not for
- * the specfic format/filter.
- * e.g handle "zip:compression=9,opt=XXX,opt-b=ZZZ"
- * "zip" format/filter handler will get "compression=9"
- * all format/filter handler will get "opt=XXX"
- * all format/filter handler will get "opt-b=ZZZ"
- *
- * - Whitespace and tab are bypassed.
- *
+ * Create a temporary file
+ */
+#if defined(_WIN32) && !defined(__CYGWIN__)
+
+/*
+ * Do not use Windows tmpfile() function.
+ * It will make a temporary file under the root directory
+ * and it'll cause permission error if a user who is
+ * non-Administrator creates temporary files.
+ * Also Windows version of mktemp family including _mktemp_s
+ * are not secure.
*/
int
-__archive_parse_options(const char *p, const char *fn, int keysize, char *key,
- int valsize, char *val)
+__archive_mktemp(const char *tmpdir)
{
- const char *p_org;
- int apply;
- int kidx, vidx;
- int negative;
- enum {
- /* Requested for initialization. */
- INIT,
- /* Finding format/filter-name and option-name. */
- F_BOTH,
- /* Finding option-name only.
- * (already detected format/filter-name) */
- F_NAME,
- /* Getting option-value. */
- G_VALUE,
- } state;
-
- p_org = p;
- state = INIT;
- kidx = vidx = negative = 0;
- apply = 1;
- while (*p) {
- switch (state) {
- case INIT:
- kidx = vidx = 0;
- negative = 0;
- apply = 1;
- state = F_BOTH;
- break;
- case F_BOTH:
- case F_NAME:
- if ((*p >= 'a' && *p <= 'z') ||
- (*p >= '0' && *p <= '9') || *p == '-') {
- if (kidx == 0 && !(*p >= 'a' && *p <= 'z'))
- /* Illegal sequence. */
- return (-1);
- if (kidx >= keysize -1)
- /* Too many characters. */
- return (-1);
- key[kidx++] = *p++;
- } else if (*p == '!') {
- if (kidx != 0)
- /* Illegal sequence. */
- return (-1);
- negative = 1;
- ++p;
- } else if (*p == ',') {
- if (kidx == 0)
- /* Illegal sequence. */
- return (-1);
- if (!negative)
- val[vidx++] = '1';
- /* We have got boolean option data. */
- ++p;
- if (apply)
- goto complete;
- else
- /* This option does not apply to the
- * format which the fn variable
- * indicate. */
- state = INIT;
- } else if (*p == ':') {
- /* obuf data is format name */
- if (state == F_NAME)
- /* We already found it. */
- return (-1);
- if (kidx == 0)
- /* Illegal sequence. */
- return (-1);
- if (negative)
- /* We cannot accept "!format-name:". */
- return (-1);
- key[kidx] = '\0';
- if (strcmp(fn, key) != 0)
- /* This option does not apply to the
- * format which the fn variable
- * indicate. */
- apply = 0;
- kidx = 0;
- ++p;
- state = F_NAME;
- } else if (*p == '=') {
- if (kidx == 0)
- /* Illegal sequence. */
- return (-1);
- if (negative)
- /* We cannot accept "!opt-name=value". */
- return (-1);
- ++p;
- state = G_VALUE;
- } else if (*p == ' ') {
- /* Pass the space character */
- ++p;
- } else {
- /* Illegal character. */
- return (-1);
- }
- break;
- case G_VALUE:
- if (*p == ',') {
- if (vidx == 0)
- /* Illegal sequence. */
- return (-1);
- /* We have got option data. */
- ++p;
- if (apply)
- goto complete;
- else
- /* This option does not apply to the
- * format which the fn variable
- * indicate. */
- state = INIT;
- } else if (*p == ' ') {
- /* Pass the space character */
- ++p;
- } else {
- if (vidx >= valsize -1)
- /* Too many characters. */
- return (-1);
- val[vidx++] = *p++;
- }
- break;
- }
+ static const wchar_t num[] = {
+ L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7',
+ L'8', L'9', L'A', L'B', L'C', L'D', L'E', L'F',
+ L'G', L'H', L'I', L'J', L'K', L'L', L'M', L'N',
+ L'O', L'P', L'Q', L'R', L'S', L'T', L'U', L'V',
+ L'W', L'X', L'Y', L'Z', L'a', L'b', L'c', L'd',
+ L'e', L'f', L'g', L'h', L'i', L'j', L'k', L'l',
+ L'm', L'n', L'o', L'p', L'q', L'r', L's', L't',
+ L'u', L'v', L'w', L'x', L'y', L'z'
+ };
+ HCRYPTPROV hProv;
+ struct archive_wstring temp_name;
+ wchar_t *ws;
+ DWORD attr;
+ wchar_t *xp, *ep;
+ int fd;
+
+ hProv = (HCRYPTPROV)NULL;
+ fd = -1;
+ ws = NULL;
+ archive_string_init(&temp_name);
+
+ /* Get a temporary directory. */
+ if (tmpdir == NULL) {
+ size_t l;
+ wchar_t *tmp;
+
+ l = GetTempPathW(0, NULL);
+ if (l == 0) {
+ la_dosmaperr(GetLastError());
+ goto exit_tmpfile;
+ }
+ tmp = malloc(l*sizeof(wchar_t));
+ if (tmp == NULL) {
+ errno = ENOMEM;
+ goto exit_tmpfile;
+ }
+ GetTempPathW(l, tmp);
+ archive_wstrcpy(&temp_name, tmp);
+ free(tmp);
+ } else {
+ archive_wstring_append_from_mbs(&temp_name, tmpdir,
+ strlen(tmpdir));
+ if (temp_name.s[temp_name.length-1] != L'/')
+ archive_wstrappend_wchar(&temp_name, L'/');
+ }
+
+ /* Check if temp_name is a directory. */
+ attr = GetFileAttributesW(temp_name.s);
+ if (attr == (DWORD)-1) {
+ if (GetLastError() != ERROR_FILE_NOT_FOUND) {
+ la_dosmaperr(GetLastError());
+ goto exit_tmpfile;
+ }
+ ws = __la_win_permissive_name_w(temp_name.s);
+ if (ws == NULL) {
+ errno = EINVAL;
+ goto exit_tmpfile;
+ }
+ attr = GetFileAttributesW(ws);
+ if (attr == (DWORD)-1) {
+ la_dosmaperr(GetLastError());
+ goto exit_tmpfile;
+ }
+ }
+ if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) {
+ errno = ENOTDIR;
+ goto exit_tmpfile;
+ }
+
+ /*
+ * Create a temporary file.
+ */
+ archive_wstrcat(&temp_name, L"libarchive_");
+ xp = temp_name.s + archive_strlen(&temp_name);
+ archive_wstrcat(&temp_name, L"XXXXXXXXXX");
+ ep = temp_name.s + archive_strlen(&temp_name);
+
+ if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
+ CRYPT_VERIFYCONTEXT)) {
+ la_dosmaperr(GetLastError());
+ goto exit_tmpfile;
}
- switch (state) {
- case F_BOTH:
- case F_NAME:
- if (kidx != 0) {
- if (!negative)
- val[vidx++] = '1';
- /* We have got boolean option. */
- if (apply)
- /* This option apply to the format which the
- * fn variable indicate. */
- goto complete;
+ for (;;) {
+ wchar_t *p;
+ HANDLE h;
+
+ /* Generate a random file name through CryptGenRandom(). */
+ p = xp;
+ if (!CryptGenRandom(hProv, (ep - p)*sizeof(wchar_t), (BYTE*)p)) {
+ la_dosmaperr(GetLastError());
+ goto exit_tmpfile;
+ }
+ for (; p < ep; p++)
+ *p = num[((DWORD)*p) % (sizeof(num)/sizeof(num[0]))];
+
+ free(ws);
+ ws = __la_win_permissive_name_w(temp_name.s);
+ if (ws == NULL) {
+ errno = EINVAL;
+ goto exit_tmpfile;
}
- break;
- case G_VALUE:
- if (vidx == 0)
- /* Illegal sequence. */
- return (-1);
- /* We have got option value. */
- if (apply)
- /* This option apply to the format which the fn
- * variable indicate. */
- goto complete;
- break;
- case INIT:/* nothing */
- break;
+ /* Specifies FILE_FLAG_DELETE_ON_CLOSE flag is to
+ * delete this temporary file immediately when this
+ * file closed. */
+ h = CreateFileW(ws,
+ GENERIC_READ | GENERIC_WRITE | DELETE,
+ 0,/* Not share */
+ NULL,
+ CREATE_NEW,/* Create a new file only */
+ FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
+ NULL);
+ if (h == INVALID_HANDLE_VALUE) {
+ /* The same file already exists. retry with
+ * a new filename. */
+ if (GetLastError() == ERROR_FILE_EXISTS)
+ continue;
+ /* Otherwise, fail creation temporary file. */
+ la_dosmaperr(GetLastError());
+ goto exit_tmpfile;
+ }
+ fd = _open_osfhandle((intptr_t)h, _O_BINARY | _O_RDWR);
+ if (fd == -1) {
+ CloseHandle(h);
+ goto exit_tmpfile;
+ } else
+ break;/* success! */
}
+exit_tmpfile:
+ if (hProv != (HCRYPTPROV)NULL)
+ CryptReleaseContext(hProv, 0);
+ free(ws);
+ archive_wstring_free(&temp_name);
+ return (fd);
+}
- /* End of Option string. */
- return (0);
+#else
-complete:
- key[kidx] = '\0';
- val[vidx] = '\0';
- /* Return a size which we've consumed for detecting option */
- return ((int)(p - p_org));
+static int
+get_tempdir(struct archive_string *temppath)
+{
+ const char *tmp;
+
+ tmp = getenv("TMPDIR");
+ if (tmp == NULL)
+#ifdef _PATH_TMP
+ tmp = _PATH_TMP;
+#else
+ tmp = "/tmp";
+#endif
+ archive_strcpy(temppath, tmp);
+ if (temppath->s[temppath->length-1] != '/')
+ archive_strappend_char(temppath, '/');
+ return (ARCHIVE_OK);
}
+
+#if defined(HAVE_MKSTEMP)
+
+/*
+ * We can use mkstemp().
+ */
+
+int
+__archive_mktemp(const char *tmpdir)
+{
+ struct archive_string temp_name;
+ int fd = -1;
+
+ archive_string_init(&temp_name);
+ if (tmpdir == NULL) {
+ if (get_tempdir(&temp_name) != ARCHIVE_OK)
+ goto exit_tmpfile;
+ } else {
+ archive_strcpy(&temp_name, tmpdir);
+ if (temp_name.s[temp_name.length-1] != '/')
+ archive_strappend_char(&temp_name, '/');
+ }
+ archive_strcat(&temp_name, "libarchive_XXXXXX");
+ fd = mkstemp(temp_name.s);
+ if (fd < 0)
+ goto exit_tmpfile;
+ unlink(temp_name.s);
+exit_tmpfile:
+ archive_string_free(&temp_name);
+ return (fd);
+}
+
+#else
+
+/*
+ * We use a private routine.
+ */
+
+int
+__archive_mktemp(const char *tmpdir)
+{
+ static const char num[] = {
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
+ 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
+ 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
+ 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
+ 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
+ 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
+ 'u', 'v', 'w', 'x', 'y', 'z'
+ };
+ struct archive_string temp_name;
+ struct stat st;
+ int fd;
+ char *tp, *ep;
+ unsigned seed;
+
+ fd = -1;
+ archive_string_init(&temp_name);
+ if (tmpdir == NULL) {
+ if (get_tempdir(&temp_name) != ARCHIVE_OK)
+ goto exit_tmpfile;
+ } else
+ archive_strcpy(&temp_name, tmpdir);
+ if (temp_name.s[temp_name.length-1] == '/') {
+ temp_name.s[temp_name.length-1] = '\0';
+ temp_name.length --;
+ }
+ if (stat(temp_name.s, &st) < 0)
+ goto exit_tmpfile;
+ if (!S_ISDIR(st.st_mode)) {
+ errno = ENOTDIR;
+ goto exit_tmpfile;
+ }
+ archive_strcat(&temp_name, "/libarchive_");
+ tp = temp_name.s + archive_strlen(&temp_name);
+ archive_strcat(&temp_name, "XXXXXXXXXX");
+ ep = temp_name.s + archive_strlen(&temp_name);
+
+ fd = open("/dev/random", O_RDONLY);
+ if (fd < 0)
+ seed = time(NULL);
+ else {
+ if (read(fd, &seed, sizeof(seed)) < 0)
+ seed = time(NULL);
+ close(fd);
+ }
+ do {
+ char *p;
+
+ p = tp;
+ while (p < ep)
+ *p++ = num[((unsigned)rand_r(&seed)) % sizeof(num)];
+ fd = open(temp_name.s, O_CREAT | O_EXCL | O_RDWR, 0600);
+ } while (fd < 0 && errno == EEXIST);
+ if (fd < 0)
+ goto exit_tmpfile;
+ unlink(temp_name.s);
+exit_tmpfile:
+ archive_string_free(&temp_name);
+ return (fd);
+}
+
+#endif /* HAVE_MKSTEMP */
+#endif /* !_WIN32 || __CYGWIN__ */
diff --git a/libarchive/archive_virtual.c b/libarchive/archive_virtual.c
index 836886270f9f..83089f27f942 100644
--- a/libarchive/archive_virtual.c
+++ b/libarchive/archive_virtual.c
@@ -31,6 +31,30 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_virtual.c 201098 2009-12-28 02:5
#include "archive_private.h"
int
+archive_filter_code(struct archive *a, int n)
+{
+ return ((a->vtable->archive_filter_code)(a, n));
+}
+
+int
+archive_filter_count(struct archive *a)
+{
+ return ((a->vtable->archive_filter_count)(a));
+}
+
+const char *
+archive_filter_name(struct archive *a, int n)
+{
+ return ((a->vtable->archive_filter_name)(a, n));
+}
+
+int64_t
+archive_filter_bytes(struct archive *a, int n)
+{
+ return ((a->vtable->archive_filter_bytes)(a, n));
+}
+
+int
archive_write_close(struct archive *a)
{
return ((a->vtable->archive_close)(a));
@@ -45,6 +69,8 @@ archive_read_close(struct archive *a)
int
archive_write_free(struct archive *a)
{
+ if (a == NULL)
+ return (ARCHIVE_OK);
return ((a->vtable->archive_free)(a));
}
@@ -53,13 +79,15 @@ archive_write_free(struct archive *a)
int
archive_write_finish(struct archive *a)
{
- return ((a->vtable->archive_free)(a));
+ return archive_write_free(a);
}
#endif
int
archive_read_free(struct archive *a)
{
+ if (a == NULL)
+ return (ARCHIVE_OK);
return ((a->vtable->archive_free)(a));
}
@@ -68,7 +96,7 @@ archive_read_free(struct archive *a)
int
archive_read_finish(struct archive *a)
{
- return ((a->vtable->archive_free)(a));
+ return archive_read_free(a);
}
#endif
@@ -92,7 +120,32 @@ archive_write_data(struct archive *a, const void *buff, size_t s)
}
ssize_t
-archive_write_data_block(struct archive *a, const void *buff, size_t s, off_t o)
+archive_write_data_block(struct archive *a, const void *buff, size_t s, int64_t o)
{
+ if (a->vtable->archive_write_data_block == NULL) {
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "archive_write_data_block not supported");
+ a->state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+ }
return ((a->vtable->archive_write_data_block)(a, buff, s, o));
}
+
+int
+archive_read_next_header(struct archive *a, struct archive_entry **entry)
+{
+ return ((a->vtable->archive_read_next_header)(a, entry));
+}
+
+int
+archive_read_next_header2(struct archive *a, struct archive_entry *entry)
+{
+ return ((a->vtable->archive_read_next_header2)(a, entry));
+}
+
+int
+archive_read_data_block(struct archive *a,
+ const void **buff, size_t *s, int64_t *o)
+{
+ return ((a->vtable->archive_read_data_block)(a, buff, s, o));
+}
diff --git a/libarchive/archive_windows.c b/libarchive/archive_windows.c
index d9f29b72aff5..4d37a9c25c43 100644
--- a/libarchive/archive_windows.c
+++ b/libarchive/archive_windows.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2009 Michihiro NAKAJIMA
+ * Copyright (c) 2009-2011 Michihiro NAKAJIMA
* Copyright (c) 2003-2007 Kees Zeelenberg
* All rights reserved.
*
@@ -48,7 +48,6 @@
#include "archive_platform.h"
#include "archive_private.h"
-#include "archive_hash.h"
#include <ctype.h>
#include <errno.h>
#include <stddef.h>
@@ -56,31 +55,15 @@
#include <sys/utime.h>
#endif
#include <sys/stat.h>
+#include <locale.h>
#include <process.h>
#include <stdlib.h>
#include <wchar.h>
#include <windows.h>
+#include <share.h>
#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
-#if defined(_MSC_VER) && _MSC_VER < 1300
-/* VS 6 does not provide SetFilePointerEx, so define it here. */
-static BOOL SetFilePointerEx(HANDLE hFile,
- LARGE_INTEGER liDistanceToMove,
- PLARGE_INTEGER lpNewFilePointer,
- DWORD dwMoveMethod)
-{
- LARGE_INTEGER li;
- li.QuadPart = liDistanceToMove.QuadPart;
- li.LowPart = SetFilePointer(
- hFile, li.LowPart, &li.HighPart, dwMoveMethod);
- if(lpNewFilePointer) {
- lpNewFilePointer->QuadPart = li.QuadPart;
- }
- return li.LowPart != -1 || GetLastError() == NO_ERROR;
-}
-#endif
-
struct ustat {
int64_t st_atime;
uint32_t st_atime_nsec;
@@ -99,9 +82,6 @@ struct ustat {
dev_t st_rdev;
};
-/* Local replacement for undocumented Windows CRT function. */
-static void la_dosmaperr(unsigned long e);
-
/* Transform 64-bits ino into 32-bits by hashing.
* You do not forget that really unique number size is 64-bits.
*/
@@ -121,52 +101,63 @@ getino(struct ustat *ub)
* characters.
* see also http://msdn.microsoft.com/en-us/library/aa365247.aspx
*/
-static wchar_t *
-permissive_name(const char *name)
+wchar_t *
+__la_win_permissive_name(const char *name)
{
- wchar_t *wn, *wnp;
- wchar_t *ws, *wsp;
- DWORD l, len, slen;
- int unc;
+ wchar_t *wn;
+ wchar_t *ws;
+ size_t ll;
- len = (DWORD)strlen(name);
- wn = malloc((len + 1) * sizeof(wchar_t));
+ ll = strlen(name);
+ wn = malloc((ll + 1) * sizeof(wchar_t));
if (wn == NULL)
return (NULL);
- l = MultiByteToWideChar(CP_ACP, 0, name, (int)len, wn, (int)len);
- if (l == 0) {
+ ll = mbstowcs(wn, name, ll);
+ if (ll == (size_t)-1) {
free(wn);
return (NULL);
}
- wn[l] = L'\0';
+ wn[ll] = L'\0';
+ ws = __la_win_permissive_name_w(wn);
+ free(wn);
+ return (ws);
+}
- /* Get a full path names */
- l = GetFullPathNameW(wn, 0, NULL, NULL);
- if (l == 0) {
- free(wn);
+wchar_t *
+__la_win_permissive_name_w(const wchar_t *wname)
+{
+ wchar_t *wn, *wnp;
+ wchar_t *ws, *wsp;
+ DWORD l, len, slen;
+ int unc;
+
+ /* Get a full-pathname. */
+ l = GetFullPathNameW(wname, 0, NULL, NULL);
+ if (l == 0)
return (NULL);
- }
+ /* NOTE: GetFullPathNameW has a bug that if the length of the file
+ * name is just 1 then it returns incomplete buffer size. Thus, we
+ * have to add three to the size to allocate a sufficient buffer
+ * size for the full-pathname of the file name. */
+ l += 3;
wnp = malloc(l * sizeof(wchar_t));
- if (wnp == NULL) {
- free(wn);
+ if (wnp == NULL)
return (NULL);
- }
- len = GetFullPathNameW(wn, l, wnp, NULL);
- free(wn);
+ len = GetFullPathNameW(wname, l, wnp, NULL);
wn = wnp;
if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
wnp[2] == L'?' && wnp[3] == L'\\')
- /* We have already permissive names. */
+ /* We have already a permissive name. */
return (wn);
if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
wnp[2] == L'.' && wnp[3] == L'\\') {
- /* Device names */
+ /* This is a device name */
if (((wnp[4] >= L'a' && wnp[4] <= L'z') ||
(wnp[4] >= L'A' && wnp[4] <= L'Z')) &&
wnp[5] == L':' && wnp[6] == L'\\')
- wnp[2] = L'?';/* Not device names. */
+ wnp[2] = L'?';/* Not device name. */
return (wn);
}
@@ -214,6 +205,10 @@ permissive_name(const char *name)
return (ws);
}
+/*
+ * Create a file handle.
+ * This can exceed MAX_PATH limitation.
+ */
static HANDLE
la_CreateFile(const char *path, DWORD dwDesiredAccess, DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition,
@@ -229,7 +224,7 @@ la_CreateFile(const char *path, DWORD dwDesiredAccess, DWORD dwShareMode,
return (handle);
if (GetLastError() != ERROR_PATH_NOT_FOUND)
return (handle);
- wpath = permissive_name(path);
+ wpath = __la_win_permissive_name(path);
if (wpath == NULL)
return (handle);
handle = CreateFileW(wpath, dwDesiredAccess, dwShareMode,
@@ -239,376 +234,7 @@ la_CreateFile(const char *path, DWORD dwDesiredAccess, DWORD dwShareMode,
return (handle);
}
-static void *
-la_GetFunctionKernel32(const char *name)
-{
- static HINSTANCE lib;
- static int set;
- if (!set) {
- set = 1;
- lib = LoadLibrary("kernel32.dll");
- }
- if (lib == NULL) {
- fprintf(stderr, "Can't load kernel32.dll?!\n");
- exit(1);
- }
- return (void *)GetProcAddress(lib, name);
-}
-
-static int
-la_CreateHardLinkW(wchar_t *linkname, wchar_t *target)
-{
- static BOOLEAN (WINAPI *f)(LPWSTR, LPWSTR, LPSECURITY_ATTRIBUTES);
- static int set;
- if (!set) {
- set = 1;
- f = la_GetFunctionKernel32("CreateHardLinkW");
- }
- return f == NULL ? 0 : (*f)(linkname, target, NULL);
-}
-
-
-/* Make a link to src called dst. */
-static int
-__link(const char *src, const char *dst)
-{
- wchar_t *wsrc, *wdst;
- int res, retval;
- DWORD attr;
-
- if (src == NULL || dst == NULL) {
- set_errno (EINVAL);
- return -1;
- }
-
- wsrc = permissive_name(src);
- wdst = permissive_name(dst);
- if (wsrc == NULL || wdst == NULL) {
- free(wsrc);
- free(wdst);
- set_errno (EINVAL);
- return -1;
- }
-
- if ((attr = GetFileAttributesW(wsrc)) != (DWORD)-1) {
- res = la_CreateHardLinkW(wdst, wsrc);
- } else {
- /* wsrc does not exist; try src prepend it with the dirname of wdst */
- wchar_t *wnewsrc, *slash;
- int i, n, slen, wlen;
-
- if (strlen(src) >= 3 && isalpha((unsigned char)src[0]) &&
- src[1] == ':' && src[2] == '\\') {
- /* Original src name is already full-path */
- retval = -1;
- goto exit;
- }
- if (src[0] == '\\') {
- /* Original src name is almost full-path
- * (maybe src name is without drive) */
- retval = -1;
- goto exit;
- }
-
- wnewsrc = malloc ((wcslen(wsrc) + wcslen(wdst) + 1) * sizeof(wchar_t));
- if (wnewsrc == NULL) {
- errno = ENOMEM;
- retval = -1;
- goto exit;
- }
- /* Copying a dirname of wdst */
- wcscpy(wnewsrc, wdst);
- slash = wcsrchr(wnewsrc, L'\\');
- if (slash != NULL)
- *++slash = L'\0';
- else
- wcscat(wnewsrc, L"\\");
- /* Converting multi-byte src to wide-char src */
- wlen = (int)wcslen(wsrc);
- slen = (int)strlen(src);
- n = MultiByteToWideChar(CP_ACP, 0, src, slen, wsrc, wlen);
- if (n == 0) {
- free (wnewsrc);
- retval = -1;
- goto exit;
- }
- for (i = 0; i < n; i++)
- if (wsrc[i] == L'/')
- wsrc[i] = L'\\';
- wcsncat(wnewsrc, wsrc, n);
- /* Check again */
- attr = GetFileAttributesW(wnewsrc);
- if (attr == (DWORD)-1 || (attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
- if (attr == (DWORD)-1)
- la_dosmaperr(GetLastError());
- else
- errno = EPERM;
- free (wnewsrc);
- retval = -1;
- goto exit;
- }
- res = la_CreateHardLinkW(wdst, wnewsrc);
- free (wnewsrc);
- }
- if (res == 0) {
- la_dosmaperr(GetLastError());
- retval = -1;
- } else
- retval = 0;
-exit:
- free(wsrc);
- free(wdst);
- return (retval);
-}
-
-/* Make a hard link to src called dst. */
-int
-__la_link(const char *src, const char *dst)
-{
- return __link(src, dst);
-}
-
-int
-__la_ftruncate(int fd, off_t length)
-{
- LARGE_INTEGER distance;
- HANDLE handle;
-
- if (fd < 0) {
- errno = EBADF;
- return (-1);
- }
- handle = (HANDLE)_get_osfhandle(fd);
- if (GetFileType(handle) != FILE_TYPE_DISK) {
- errno = EBADF;
- return (-1);
- }
- distance.QuadPart = length;
- if (!SetFilePointerEx(handle, distance, NULL, FILE_BEGIN)) {
- la_dosmaperr(GetLastError());
- return (-1);
- }
- if (!SetEndOfFile(handle)) {
- la_dosmaperr(GetLastError());
- return (-1);
- }
- return (0);
-}
-
-#define WINTIME(sec, usec) ((Int32x32To64(sec, 10000000) + EPOC_TIME) + (usec * 10))
-static int
-__hutimes(HANDLE handle, const struct __timeval *times)
-{
- ULARGE_INTEGER wintm;
- FILETIME fatime, fmtime;
-
- wintm.QuadPart = WINTIME(times[0].tv_sec, times[0].tv_usec);
- fatime.dwLowDateTime = wintm.LowPart;
- fatime.dwHighDateTime = wintm.HighPart;
- wintm.QuadPart = WINTIME(times[1].tv_sec, times[1].tv_usec);
- fmtime.dwLowDateTime = wintm.LowPart;
- fmtime.dwHighDateTime = wintm.HighPart;
- if (SetFileTime(handle, NULL, &fatime, &fmtime) == 0) {
- errno = EINVAL;
- return (-1);
- }
- return (0);
-}
-
-int
-__la_futimes(int fd, const struct __timeval *times)
-{
-
- return (__hutimes((HANDLE)_get_osfhandle(fd), times));
-}
-
-int
-__la_utimes(const char *name, const struct __timeval *times)
-{
- int ret;
- HANDLE handle;
-
- handle = la_CreateFile(name, GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS, NULL);
- if (handle == INVALID_HANDLE_VALUE) {
- la_dosmaperr(GetLastError());
- return (-1);
- }
- ret = __hutimes(handle, times);
- CloseHandle(handle);
- return (ret);
-}
-
-int
-__la_chdir(const char *path)
-{
- wchar_t *ws;
- int r;
-
- r = SetCurrentDirectoryA(path);
- if (r == 0) {
- if (GetLastError() != ERROR_FILE_NOT_FOUND) {
- la_dosmaperr(GetLastError());
- return (-1);
- }
- } else
- return (0);
- ws = permissive_name(path);
- if (ws == NULL) {
- errno = EINVAL;
- return (-1);
- }
- r = SetCurrentDirectoryW(ws);
- free(ws);
- if (r == 0) {
- la_dosmaperr(GetLastError());
- return (-1);
- }
- return (0);
-}
-
-int
-__la_chmod(const char *path, mode_t mode)
-{
- wchar_t *ws;
- DWORD attr;
- BOOL r;
-
- ws = NULL;
- attr = GetFileAttributesA(path);
- if (attr == (DWORD)-1) {
- if (GetLastError() != ERROR_FILE_NOT_FOUND) {
- la_dosmaperr(GetLastError());
- return (-1);
- }
- ws = permissive_name(path);
- if (ws == NULL) {
- errno = EINVAL;
- return (-1);
- }
- attr = GetFileAttributesW(ws);
- if (attr == (DWORD)-1) {
- free(ws);
- la_dosmaperr(GetLastError());
- return (-1);
- }
- }
- if (mode & _S_IWRITE)
- attr &= ~FILE_ATTRIBUTE_READONLY;
- else
- attr |= FILE_ATTRIBUTE_READONLY;
- if (ws == NULL)
- r = SetFileAttributesA(path, attr);
- else {
- r = SetFileAttributesW(ws, attr);
- free(ws);
- }
- if (r == 0) {
- la_dosmaperr(GetLastError());
- return (-1);
- }
- return (0);
-}
-
-/*
- * This fcntl is limited implemention.
- */
-int
-__la_fcntl(int fd, int cmd, int val)
-{
- HANDLE handle;
-
- handle = (HANDLE)_get_osfhandle(fd);
- if (GetFileType(handle) == FILE_TYPE_PIPE) {
- if (cmd == F_SETFL && val == 0) {
- DWORD mode = PIPE_WAIT;
- if (SetNamedPipeHandleState(
- handle, &mode, NULL, NULL) != 0)
- return (0);
- }
- }
- errno = EINVAL;
- return (-1);
-}
-
-__int64
-__la_lseek(int fd, __int64 offset, int whence)
-{
- LARGE_INTEGER distance;
- LARGE_INTEGER newpointer;
- HANDLE handle;
-
- if (fd < 0) {
- errno = EBADF;
- return (-1);
- }
- handle = (HANDLE)_get_osfhandle(fd);
- if (GetFileType(handle) != FILE_TYPE_DISK) {
- errno = EBADF;
- return (-1);
- }
- distance.QuadPart = offset;
- if (!SetFilePointerEx(handle, distance, &newpointer, whence)) {
- DWORD lasterr;
-
- lasterr = GetLastError();
- if (lasterr == ERROR_BROKEN_PIPE)
- return (0);
- if (lasterr == ERROR_ACCESS_DENIED)
- errno = EBADF;
- else
- la_dosmaperr(lasterr);
- return (-1);
- }
- return (newpointer.QuadPart);
-}
-
-int
-__la_mkdir(const char *path, mode_t mode)
-{
- wchar_t *ws;
- int r;
-
- (void)mode;/* UNUSED */
- r = CreateDirectoryA(path, NULL);
- if (r == 0) {
- DWORD lasterr = GetLastError();
- if (lasterr != ERROR_FILENAME_EXCED_RANGE &&
- lasterr != ERROR_PATH_NOT_FOUND) {
- la_dosmaperr(GetLastError());
- return (-1);
- }
- } else
- return (0);
- ws = permissive_name(path);
- if (ws == NULL) {
- errno = EINVAL;
- return (-1);
- }
- r = CreateDirectoryW(ws, NULL);
- free(ws);
- if (r == 0) {
- la_dosmaperr(GetLastError());
- return (-1);
- }
- return (0);
-}
-
-/* Windows' mbstowcs is differrent error handling from other unix mbstowcs.
- * That one is using MultiByteToWideChar function with MB_PRECOMPOSED and
- * MB_ERR_INVALID_CHARS flags.
- * This implements for only to pass libarchive_test.
- */
-size_t
-__la_mbstowcs(wchar_t *wcstr, const char *mbstr, size_t nwchars)
-{
-
- return (MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS,
- mbstr, (int)strlen(mbstr), wcstr,
- (int)nwchars));
-}
-
+/* This can exceed MAX_PATH limitation. */
int
__la_open(const char *path, int flags, ...)
{
@@ -628,7 +254,7 @@ __la_open(const char *path, int flags, ...)
*/
attr = GetFileAttributesA(path);
if (attr == (DWORD)-1 && GetLastError() == ERROR_PATH_NOT_FOUND) {
- ws = permissive_name(path);
+ ws = __la_win_permissive_name(path);
if (ws == NULL) {
errno = EINVAL;
return (-1);
@@ -673,7 +299,7 @@ __la_open(const char *path, int flags, ...)
r = _open(path, flags, pmode);
#endif
if (r < 0 && errno == EACCES && (flags & O_CREAT) != 0) {
- /* simular other POSIX system action to pass a test */
+ /* Simulate other POSIX system action to pass our test suite. */
attr = GetFileAttributesA(path);
if (attr == (DWORD)-1)
la_dosmaperr(GetLastError());
@@ -685,7 +311,7 @@ __la_open(const char *path, int flags, ...)
}
if (r >= 0 || errno != ENOENT)
return (r);
- ws = permissive_name(path);
+ ws = __la_win_permissive_name(path);
if (ws == NULL) {
errno = EINVAL;
return (-1);
@@ -693,7 +319,7 @@ __la_open(const char *path, int flags, ...)
}
r = _wopen(ws, flags, pmode);
if (r < 0 && errno == EACCES && (flags & O_CREAT) != 0) {
- /* simular other POSIX system action to pass a test */
+ /* Simulate other POSIX system action to pass our test suite. */
attr = GetFileAttributesW(ws);
if (attr == (DWORD)-1)
la_dosmaperr(GetLastError());
@@ -721,23 +347,11 @@ __la_read(int fd, void *buf, size_t nbytes)
errno = EBADF;
return (-1);
}
+ /* Do not pass 0 to third parameter of ReadFile(), read bytes.
+ * This will not return to application side. */
+ if (nbytes == 0)
+ return (0);
handle = (HANDLE)_get_osfhandle(fd);
- if (GetFileType(handle) == FILE_TYPE_PIPE) {
- DWORD sta;
- if (GetNamedPipeHandleState(
- handle, &sta, NULL, NULL, NULL, NULL, 0) != 0 &&
- (sta & PIPE_NOWAIT) == 0) {
- DWORD avail = -1;
- int cnt = 3;
-
- while (PeekNamedPipe(
- handle, NULL, 0, NULL, &avail, NULL) != 0 &&
- avail == 0 && --cnt)
- Sleep(100);
- if (avail == 0)
- return (0);
- }
- }
r = ReadFile(handle, buf, (uint32_t)nbytes,
&bytes_read, NULL);
if (r == 0) {
@@ -757,26 +371,6 @@ __la_read(int fd, void *buf, size_t nbytes)
return ((ssize_t)bytes_read);
}
-/* Remove directory */
-int
-__la_rmdir(const char *path)
-{
- wchar_t *ws;
- int r;
-
- r = _rmdir(path);
- if (r >= 0 || errno != ENOENT)
- return (r);
- ws = permissive_name(path);
- if (ws == NULL) {
- errno = EINVAL;
- return (-1);
- }
- r = _wrmdir(ws);
- free(ws);
- return (r);
-}
-
/* Convert Windows FILETIME to UTC */
__inline static void
fileTimeToUTC(const FILETIME *filetime, time_t *time, long *ns)
@@ -796,9 +390,9 @@ fileTimeToUTC(const FILETIME *filetime, time_t *time, long *ns)
}
/* Stat by handle
- * Windows' stat() does not accept path which is added "\\?\" especially "?"
+ * Windows' stat() does not accept the path added "\\?\" especially "?"
* character.
- * It means we cannot access a long name path(which is longer than MAX_PATH).
+ * It means we cannot access the long name path longer than MAX_PATH.
* So I've implemented simular Windows' stat() to access the long name path.
* And I've added some feature.
* 1. set st_ino by nFileIndexHigh and nFileIndexLow of
@@ -887,7 +481,7 @@ __hstat(HANDLE handle, struct ustat *st)
st->st_nlink = 1;
st->st_dev = 0;
#else
- /* Getting FileIndex as i-node. We have to remove a sequence which
+ /* Getting FileIndex as i-node. We should remove a sequence which
* is high-16-bits of nFileIndexHigh. */
ino64.HighPart = info.nFileIndexHigh & 0x0000FFFFUL;
ino64.LowPart = info.nFileIndexLow;
@@ -919,6 +513,11 @@ copy_stat(struct stat *st, struct ustat *us)
st->st_rdev = us->st_rdev;
}
+/*
+ * TODO: Remove a use of __la_fstat and __la_stat.
+ * We should use GetFileInformationByHandle in place
+ * where We still use the *stat functions.
+ */
int
__la_fstat(int fd, struct stat *st)
{
@@ -940,6 +539,7 @@ __la_fstat(int fd, struct stat *st)
return (ret);
}
+/* This can exceed MAX_PATH limitation. */
int
__la_stat(const char *path, struct stat *st)
{
@@ -948,7 +548,7 @@ __la_stat(const char *path, struct stat *st)
int ret;
handle = la_CreateFile(path, 0, 0, NULL, OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS | FILE_ATTRIBUTE_READONLY,
+ FILE_FLAG_BACKUP_SEMANTICS,
NULL);
if (handle == INVALID_HANDLE_VALUE) {
la_dosmaperr(GetLastError());
@@ -977,27 +577,8 @@ __la_stat(const char *path, struct stat *st)
return (ret);
}
-int
-__la_unlink(const char *path)
-{
- wchar_t *ws;
- int r;
-
- r = _unlink(path);
- if (r >= 0 || errno != ENOENT)
- return (r);
- ws = permissive_name(path);
- if (ws == NULL) {
- errno = EINVAL;
- return (-1);
- }
- r = _wunlink(ws);
- free(ws);
- return (r);
-}
-
/*
- * This waitpid is limited implemention.
+ * This waitpid is limited implementation.
*/
pid_t
__la_waitpid(pid_t wpid, int *status, int option)
@@ -1006,6 +587,7 @@ __la_waitpid(pid_t wpid, int *status, int option)
DWORD cs, ret;
(void)option;/* UNUSED */
+ *status = 0;
child = OpenProcess(PROCESS_QUERY_INFORMATION | SYNCHRONIZE, FALSE, wpid);
if (child == NULL) {
la_dosmaperr(GetLastError());
@@ -1152,8 +734,8 @@ static const struct {
{ ERROR_NOT_ENOUGH_QUOTA, ENOMEM }
};
-static void
-la_dosmaperr(unsigned long e)
+void
+__la_dosmaperr(unsigned long e)
{
int i;
@@ -1177,60 +759,4 @@ la_dosmaperr(unsigned long e)
return;
}
-#if defined(ARCHIVE_HASH_MD5_WIN) ||\
- defined(ARCHIVE_HASH_SHA1_WIN) || defined(ARCHIVE_HASH_SHA256_WIN) ||\
- defined(ARCHIVE_HASH_SHA384_WIN) || defined(ARCHIVE_HASH_SHA512_WIN)
-/*
- * Message digest functions.
- */
-void
-__la_hash_Init(Digest_CTX *ctx, ALG_ID algId)
-{
-
- ctx->valid = 0;
- if (!CryptAcquireContext(&ctx->cryptProv, NULL, NULL,
- PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
- if (GetLastError() != (DWORD)NTE_BAD_KEYSET)
- return;
- if (!CryptAcquireContext(&ctx->cryptProv, NULL, NULL,
- PROV_RSA_FULL, CRYPT_NEWKEYSET))
- return;
- }
-
- if (!CryptCreateHash(ctx->cryptProv, algId, 0, 0, &ctx->hash)) {
- CryptReleaseContext(ctx->cryptProv, 0);
- return;
- }
-
- ctx->valid = 1;
-}
-
-void
-__la_hash_Update(Digest_CTX *ctx, const unsigned char *buf, size_t len)
-{
-
- if (!ctx->valid)
- return;
-
- CryptHashData(ctx->hash,
- (unsigned char *)(uintptr_t)buf,
- (DWORD)len, 0);
-}
-
-void
-__la_hash_Final(unsigned char *buf, size_t bufsize, Digest_CTX *ctx)
-{
- DWORD siglen = bufsize;
-
- if (!ctx->valid)
- return;
-
- CryptGetHashParam(ctx->hash, HP_HASHVAL, buf, &siglen, 0);
- CryptDestroyHash(ctx->hash);
- CryptReleaseContext(ctx->cryptProv, 0);
- ctx->valid = 0;
-}
-
-#endif /* defined(ARCHIVE_HASH_*_WIN) */
-
#endif /* _WIN32 && !__CYGWIN__ */
diff --git a/libarchive/archive_windows.h b/libarchive/archive_windows.h
index 86c9f4f6ba95..cfb3e97d2811 100644
--- a/libarchive/archive_windows.h
+++ b/libarchive/archive_windows.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2009 Michihiro NAKAJIMA
+ * Copyright (c) 2009-2011 Michihiro NAKAJIMA
* Copyright (c) 2003-2006 Tim Kientzle
* All rights reserved.
*
@@ -62,23 +62,15 @@
#include <sys/stat.h>
#include <process.h>
#include <direct.h>
+#if defined(__MINGW32__) && defined(HAVE_UNISTD_H)
+/* Prevent build error from a type mismatch of ftruncate().
+ * This unistd.h defines it as ftruncate(int, off_t). */
+#include <unistd.h>
+#endif
#define NOCRYPT
#include <windows.h>
//#define EFTYPE 7
-#if !defined(STDIN_FILENO)
-#define STDIN_FILENO 0
-#endif
-
-#if !defined(STDOUT_FILENO)
-#define STDOUT_FILENO 1
-#endif
-
-#if !defined(STDERR_FILENO)
-#define STDERR_FILENO 2
-#endif
-
-
#if defined(_MSC_VER)
/* TODO: Fix the code, don't suppress the warnings. */
#pragma warning(disable:4244) /* 'conversion' conversion from 'type1' to 'type2', possible loss of data */
@@ -97,27 +89,16 @@
#endif
/* Alias the Windows _function to the POSIX equivalent. */
-#define access _access
-#define chdir __la_chdir
-#define chmod __la_chmod
#define close _close
-#define fcntl __la_fcntl
+#define fcntl(fd, cmd, flg) /* No operation. */
#ifndef fileno
#define fileno _fileno
#endif
#define fstat __la_fstat
-#define ftruncate __la_ftruncate
-#define futimes __la_futimes
-#define getcwd _getcwd
-#define link __la_link
-#define lseek __la_lseek
+#define lseek _lseeki64
#define lstat __la_stat
-#define mbstowcs __la_mbstowcs
-#define mkdir(d,m) __la_mkdir(d, m)
-#define mktemp _mktemp
#define open __la_open
#define read __la_read
-#define rmdir __la_rmdir
#if !defined(__BORLANDC__)
#define setmode _setmode
#endif
@@ -129,8 +110,6 @@
#if !defined(__BORLANDC__)
#define umask _umask
#endif
-#define unlink __la_unlink
-#define utimes __la_utimes
#define waitpid __la_waitpid
#define write __la_write
@@ -263,78 +242,12 @@
#endif
-#ifdef _LARGEFILE_SOURCE
-# define __USE_LARGEFILE 1 /* declare fseeko and ftello */
-#endif
-
-#if defined _FILE_OFFSET_BITS && _FILE_OFFSET_BITS == 64
-# define __USE_FILE_OFFSET64 1 /* replace 32-bit functions by 64-bit ones */
-#endif
-
-#if __USE_LARGEFILE && __USE_FILE_OFFSET64
-/* replace stat and seek by their large-file equivalents */
-#undef stat
-#define stat _stati64
-
-#undef lseek
-#define lseek _lseeki64
-#define lseek64 _lseeki64
-#define tell _telli64
-#define tell64 _telli64
-
-#ifdef __MINGW32__
-# define fseek fseeko64
-# define fseeko fseeko64
-# define ftell ftello64
-# define ftello ftello64
-# define ftell64 ftello64
-#endif /* __MINGW32__ */
-#endif /* LARGE_FILES */
-
-#ifdef USE_WINSOCK_TIMEVAL
-/* Winsock timeval has long size tv_sec. */
-#define __timeval timeval
-#else
-struct _timeval64i32 {
- time_t tv_sec;
- long tv_usec;
-};
-#define __timeval _timeval64i32
-#endif
-
-/* End of Win32 definitions. */
-
-/* Tell libarchive code that we have simulations for these. */
-#ifndef HAVE_FTRUNCATE
-#define HAVE_FTRUNCATE 1
-#endif
-#ifndef HAVE_FUTIMES
-#define HAVE_FUTIMES 1
-#endif
-#ifndef HAVE_UTIMES
-#define HAVE_UTIMES 1
-#endif
-#ifndef HAVE_LINK
-#define HAVE_LINK 1
-#endif
-
/* Replacement POSIX function */
-extern int __la_chdir(const char *path);
-extern int __la_chmod(const char *path, mode_t mode);
-extern int __la_fcntl(int fd, int cmd, int val);
extern int __la_fstat(int fd, struct stat *st);
-extern int __la_ftruncate(int fd, off_t length);
-extern int __la_futimes(int fd, const struct __timeval *times);
-extern int __la_link(const char *src, const char *dst);
-extern __int64 __la_lseek(int fd, __int64 offset, int whence);
-extern size_t __la_mbstowcs(wchar_t *wcstr, const char *mbstr, size_t nwchars);
-extern int __la_mkdir(const char *path, mode_t mode);
+extern int __la_lstat(const char *path, struct stat *st);
extern int __la_open(const char *path, int flags, ...);
extern ssize_t __la_read(int fd, void *buf, size_t nbytes);
-extern int __la_rmdir(const char *path);
extern int __la_stat(const char *path, struct stat *st);
-extern int __la_unlink(const char *path);
-extern int __la_utimes(const char *name, const struct __timeval *times);
extern pid_t __la_waitpid(pid_t wpid, int *status, int option);
extern ssize_t __la_write(int fd, const void *buf, size_t nbytes);
@@ -344,4 +257,10 @@ extern ssize_t __la_write(int fd, const void *buf, size_t nbytes);
#define WIFEXITED(sts) ((sts & 0x100) == 0)
#define WEXITSTATUS(sts) (sts & 0x0FF)
+extern wchar_t *__la_win_permissive_name(const char *name);
+extern wchar_t *__la_win_permissive_name_w(const wchar_t *wname);
+extern void __la_dosmaperr(unsigned long e);
+#define la_dosmaperr(e) __la_dosmaperr(e)
+
+
#endif /* LIBARCHIVE_ARCHIVE_WINDOWS_H_INCLUDED */
diff --git a/libarchive/archive_write.3 b/libarchive/archive_write.3
index 6534128b0c98..f87386a8b87f 100644
--- a/libarchive/archive_write.3
+++ b/libarchive/archive_write.3
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2003-2007 Tim Kientzle
+.\" Copyright (c) 2003-2011 Tim Kientzle
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@@ -24,108 +24,14 @@
.\"
.\" $FreeBSD: head/lib/libarchive/archive_write.3 201110 2009-12-28 03:31:29Z kientzle $
.\"
-.Dd May 11, 2008
+.Dd March 23, 2011
.Dt ARCHIVE_WRITE 3
.Os
.Sh NAME
-.Nm archive_write_new ,
-.Nm archive_write_set_format_cpio ,
-.Nm archive_write_set_format_pax ,
-.Nm archive_write_set_format_pax_restricted ,
-.Nm archive_write_set_format_shar ,
-.Nm archive_write_set_format_shar_binary ,
-.Nm archive_write_set_format_ustar ,
-.Nm archive_write_get_bytes_per_block ,
-.Nm archive_write_set_bytes_per_block ,
-.Nm archive_write_set_bytes_in_last_block ,
-.Nm archive_write_set_compression_bzip2 ,
-.Nm archive_write_set_compression_compress ,
-.Nm archive_write_set_compression_gzip ,
-.Nm archive_write_set_compression_none ,
-.Nm archive_write_set_compression_program ,
-.Nm archive_write_set_compressor_options ,
-.Nm archive_write_set_format_options ,
-.Nm archive_write_set_options ,
-.Nm archive_write_open ,
-.Nm archive_write_open_fd ,
-.Nm archive_write_open_FILE ,
-.Nm archive_write_open_filename ,
-.Nm archive_write_open_memory ,
-.Nm archive_write_header ,
-.Nm archive_write_data ,
-.Nm archive_write_finish_entry ,
-.Nm archive_write_close ,
-.Nm archive_write_free
+.Nm archive_write
.Nd functions for creating archives
.Sh SYNOPSIS
.In archive.h
-.Ft struct archive *
-.Fn archive_write_new "void"
-.Ft int
-.Fn archive_write_get_bytes_per_block "struct archive *"
-.Ft int
-.Fn archive_write_set_bytes_per_block "struct archive *" "int bytes_per_block"
-.Ft int
-.Fn archive_write_set_bytes_in_last_block "struct archive *" "int"
-.Ft int
-.Fn archive_write_set_compression_bzip2 "struct archive *"
-.Ft int
-.Fn archive_write_set_compression_compress "struct archive *"
-.Ft int
-.Fn archive_write_set_compression_gzip "struct archive *"
-.Ft int
-.Fn archive_write_set_compression_none "struct archive *"
-.Ft int
-.Fn archive_write_set_compression_program "struct archive *" "const char * cmd"
-.Ft int
-.Fn archive_write_set_format_cpio "struct archive *"
-.Ft int
-.Fn archive_write_set_format_pax "struct archive *"
-.Ft int
-.Fn archive_write_set_format_pax_restricted "struct archive *"
-.Ft int
-.Fn archive_write_set_format_shar "struct archive *"
-.Ft int
-.Fn archive_write_set_format_shar_binary "struct archive *"
-.Ft int
-.Fn archive_write_set_format_ustar "struct archive *"
-.Ft int
-.Fn archive_write_set_format_options "struct archive *" "const char *"
-.Ft int
-.Fn archive_write_set_compressor_options "struct archive *" "const char *"
-.Ft int
-.Fn archive_write_set_options "struct archive *" "const char *"
-.Ft int
-.Fo archive_write_open
-.Fa "struct archive *"
-.Fa "void *client_data"
-.Fa "archive_open_callback *"
-.Fa "archive_write_callback *"
-.Fa "archive_close_callback *"
-.Fc
-.Ft int
-.Fn archive_write_open_fd "struct archive *" "int fd"
-.Ft int
-.Fn archive_write_open_FILE "struct archive *" "FILE *file"
-.Ft int
-.Fn archive_write_open_filename "struct archive *" "const char *filename"
-.Ft int
-.Fo archive_write_open_memory
-.Fa "struct archive *"
-.Fa "void *buffer"
-.Fa "size_t bufferSize"
-.Fa "size_t *outUsed"
-.Fc
-.Ft int
-.Fn archive_write_header "struct archive *" "struct archive_entry *"
-.Ft ssize_t
-.Fn archive_write_data "struct archive *" "const void *" "size_t"
-.Ft int
-.Fn archive_write_finish_entry "struct archive *"
-.Ft int
-.Fn archive_write_close "struct archive *"
-.Ft int
-.Fn archive_write_free "struct archive *"
.Sh DESCRIPTION
These functions provide a complete API for creating streaming
archive files.
@@ -133,316 +39,83 @@ The general process is to first create the
.Tn struct archive
object, set any desired options, initialize the archive, append entries, then
close the archive and release all resources.
-The following summary describes the functions in approximately
-the order they are ordinarily used:
-.Bl -tag -width indent
-.It Fn archive_write_new
-Allocates and initializes a
+.\"
+.Ss Create archive object
+See
+.Xr archive_write_new 3 .
+.Pp
+To write an archive, you must first obtain an initialized
.Tn struct archive
-object suitable for writing a tar archive.
-.It Fn archive_write_set_bytes_per_block
-Sets the block size used for writing the archive data.
-Every call to the write callback function, except possibly the last one, will
-use this value for the length.
-The third parameter is a boolean that specifies whether or not the final block
-written will be padded to the full block size.
-If it is zero, the last block will not be padded.
-If it is non-zero, padding will be added both before and after compression.
-The default is to use a block size of 10240 bytes and to pad the last block.
-Note that a block size of zero will suppress internal blocking
-and cause writes to be sent directly to the write callback as they occur.
-.It Fn archive_write_get_bytes_per_block
-Retrieve the block size to be used for writing.
-A value of -1 here indicates that the library should use default values.
-A value of zero indicates that internal blocking is suppressed.
-.It Fn archive_write_set_bytes_in_last_block
-Sets the block size used for writing the last block.
-If this value is zero, the last block will be padded to the same size
-as the other blocks.
-Otherwise, the final block will be padded to a multiple of this size.
-In particular, setting it to 1 will cause the final block to not be padded.
-For compressed output, any padding generated by this option
-is applied only after the compression.
-The uncompressed data is always unpadded.
-The default is to pad the last block to the full block size (note that
-.Fn archive_write_open_filename
-will set this based on the file type).
-Unlike the other
-.Dq set
-functions, this function can be called after the archive is opened.
-.It Fn archive_write_get_bytes_in_last_block
-Retrieve the currently-set value for last block size.
-A value of -1 here indicates that the library should use default values.
-.It Xo
-.Fn archive_write_set_format_cpio ,
-.Fn archive_write_set_format_pax ,
-.Fn archive_write_set_format_pax_restricted ,
-.Fn archive_write_set_format_shar ,
-.Fn archive_write_set_format_shar_binary ,
-.Fn archive_write_set_format_ustar
-.Xc
-Sets the format that will be used for the archive.
-The library can write
-POSIX octet-oriented cpio format archives,
-POSIX-standard
-.Dq pax interchange
-format archives,
-traditional
-.Dq shar
-archives,
-enhanced
-.Dq binary
-shar archives that store a variety of file attributes and handle binary files,
+object from
+.Fn archive_write_new .
+.\"
+.Ss Enable filters and formats, configure block size and padding
+See
+.Xr archive_write_filter 3 ,
+.Xr archive_write_format 3
and
-POSIX-standard
-.Dq ustar
-archives.
-The pax interchange format is a backwards-compatible tar format that
-adds key/value attributes to each entry and supports arbitrary
-filenames, linknames, uids, sizes, etc.
-.Dq Restricted pax interchange format
-is the library default; this is the same as pax format, but suppresses
-the pax extended header for most normal files.
-In most cases, this will result in ordinary ustar archives.
-.It Xo
-.Fn archive_write_set_compression_bzip2 ,
-.Fn archive_write_set_compression_compress ,
-.Fn archive_write_set_compression_gzip ,
-.Fn archive_write_set_compression_none
-.Xc
-The resulting archive will be compressed as specified.
-Note that the compressed output is always properly blocked.
-.It Fn archive_write_set_compression_program
-The archive will be fed into the specified compression program.
-The output of that program is blocked and written to the client
-write callbacks.
-.It Xo
-.Fn archive_write_set_compressor_options ,
-.Fn archive_write_set_format_options ,
-.Fn archive_write_set_options
-.Xc
-Specifies options that will be passed to the currently-enabled
-compressor and/or format writer.
-The argument is a comma-separated list of individual options.
-Individual options have one of the following forms:
-.Bl -tag -compact -width indent
-.It Ar option=value
-The option/value pair will be provided to every module.
-Modules that do not accept an option with this name will ignore it.
-.It Ar option
-The option will be provided to every module with a value of
-.Dq 1 .
-.It Ar !option
-The option will be provided to every module with a NULL value.
-.It Ar module:option=value , Ar module:option , Ar module:!option
-As above, but the corresponding option and value will be provided
-only to modules whose name matches
-.Ar module .
-.El
-The return value will be
-.Cm ARCHIVE_OK
-if any module accepts the option, or
-.Cm ARCHIVE_WARN
-if no module accepted the option, or
-.Cm ARCHIVE_FATAL
-if there was a fatal error while attempting to process the option.
+.Xr archive_write_blocksize 3 .
.Pp
-The currently supported options are:
-.Bl -tag -compact -width indent
-.It Compressor gzip
-.Bl -tag -compact -width indent
-.It Cm compression-level
-The value is interpreted as a decimal integer specifying the
-gzip compression level.
-.El
-.It Compressor xz
-.Bl -tag -compact -width indent
-.It Cm compression-level
-The value is interpreted as a decimal integer specifying the
-compression level.
-.El
-.It Format mtree
-.Bl -tag -compact -width indent
-.It Cm cksum , Cm device , Cm flags , Cm gid , Cm gname , Cm indent , Cm link , Cm md5 , Cm mode , Cm nlink , Cm rmd160 , Cm sha1 , Cm sha256 , Cm sha384 , Cm sha512 , Cm size , Cm time , Cm uid , Cm uname
-Enable a particular keyword in the mtree output.
-Prefix with an exclamation mark to disable the corresponding keyword.
-The default is equivalent to
-.Dq device, flags, gid, gname, link, mode, nlink, size, time, type, uid, uname .
-.It Cm all
-Enables all of the above keywords.
-.It Cm use-set
-Enables generation of
-.Cm /set
-lines that specify default values for the following files and/or directories.
-.It Cm indent
-XXX needs explanation XXX
-.El
-.El
-.It Fn archive_write_open
-Freeze the settings, open the archive, and prepare for writing entries.
-This is the most generic form of this function, which accepts
-pointers to three callback functions which will be invoked by
-the compression layer to write the constructed archive.
-.It Fn archive_write_open_fd
-A convenience form of
-.Fn archive_write_open
-that accepts a file descriptor.
-The
-.Fn archive_write_open_fd
-function is safe for use with tape drives or other
-block-oriented devices.
-.It Fn archive_write_open_FILE
-A convenience form of
+You can then modify this object for the desired operations with the
+various
+.Fn archive_write_set_XXX
+functions.
+In particular, you will need to invoke appropriate
+.Fn archive_write_add_XXX
+and
+.Fn archive_write_set_XXX
+functions to enable the corresponding compression and format
+support.
+.\"
+.Ss Set options
+See
+.Xr archive_read_set_options 3 .
+.\"
+.Ss Open archive
+See
+.Xr archive_write_open 3 .
+.Pp
+Once you have prepared the
+.Tn struct archive
+object, you call
.Fn archive_write_open
-that accepts a
+to actually open the archive and prepare it for writing.
+There are several variants of this function;
+the most basic expects you to provide pointers to several
+functions that can provide blocks of bytes from the archive.
+There are convenience forms that allow you to
+specify a filename, file descriptor,
.Ft "FILE *"
-pointer.
-Note that
-.Fn archive_write_open_FILE
-is not safe for writing to tape drives or other devices
-that require correct blocking.
-.It Fn archive_write_open_file
-A deprecated synonym for
-.Fn archive_write_open_filename .
-.It Fn archive_write_open_filename
-A convenience form of
-.Fn archive_write_open
-that accepts a filename.
-A NULL argument indicates that the output should be written to standard output;
-an argument of
-.Dq -
-will open a file with that name.
-If you have not invoked
-.Fn archive_write_set_bytes_in_last_block ,
-then
-.Fn archive_write_open_filename
-will adjust the last-block padding depending on the file:
-it will enable padding when writing to standard output or
-to a character or block device node, it will disable padding otherwise.
-You can override this by manually invoking
-.Fn archive_write_set_bytes_in_last_block
-before calling
-.Fn archive_write_open .
-The
-.Fn archive_write_open_filename
-function is safe for use with tape drives or other
-block-oriented devices.
-.It Fn archive_write_open_memory
-A convenience form of
-.Fn archive_write_open
-that accepts a pointer to a block of memory that will receive
-the archive.
-The final
-.Ft "size_t *"
-argument points to a variable that will be updated
-after each write to reflect how much of the buffer
-is currently in use.
-You should be careful to ensure that this variable
-remains allocated until after the archive is
-closed.
-.It Fn archive_write_header
-Build and write a header using the data in the provided
-.Tn struct archive_entry
-structure.
+object, or a block of memory from which to write the archive data.
+.\"
+.Ss Produce archive
See
-.Xr archive_entry 3
-for information on creating and populating
-.Tn struct archive_entry
-objects.
-.It Fn archive_write_data
-Write data corresponding to the header just written.
-Returns number of bytes written or -1 on error.
-.It Fn archive_write_finish_entry
-Close out the entry just written.
-In particular, this writes out the final padding required by some formats.
-Ordinarily, clients never need to call this, as it
-is called automatically by
-.Fn archive_write_next_header
+.Xr archive_write_header 3
and
-.Fn archive_write_close
-as needed.
-.It Fn archive_write_close
-Complete the archive and invoke the close callback.
-.It Fn archive_write_free
-Invokes
-.Fn archive_write_close
-if necessary, then releases all resources.
-If you need detailed information about
-.Fn archive_write_close
-failures, you should be careful to call it separately, as
-you cannot obtain error information after
-.Fn archive_write_free
-returns.
-.El
-More information about the
-.Va struct archive
-object and the overall design of the library can be found in the
-.Xr libarchive 3
-overview.
-.Sh IMPLEMENTATION
-Compression support is built-in to libarchive, which uses zlib and bzlib
-to handle gzip and bzip2 compression, respectively.
-.Sh CLIENT CALLBACKS
-To use this library, you will need to define and register
-callback functions that will be invoked to write data to the
-resulting archive.
-These functions are registered by calling
-.Fn archive_write_open :
-.Bl -item -offset indent
-.It
-.Ft typedef int
-.Fn archive_open_callback "struct archive *" "void *client_data"
-.El
+.Xr archive_write_data 3 .
.Pp
-The open callback is invoked by
-.Fn archive_write_open .
-It should return
-.Cm ARCHIVE_OK
-if the underlying file or data source is successfully
-opened.
-If the open fails, it should call
-.Fn archive_set_error
-to register an error code and message and return
-.Cm ARCHIVE_FATAL .
-.Bl -item -offset indent
-.It
-.Ft typedef ssize_t
-.Fo archive_write_callback
-.Fa "struct archive *"
-.Fa "void *client_data"
-.Fa "const void *buffer"
-.Fa "size_t length"
-.Fc
-.El
-.Pp
-The write callback is invoked whenever the library
-needs to write raw bytes to the archive.
-For correct blocking, each call to the write callback function
-should translate into a single
-.Xr write 2
-system call.
-This is especially critical when writing archives to tape drives.
-On success, the write callback should return the
-number of bytes actually written.
-On error, the callback should invoke
-.Fn archive_set_error
-to register an error code and message and return -1.
-.Bl -item -offset indent
-.It
-.Ft typedef int
-.Fn archive_close_callback "struct archive *" "void *client_data"
-.El
+Individual archive entries are written in a three-step
+process:
+You first initialize a
+.Tn struct archive_entry
+structure with information about the new entry.
+At a minimum, you should set the pathname of the
+entry and provide a
+.Va struct stat
+with a valid
+.Va st_mode
+field, which specifies the type of object and
+.Va st_size
+field, which specifies the size of the data portion of the object.
+.\"
+.Ss Release resources
+See
+.Xr archive_write_free 3 .
.Pp
-The close callback is invoked by archive_close when
-the archive processing is complete.
-The callback should return
-.Cm ARCHIVE_OK
-on success.
-On failure, the callback should invoke
-.Fn archive_set_error
-to register an error code and message and
-return
-.Cm ARCHIVE_FATAL.
+After all entries have been written, use the
+.Fn archive_write_free
+function to release all resources.
+.\"
.Sh EXAMPLE
The following sketch illustrates basic usage of the library.
In this example,
@@ -464,8 +137,8 @@ system calls.
#include <unistd.h>
struct mydata {
- const char *name;
- int fd;
+ const char *name;
+ int fd;
};
int
@@ -511,7 +184,7 @@ write_archive(const char *outname, const char **filename)
a = archive_write_new();
mydata->name = outname;
- archive_write_set_compression_gzip(a);
+ archive_write_add_filter_gzip(a);
archive_write_set_format_ustar(a);
archive_write_open(a, mydata, myopen, mywrite, myclose);
while (*filename) {
@@ -520,11 +193,13 @@ write_archive(const char *outname, const char **filename)
archive_entry_copy_stat(entry, &st);
archive_entry_set_pathname(entry, *filename);
archive_write_header(a, entry);
- fd = open(*filename, O_RDONLY);
- len = read(fd, buff, sizeof(buff));
- while ( len > 0 ) {
- archive_write_data(a, buff, len);
- len = read(fd, buff, sizeof(buff));
+ if ((fd = open(*filename, O_RDONLY)) != -1) {
+ len = read(fd, buff, sizeof(buff));
+ while ( len > 0 ) {
+ archive_write_data(a, buff, len);
+ len = read(fd, buff, sizeof(buff));
+ }
+ close(fd);
}
archive_entry_free(entry);
filename++;
@@ -534,62 +209,19 @@ write_archive(const char *outname, const char **filename)
int main(int argc, const char **argv)
{
- const char *outname;
- argv++;
- outname = argv++;
- write_archive(outname, argv);
- return 0;
+ const char *outname;
+ argv++;
+ outname = argv++;
+ write_archive(outname, argv);
+ return 0;
}
.Ed
-.Sh RETURN VALUES
-Most functions return
-.Cm ARCHIVE_OK
-(zero) on success, or one of several non-zero
-error codes for errors.
-Specific error codes include:
-.Cm ARCHIVE_RETRY
-for operations that might succeed if retried,
-.Cm ARCHIVE_WARN
-for unusual conditions that do not prevent further operations, and
-.Cm ARCHIVE_FATAL
-for serious errors that make remaining operations impossible.
-The
-.Fn archive_errno
-and
-.Fn archive_error_string
-functions can be used to retrieve an appropriate error code and a
-textual error message.
-.Pp
-.Fn archive_write_new
-returns a pointer to a newly-allocated
-.Tn struct archive
-object.
-.Pp
-.Fn archive_write_data
-returns a count of the number of bytes actually written.
-On error, -1 is returned and the
-.Fn archive_errno
-and
-.Fn archive_error_string
-functions will return appropriate values.
-Note that if the client-provided write callback function
-returns a non-zero value, that error will be propagated back to the caller
-through whatever API function resulted in that call, which
-may include
-.Fn archive_write_header ,
-.Fn archive_write_data ,
-.Fn archive_write_close ,
-or
-.Fn archive_write_free .
-The client callback can call
-.Fn archive_set_error
-to provide values that can then be retrieved by
-.Fn archive_errno
-and
-.Fn archive_error_string .
.Sh SEE ALSO
.Xr tar 1 ,
.Xr libarchive 3 ,
+.Xr archive_write_set_options 3 ,
+.Xr cpio 5 ,
+.Xr mtree 5 ,
.Xr tar 5
.Sh HISTORY
The
diff --git a/libarchive/archive_write.c b/libarchive/archive_write.c
index eba7227221a2..f38e5c11c656 100644
--- a/libarchive/archive_write.c
+++ b/libarchive/archive_write.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2003-2010 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -29,7 +29,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write.c 201099 2009-12-28 03:03:
/*
* This file contains the "essential" portions of the write API, that
* is, stuff that will essentially always be used by any client that
- * actually needs to write a archive. Optional pieces have been, as
+ * actually needs to write an archive. Optional pieces have been, as
* far as possible, separated out into separate files to reduce
* needlessly bloating statically-linked clients.
*/
@@ -37,6 +37,9 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write.c 201099 2009-12-28 03:03:
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
@@ -59,12 +62,23 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write.c 201099 2009-12-28 03:03:
static struct archive_vtable *archive_write_vtable(void);
+static int _archive_filter_code(struct archive *, int);
+static const char *_archive_filter_name(struct archive *, int);
+static int64_t _archive_filter_bytes(struct archive *, int);
+static int _archive_write_filter_count(struct archive *);
static int _archive_write_close(struct archive *);
static int _archive_write_free(struct archive *);
static int _archive_write_header(struct archive *, struct archive_entry *);
static int _archive_write_finish_entry(struct archive *);
static ssize_t _archive_write_data(struct archive *, const void *, size_t);
+struct archive_none {
+ size_t buffer_size;
+ size_t avail;
+ char *buffer;
+ char *next;
+};
+
static struct archive_vtable *
archive_write_vtable(void)
{
@@ -73,10 +87,15 @@ archive_write_vtable(void)
if (!inited) {
av.archive_close = _archive_write_close;
+ av.archive_filter_bytes = _archive_filter_bytes;
+ av.archive_filter_code = _archive_filter_code;
+ av.archive_filter_name = _archive_filter_name;
+ av.archive_filter_count = _archive_write_filter_count;
av.archive_free = _archive_write_free;
av.archive_write_header = _archive_write_header;
av.archive_write_finish_entry = _archive_write_finish_entry;
av.archive_write_data = _archive_write_data;
+ inited = 1;
}
return (&av);
}
@@ -114,133 +133,17 @@ archive_write_new(void)
}
memset(nulls, 0, a->null_length);
a->nulls = nulls;
- /*
- * Set default compression, but don't set a default format.
- * Were we to set a default format here, we would force every
- * client to link in support for that format, even if they didn't
- * ever use it.
- */
- archive_write_set_compression_none(&a->archive);
return (&a->archive);
}
/*
- * Set write options for the format. Returns 0 if successful.
- */
-int
-archive_write_set_format_options(struct archive *_a, const char *s)
-{
- struct archive_write *a = (struct archive_write *)_a;
- char key[64], val[64];
- int len, r, ret = ARCHIVE_OK;
-
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_set_format_options");
- archive_clear_error(&a->archive);
-
- if (s == NULL || *s == '\0')
- return (ARCHIVE_OK);
- if (a->format_options == NULL)
- /* This format does not support option. */
- return (ARCHIVE_OK);
-
- while ((len = __archive_parse_options(s, a->format_name,
- sizeof(key), key, sizeof(val), val)) > 0) {
- if (val[0] == '\0')
- r = a->format_options(a, key, NULL);
- else
- r = a->format_options(a, key, val);
- if (r == ARCHIVE_FATAL)
- return (r);
- if (r < ARCHIVE_OK) { /* This key was not handled. */
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Unsupported option ``%s''", key);
- ret = ARCHIVE_WARN;
- }
- s += len;
- }
- if (len < 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Malformed options string.");
- return (ARCHIVE_WARN);
- }
- return (ret);
-}
-
-/*
- * Set write options for the compressor. Returns 0 if successful.
- */
-int
-archive_write_set_compressor_options(struct archive *_a, const char *s)
-{
- struct archive_write *a = (struct archive_write *)_a;
- char key[64], val[64];
- int len, r;
- int ret = ARCHIVE_OK;
-
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_set_compressor_options");
- archive_clear_error(&a->archive);
-
- if (s == NULL || *s == '\0')
- return (ARCHIVE_OK);
- if (a->compressor.options == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Unsupported option ``%s''", s);
- /* This compressor does not support option. */
- return (ARCHIVE_WARN);
- }
-
- while ((len = __archive_parse_options(s, a->archive.compression_name,
- sizeof(key), key, sizeof(val), val)) > 0) {
- if (val[0] == '\0')
- r = a->compressor.options(a, key, NULL);
- else
- r = a->compressor.options(a, key, val);
- if (r == ARCHIVE_FATAL)
- return (r);
- if (r < ARCHIVE_OK) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Unsupported option ``%s''", key);
- ret = ARCHIVE_WARN;
- }
- s += len;
- }
- if (len < 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Illegal format options.");
- return (ARCHIVE_WARN);
- }
- return (ret);
-}
-
-/*
- * Set write options for the format and the compressor. Returns 0 if successful.
- */
-int
-archive_write_set_options(struct archive *_a, const char *s)
-{
- int r1, r2;
-
- r1 = archive_write_set_format_options(_a, s);
- if (r1 < ARCHIVE_WARN)
- return (r1);
- r2 = archive_write_set_compressor_options(_a, s);
- if (r2 < ARCHIVE_WARN)
- return (r2);
- if (r1 == ARCHIVE_WARN && r2 == ARCHIVE_WARN)
- return (ARCHIVE_WARN);
- return (ARCHIVE_OK);
-}
-
-/*
* Set the block size. Returns 0 if successful.
*/
int
archive_write_set_bytes_per_block(struct archive *_a, int bytes_per_block)
{
struct archive_write *a = (struct archive_write *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_NEW, "archive_write_set_bytes_per_block");
a->bytes_per_block = bytes_per_block;
return (ARCHIVE_OK);
@@ -253,7 +156,7 @@ int
archive_write_get_bytes_per_block(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_get_bytes_per_block");
return (a->bytes_per_block);
}
@@ -266,7 +169,7 @@ int
archive_write_set_bytes_in_last_block(struct archive *_a, int bytes)
{
struct archive_write *a = (struct archive_write *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_set_bytes_in_last_block");
a->bytes_in_last_block = bytes;
return (ARCHIVE_OK);
@@ -279,27 +182,264 @@ int
archive_write_get_bytes_in_last_block(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_get_bytes_in_last_block");
return (a->bytes_in_last_block);
}
-
/*
* dev/ino of a file to be rejected. Used to prevent adding
* an archive to itself recursively.
*/
int
-archive_write_set_skip_file(struct archive *_a, dev_t d, ino_t i)
+archive_write_set_skip_file(struct archive *_a, int64_t d, int64_t i)
{
struct archive_write *a = (struct archive_write *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_set_skip_file");
+ a->skip_file_set = 1;
a->skip_file_dev = d;
a->skip_file_ino = i;
return (ARCHIVE_OK);
}
+/*
+ * Allocate and return the next filter structure.
+ */
+struct archive_write_filter *
+__archive_write_allocate_filter(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ struct archive_write_filter *f;
+
+ f = calloc(1, sizeof(*f));
+ f->archive = _a;
+ if (a->filter_first == NULL)
+ a->filter_first = f;
+ else
+ a->filter_last->next_filter = f;
+ a->filter_last = f;
+ return f;
+}
+
+/*
+ * Write data to a particular filter.
+ */
+int
+__archive_write_filter(struct archive_write_filter *f,
+ const void *buff, size_t length)
+{
+ int r;
+ if (length == 0)
+ return(ARCHIVE_OK);
+ r = (f->write)(f, buff, length);
+ f->bytes_written += length;
+ return (r);
+}
+
+/*
+ * Open a filter.
+ */
+int
+__archive_write_open_filter(struct archive_write_filter *f)
+{
+ if (f->open == NULL)
+ return (ARCHIVE_OK);
+ return (f->open)(f);
+}
+
+/*
+ * Close a filter.
+ */
+int
+__archive_write_close_filter(struct archive_write_filter *f)
+{
+ if (f->close != NULL)
+ return (f->close)(f);
+ if (f->next_filter != NULL)
+ return (__archive_write_close_filter(f->next_filter));
+ return (ARCHIVE_OK);
+}
+
+int
+__archive_write_output(struct archive_write *a, const void *buff, size_t length)
+{
+ return (__archive_write_filter(a->filter_first, buff, length));
+}
+
+int
+__archive_write_nulls(struct archive_write *a, size_t length)
+{
+ if (length == 0)
+ return (ARCHIVE_OK);
+
+ while (length > 0) {
+ size_t to_write = length < a->null_length ? length : a->null_length;
+ int r = __archive_write_output(a, a->nulls, to_write);
+ if (r < ARCHIVE_OK)
+ return (r);
+ length -= to_write;
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_write_client_open(struct archive_write_filter *f)
+{
+ struct archive_write *a = (struct archive_write *)f->archive;
+ struct archive_none *state;
+ void *buffer;
+ size_t buffer_size;
+
+ f->bytes_per_block = archive_write_get_bytes_per_block(f->archive);
+ f->bytes_in_last_block =
+ archive_write_get_bytes_in_last_block(f->archive);
+ buffer_size = f->bytes_per_block;
+
+ state = (struct archive_none *)calloc(1, sizeof(*state));
+ buffer = (char *)malloc(buffer_size);
+ if (state == NULL || buffer == NULL) {
+ free(state);
+ free(buffer);
+ archive_set_error(f->archive, ENOMEM,
+ "Can't allocate data for output buffering");
+ return (ARCHIVE_FATAL);
+ }
+
+ state->buffer_size = buffer_size;
+ state->buffer = buffer;
+ state->next = state->buffer;
+ state->avail = state->buffer_size;
+ f->data = state;
+
+ if (a->client_opener == NULL)
+ return (ARCHIVE_OK);
+ return (a->client_opener(f->archive, a->client_data));
+}
+
+static int
+archive_write_client_write(struct archive_write_filter *f,
+ const void *_buff, size_t length)
+{
+ struct archive_write *a = (struct archive_write *)f->archive;
+ struct archive_none *state = (struct archive_none *)f->data;
+ const char *buff = (const char *)_buff;
+ ssize_t remaining, to_copy;
+ ssize_t bytes_written;
+
+ remaining = length;
+
+ /*
+ * If there is no buffer for blocking, just pass the data
+ * straight through to the client write callback. In
+ * particular, this supports "no write delay" operation for
+ * special applications. Just set the block size to zero.
+ */
+ if (state->buffer_size == 0) {
+ while (remaining > 0) {
+ bytes_written = (a->client_writer)(&a->archive,
+ a->client_data, buff, remaining);
+ if (bytes_written <= 0)
+ return (ARCHIVE_FATAL);
+ remaining -= bytes_written;
+ buff += bytes_written;
+ }
+ return (ARCHIVE_OK);
+ }
+
+ /* If the copy buffer isn't empty, try to fill it. */
+ if (state->avail < state->buffer_size) {
+ /* If buffer is not empty... */
+ /* ... copy data into buffer ... */
+ to_copy = ((size_t)remaining > state->avail) ?
+ state->avail : (size_t)remaining;
+ memcpy(state->next, buff, to_copy);
+ state->next += to_copy;
+ state->avail -= to_copy;
+ buff += to_copy;
+ remaining -= to_copy;
+ /* ... if it's full, write it out. */
+ if (state->avail == 0) {
+ char *p = state->buffer;
+ size_t to_write = state->buffer_size;
+ while (to_write > 0) {
+ bytes_written = (a->client_writer)(&a->archive,
+ a->client_data, p, to_write);
+ if (bytes_written <= 0)
+ return (ARCHIVE_FATAL);
+ if ((size_t)bytes_written > to_write) {
+ archive_set_error(&(a->archive),
+ -1, "write overrun");
+ return (ARCHIVE_FATAL);
+ }
+ p += bytes_written;
+ to_write -= bytes_written;
+ }
+ state->next = state->buffer;
+ state->avail = state->buffer_size;
+ }
+ }
+
+ while ((size_t)remaining > state->buffer_size) {
+ /* Write out full blocks directly to client. */
+ bytes_written = (a->client_writer)(&a->archive,
+ a->client_data, buff, state->buffer_size);
+ if (bytes_written <= 0)
+ return (ARCHIVE_FATAL);
+ buff += bytes_written;
+ remaining -= bytes_written;
+ }
+
+ if (remaining > 0) {
+ /* Copy last bit into copy buffer. */
+ memcpy(state->next, buff, remaining);
+ state->next += remaining;
+ state->avail -= remaining;
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_write_client_close(struct archive_write_filter *f)
+{
+ struct archive_write *a = (struct archive_write *)f->archive;
+ struct archive_none *state = (struct archive_none *)f->data;
+ ssize_t block_length;
+ ssize_t target_block_length;
+ ssize_t bytes_written;
+ int ret = ARCHIVE_OK;
+
+ /* If there's pending data, pad and write the last block */
+ if (state->next != state->buffer) {
+ block_length = state->buffer_size - state->avail;
+
+ /* Tricky calculation to determine size of last block */
+ if (a->bytes_in_last_block <= 0)
+ /* Default or Zero: pad to full block */
+ target_block_length = a->bytes_per_block;
+ else
+ /* Round to next multiple of bytes_in_last_block. */
+ target_block_length = a->bytes_in_last_block *
+ ( (block_length + a->bytes_in_last_block - 1) /
+ a->bytes_in_last_block);
+ if (target_block_length > a->bytes_per_block)
+ target_block_length = a->bytes_per_block;
+ if (block_length < target_block_length) {
+ memset(state->next, 0,
+ target_block_length - block_length);
+ block_length = target_block_length;
+ }
+ bytes_written = (a->client_writer)(&a->archive,
+ a->client_data, state->buffer, block_length);
+ ret = bytes_written <= 0 ? ARCHIVE_FATAL : ARCHIVE_OK;
+ }
+ if (a->client_closer)
+ (*a->client_closer)(&a->archive, a->client_data);
+ free(state->buffer);
+ free(state);
+ a->client_data = NULL;
+ return (ret);
+}
/*
* Open the archive using the current settings.
@@ -310,29 +450,37 @@ archive_write_open(struct archive *_a, void *client_data,
archive_close_callback *closer)
{
struct archive_write *a = (struct archive_write *)_a;
- int ret;
+ struct archive_write_filter *client_filter;
+ int ret, r1;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_NEW, "archive_write_open");
archive_clear_error(&a->archive);
- a->archive.state = ARCHIVE_STATE_HEADER;
- a->client_data = client_data;
+
a->client_writer = writer;
a->client_opener = opener;
a->client_closer = closer;
- ret = (a->compressor.init)(a);
- if (a->format_init && ret == ARCHIVE_OK)
+ a->client_data = client_data;
+
+ client_filter = __archive_write_allocate_filter(_a);
+ client_filter->open = archive_write_client_open;
+ client_filter->write = archive_write_client_write;
+ client_filter->close = archive_write_client_close;
+
+ ret = __archive_write_open_filter(a->filter_first);
+ if (ret < ARCHIVE_WARN) {
+ r1 = __archive_write_close_filter(a->filter_first);
+ return (r1 < ret ? r1 : ret);
+ }
+
+ a->archive.state = ARCHIVE_STATE_HEADER;
+ if (a->format_init)
ret = (a->format_init)(a);
return (ret);
}
-
/*
* Close out the archive.
- *
- * Be careful: user might just call write_new and then write_finish.
- * Don't assume we actually wrote anything or performed any non-trivial
- * initialization.
*/
static int
_archive_write_close(struct archive *_a)
@@ -340,63 +488,105 @@ _archive_write_close(struct archive *_a)
struct archive_write *a = (struct archive_write *)_a;
int r = ARCHIVE_OK, r1 = ARCHIVE_OK;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_ANY, "archive_write_close");
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL,
+ "archive_write_close");
+ if (a->archive.state == ARCHIVE_STATE_NEW
+ || a->archive.state == ARCHIVE_STATE_CLOSED)
+ return (ARCHIVE_OK); /* Okay to close() when not open. */
+
+ archive_clear_error(&a->archive);
/* Finish the last entry. */
- if (a->archive.state & ARCHIVE_STATE_DATA)
+ if (a->archive.state == ARCHIVE_STATE_DATA)
r = ((a->format_finish_entry)(a));
/* Finish off the archive. */
- if (a->format_finish != NULL) {
- r1 = (a->format_finish)(a);
- if (r1 < r)
- r = r1;
- }
-
- /* Release format resources. */
- if (a->format_destroy != NULL) {
- r1 = (a->format_destroy)(a);
+ /* TODO: have format closers invoke compression close. */
+ if (a->format_close != NULL) {
+ r1 = (a->format_close)(a);
if (r1 < r)
r = r1;
}
/* Finish the compression and close the stream. */
- if (a->compressor.finish != NULL) {
- r1 = (a->compressor.finish)(a);
- if (r1 < r)
- r = r1;
- }
+ r1 = __archive_write_close_filter(a->filter_first);
+ if (r1 < r)
+ r = r1;
- /* Close out the client stream. */
- if (a->client_closer != NULL) {
- r1 = (a->client_closer)(&a->archive, a->client_data);
- if (r1 < r)
- r = r1;
+ if (a->archive.state != ARCHIVE_STATE_FATAL)
+ a->archive.state = ARCHIVE_STATE_CLOSED;
+ return (r);
+}
+
+static int
+_archive_write_filter_count(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ struct archive_write_filter *p = a->filter_first;
+ int count = 0;
+ while(p) {
+ count++;
+ p = p->next_filter;
}
+ return count;
+}
- a->archive.state = ARCHIVE_STATE_CLOSED;
- return (r);
+void
+__archive_write_filters_free(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ int r = ARCHIVE_OK, r1;
+
+ while (a->filter_first != NULL) {
+ struct archive_write_filter *next
+ = a->filter_first->next_filter;
+ if (a->filter_first->free != NULL) {
+ r1 = (*a->filter_first->free)(a->filter_first);
+ if (r > r1)
+ r = r1;
+ }
+ free(a->filter_first);
+ a->filter_first = next;
+ }
+ a->filter_last = NULL;
}
/*
* Destroy the archive structure.
+ *
+ * Be careful: user might just call write_new and then write_free.
+ * Don't assume we actually wrote anything or performed any non-trivial
+ * initialization.
*/
static int
_archive_write_free(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
- int r = ARCHIVE_OK;
+ int r = ARCHIVE_OK, r1;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_ANY, "archive_write_free");
- if (a->archive.state != ARCHIVE_STATE_CLOSED)
+ if (_a == NULL)
+ return (ARCHIVE_OK);
+ /* It is okay to call free() in state FATAL. */
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_write_free");
+ if (a->archive.state != ARCHIVE_STATE_FATAL)
r = archive_write_close(&a->archive);
+ /* Release format resources. */
+ if (a->format_free != NULL) {
+ r1 = (a->format_free)(a);
+ if (r1 < r)
+ r = r1;
+ }
+
+ __archive_write_filters_free(_a);
+
/* Release various dynamic buffers. */
free((void *)(uintptr_t)(const void *)a->nulls);
archive_string_free(&a->archive.error_string);
a->archive.magic = 0;
+ __archive_clean(&a->archive);
free(a);
return (r);
}
@@ -410,18 +600,30 @@ _archive_write_header(struct archive *_a, struct archive_entry *entry)
struct archive_write *a = (struct archive_write *)_a;
int ret, r2;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_DATA | ARCHIVE_STATE_HEADER, "archive_write_header");
archive_clear_error(&a->archive);
+ if (a->format_write_header == NULL) {
+ archive_set_error(&(a->archive), -1,
+ "Format must be set before you can write to an archive.");
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+ }
+
/* In particular, "retry" and "fatal" get returned immediately. */
ret = archive_write_finish_entry(&a->archive);
+ if (ret == ARCHIVE_FATAL) {
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+ }
if (ret < ARCHIVE_OK && ret != ARCHIVE_WARN)
return (ret);
- if (a->skip_file_dev != 0 &&
+ if (a->skip_file_set &&
+ archive_entry_dev_is_set(entry) &&
+ archive_entry_ino_is_set(entry) &&
archive_entry_dev(entry) == a->skip_file_dev &&
- a->skip_file_ino != 0 &&
archive_entry_ino64(entry) == a->skip_file_ino) {
archive_set_error(&a->archive, 0,
"Can't add archive to itself");
@@ -430,6 +632,10 @@ _archive_write_header(struct archive *_a, struct archive_entry *entry)
/* Format and write header. */
r2 = ((a->format_write_header)(a, entry));
+ if (r2 == ARCHIVE_FATAL) {
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+ }
if (r2 < ret)
ret = r2;
@@ -443,7 +649,7 @@ _archive_write_finish_entry(struct archive *_a)
struct archive_write *a = (struct archive_write *)_a;
int ret = ARCHIVE_OK;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
"archive_write_finish_entry");
if (a->archive.state & ARCHIVE_STATE_DATA)
@@ -459,8 +665,45 @@ static ssize_t
_archive_write_data(struct archive *_a, const void *buff, size_t s)
{
struct archive_write *a = (struct archive_write *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_DATA, "archive_write_data");
archive_clear_error(&a->archive);
return ((a->format_write_data)(a, buff, s));
}
+
+static struct archive_write_filter *
+filter_lookup(struct archive *_a, int n)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ struct archive_write_filter *f = a->filter_first;
+ if (n == -1)
+ return a->filter_last;
+ if (n < 0)
+ return NULL;
+ while (n > 0 && f != NULL) {
+ f = f->next_filter;
+ --n;
+ }
+ return f;
+}
+
+static int
+_archive_filter_code(struct archive *_a, int n)
+{
+ struct archive_write_filter *f = filter_lookup(_a, n);
+ return f == NULL ? -1 : f->code;
+}
+
+static const char *
+_archive_filter_name(struct archive *_a, int n)
+{
+ struct archive_write_filter *f = filter_lookup(_a, n);
+ return f == NULL ? NULL : f->name;
+}
+
+static int64_t
+_archive_filter_bytes(struct archive *_a, int n)
+{
+ struct archive_write_filter *f = filter_lookup(_a, n);
+ return f == NULL ? -1 : f->bytes_written;
+}
diff --git a/libarchive/archive_write_add_filter_bzip2.c b/libarchive/archive_write_add_filter_bzip2.c
new file mode 100644
index 000000000000..e0d07a9ff7c7
--- /dev/null
+++ b/libarchive/archive_write_add_filter_bzip2.c
@@ -0,0 +1,335 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+
+__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_bzip2.c 201091 2009-12-28 02:22:41Z kientzle $");
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_BZLIB_H
+#include <bzlib.h>
+#endif
+
+#include "archive.h"
+#include "archive_private.h"
+#include "archive_write_private.h"
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+int
+archive_write_set_compression_bzip2(struct archive *a)
+{
+ __archive_write_filters_free(a);
+ return (archive_write_add_filter_bzip2(a));
+}
+#endif
+
+#if !defined(HAVE_BZLIB_H) || !defined(BZ_CONFIG_ERROR)
+int
+archive_write_add_filter_bzip2(struct archive *a)
+{
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "bzip2 compression not supported on this platform");
+ return (ARCHIVE_FATAL);
+}
+#else
+/* Don't compile this if we don't have bzlib. */
+
+struct private_data {
+ int compression_level;
+ bz_stream stream;
+ int64_t total_in;
+ char *compressed;
+ size_t compressed_buffer_size;
+};
+
+/*
+ * Yuck. bzlib.h is not const-correct, so I need this one bit
+ * of ugly hackery to convert a const * pointer to a non-const pointer.
+ */
+#define SET_NEXT_IN(st,src) \
+ (st)->stream.next_in = (char *)(uintptr_t)(const void *)(src)
+
+static int archive_compressor_bzip2_close(struct archive_write_filter *);
+static int archive_compressor_bzip2_free(struct archive_write_filter *);
+static int archive_compressor_bzip2_open(struct archive_write_filter *);
+static int archive_compressor_bzip2_options(struct archive_write_filter *,
+ const char *, const char *);
+static int archive_compressor_bzip2_write(struct archive_write_filter *,
+ const void *, size_t);
+static int drive_compressor(struct archive_write_filter *,
+ struct private_data *, int finishing);
+
+/*
+ * Add a bzip2 compression filter to this write handle.
+ */
+int
+archive_write_add_filter_bzip2(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ struct archive_write_filter *f = __archive_write_allocate_filter(_a);
+ struct private_data *data;
+
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_add_filter_bzip2");
+
+ data = calloc(1, sizeof(*data));
+ if (data == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+ data->compression_level = 9; /* default */
+
+ f->data = data;
+ f->options = &archive_compressor_bzip2_options;
+ f->close = &archive_compressor_bzip2_close;
+ f->free = &archive_compressor_bzip2_free;
+ f->open = &archive_compressor_bzip2_open;
+ f->code = ARCHIVE_COMPRESSION_BZIP2;
+ f->name = "bzip2";
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Setup callback.
+ */
+static int
+archive_compressor_bzip2_open(struct archive_write_filter *f)
+{
+ struct private_data *data = (struct private_data *)f->data;
+ int ret;
+
+ ret = __archive_write_open_filter(f->next_filter);
+ if (ret != 0)
+ return (ret);
+
+ /* TODO: Find a better way to size this. (Maybe look at the */
+ /* block size expected by the following filter?) */
+ if (data->compressed == NULL) {
+ data->compressed_buffer_size = 65536;
+ data->compressed
+ = (char *)malloc(data->compressed_buffer_size);
+ if (data->compressed == NULL) {
+ archive_set_error(f->archive, ENOMEM,
+ "Can't allocate data for compression buffer");
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ memset(&data->stream, 0, sizeof(data->stream));
+ data->stream.next_out = data->compressed;
+ data->stream.avail_out = data->compressed_buffer_size;
+ f->write = archive_compressor_bzip2_write;
+
+ /* Initialize compression library */
+ ret = BZ2_bzCompressInit(&(data->stream),
+ data->compression_level, 0, 30);
+ if (ret == BZ_OK) {
+ f->data = data;
+ return (ARCHIVE_OK);
+ }
+
+ /* Library setup failed: clean up. */
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "Internal error initializing compression library");
+
+ /* Override the error message if we know what really went wrong. */
+ switch (ret) {
+ case BZ_PARAM_ERROR:
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "Internal error initializing compression library: "
+ "invalid setup parameter");
+ break;
+ case BZ_MEM_ERROR:
+ archive_set_error(f->archive, ENOMEM,
+ "Internal error initializing compression library: "
+ "out of memory");
+ break;
+ case BZ_CONFIG_ERROR:
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "Internal error initializing compression library: "
+ "mis-compiled library");
+ break;
+ }
+
+ return (ARCHIVE_FATAL);
+
+}
+
+/*
+ * Set write options.
+ */
+static int
+archive_compressor_bzip2_options(struct archive_write_filter *f,
+ const char *key, const char *value)
+{
+ struct private_data *data = (struct private_data *)f->data;
+
+ if (strcmp(key, "compression-level") == 0) {
+ if (value == NULL || !(value[0] >= '0' && value[0] <= '9') ||
+ value[1] != '\0')
+ return (ARCHIVE_WARN);
+ data->compression_level = value[0] - '0';
+ /* Make '0' be a synonym for '1'. */
+ /* This way, bzip2 compressor supports the same 0..9
+ * range of levels as gzip. */
+ if (data->compression_level < 1)
+ data->compression_level = 1;
+ return (ARCHIVE_OK);
+ }
+
+ return (ARCHIVE_WARN);
+}
+
+/*
+ * Write data to the compressed stream.
+ *
+ * Returns ARCHIVE_OK if all data written, error otherwise.
+ */
+static int
+archive_compressor_bzip2_write(struct archive_write_filter *f,
+ const void *buff, size_t length)
+{
+ struct private_data *data = (struct private_data *)f->data;
+
+ /* Update statistics */
+ data->total_in += length;
+
+ /* Compress input data to output buffer */
+ SET_NEXT_IN(data, buff);
+ data->stream.avail_in = length;
+ if (drive_compressor(f, data, 0))
+ return (ARCHIVE_FATAL);
+ return (ARCHIVE_OK);
+}
+
+
+/*
+ * Finish the compression.
+ */
+static int
+archive_compressor_bzip2_close(struct archive_write_filter *f)
+{
+ struct private_data *data = (struct private_data *)f->data;
+ int ret, r1;
+
+ /* Finish compression cycle. */
+ ret = drive_compressor(f, data, 1);
+ if (ret == ARCHIVE_OK) {
+ /* Write the last block */
+ ret = __archive_write_filter(f->next_filter,
+ data->compressed,
+ data->compressed_buffer_size - data->stream.avail_out);
+ }
+
+ switch (BZ2_bzCompressEnd(&(data->stream))) {
+ case BZ_OK:
+ break;
+ default:
+ archive_set_error(f->archive, ARCHIVE_ERRNO_PROGRAMMER,
+ "Failed to clean up compressor");
+ ret = ARCHIVE_FATAL;
+ }
+
+ r1 = __archive_write_close_filter(f->next_filter);
+ return (r1 < ret ? r1 : ret);
+}
+
+static int
+archive_compressor_bzip2_free(struct archive_write_filter *f)
+{
+ struct private_data *data = (struct private_data *)f->data;
+ free(data->compressed);
+ free(data);
+ f->data = NULL;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Utility function to push input data through compressor, writing
+ * full output blocks as necessary.
+ *
+ * Note that this handles both the regular write case (finishing ==
+ * false) and the end-of-archive case (finishing == true).
+ */
+static int
+drive_compressor(struct archive_write_filter *f,
+ struct private_data *data, int finishing)
+{
+ int ret;
+
+ for (;;) {
+ if (data->stream.avail_out == 0) {
+ ret = __archive_write_filter(f->next_filter,
+ data->compressed,
+ data->compressed_buffer_size);
+ if (ret != ARCHIVE_OK) {
+ /* TODO: Handle this write failure */
+ return (ARCHIVE_FATAL);
+ }
+ data->stream.next_out = data->compressed;
+ data->stream.avail_out = data->compressed_buffer_size;
+ }
+
+ /* If there's nothing to do, we're done. */
+ if (!finishing && data->stream.avail_in == 0)
+ return (ARCHIVE_OK);
+
+ ret = BZ2_bzCompress(&(data->stream),
+ finishing ? BZ_FINISH : BZ_RUN);
+
+ switch (ret) {
+ case BZ_RUN_OK:
+ /* In non-finishing case, did compressor
+ * consume everything? */
+ if (!finishing && data->stream.avail_in == 0)
+ return (ARCHIVE_OK);
+ break;
+ case BZ_FINISH_OK: /* Finishing: There's more work to do */
+ break;
+ case BZ_STREAM_END: /* Finishing: all done */
+ /* Only occurs in finishing case */
+ return (ARCHIVE_OK);
+ default:
+ /* Any other return value indicates an error */
+ archive_set_error(f->archive,
+ ARCHIVE_ERRNO_PROGRAMMER,
+ "Bzip2 compression failed;"
+ " BZ2_bzCompress() returned %d",
+ ret);
+ return (ARCHIVE_FATAL);
+ }
+ }
+}
+
+#endif /* HAVE_BZLIB_H && BZ_CONFIG_ERROR */
diff --git a/libarchive/archive_write_set_compression_compress.c b/libarchive/archive_write_add_filter_compress.c
index 77c73ee5f270..465ff0e77bd1 100644
--- a/libarchive/archive_write_set_compression_compress.c
+++ b/libarchive/archive_write_add_filter_compress.c
@@ -88,7 +88,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_compress.c
#define CLEAR 256 /* Table clear output code. */
struct private_data {
- off_t in_count, out_count, checkpoint;
+ int64_t in_count, out_count, checkpoint;
int code_len; /* Number of bits/code. */
int cur_maxcode; /* Maximum code, given n_bits. */
@@ -108,23 +108,35 @@ struct private_data {
size_t compressed_offset;
};
-static int archive_compressor_compress_finish(struct archive_write *);
-static int archive_compressor_compress_init(struct archive_write *);
-static int archive_compressor_compress_write(struct archive_write *,
+static int archive_compressor_compress_open(struct archive_write_filter *);
+static int archive_compressor_compress_write(struct archive_write_filter *,
const void *, size_t);
+static int archive_compressor_compress_close(struct archive_write_filter *);
+static int archive_compressor_compress_free(struct archive_write_filter *);
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+int
+archive_write_set_compression_compress(struct archive *a)
+{
+ __archive_write_filters_free(a);
+ return (archive_write_add_filter_compress(a));
+}
+#endif
/*
- * Allocate, initialize and return a archive object.
+ * Add a compress filter to this write handle.
*/
int
-archive_write_set_compression_compress(struct archive *_a)
+archive_write_add_filter_compress(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_set_compression_compress");
- a->compressor.init = &archive_compressor_compress_init;
- a->archive.compression_code = ARCHIVE_COMPRESSION_COMPRESS;
- a->archive.compression_name = "compress";
+ struct archive_write_filter *f = __archive_write_allocate_filter(_a);
+
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_add_filter_compress");
+ f->open = &archive_compressor_compress_open;
+ f->code = ARCHIVE_COMPRESSION_COMPRESS;
+ f->name = "compress";
return (ARCHIVE_OK);
}
@@ -132,46 +144,38 @@ archive_write_set_compression_compress(struct archive *_a)
* Setup callback.
*/
static int
-archive_compressor_compress_init(struct archive_write *a)
+archive_compressor_compress_open(struct archive_write_filter *f)
{
int ret;
struct private_data *state;
- a->archive.compression_code = ARCHIVE_COMPRESSION_COMPRESS;
- a->archive.compression_name = "compress";
-
- if (a->bytes_per_block < 4) {
- archive_set_error(&a->archive, EINVAL,
- "Can't write Compress header as single block");
- return (ARCHIVE_FATAL);
- }
+ f->code = ARCHIVE_COMPRESSION_COMPRESS;
+ f->name = "compress";
- if (a->client_opener != NULL) {
- ret = (a->client_opener)(&a->archive, a->client_data);
- if (ret != ARCHIVE_OK)
- return (ret);
- }
+ ret = __archive_write_open_filter(f->next_filter);
+ if (ret != ARCHIVE_OK)
+ return (ret);
- state = (struct private_data *)malloc(sizeof(*state));
+ state = (struct private_data *)calloc(1, sizeof(*state));
if (state == NULL) {
- archive_set_error(&a->archive, ENOMEM,
+ archive_set_error(f->archive, ENOMEM,
"Can't allocate data for compression");
return (ARCHIVE_FATAL);
}
- memset(state, 0, sizeof(*state));
- state->compressed_buffer_size = a->bytes_per_block;
+ state->compressed_buffer_size = 65536;
state->compressed = malloc(state->compressed_buffer_size);
if (state->compressed == NULL) {
- archive_set_error(&a->archive, ENOMEM,
+ archive_set_error(f->archive, ENOMEM,
"Can't allocate data for compression buffer");
free(state);
return (ARCHIVE_FATAL);
}
- a->compressor.write = archive_compressor_compress_write;
- a->compressor.finish = archive_compressor_compress_finish;
+ f->write = archive_compressor_compress_write;
+ f->close = archive_compressor_compress_close;
+ f->free = archive_compressor_compress_free;
state->max_maxcode = 0x10000; /* Should NEVER generate this code. */
state->in_count = 0; /* Length of input. */
@@ -192,7 +196,7 @@ archive_compressor_compress_init(struct archive_write *a)
state->compressed[2] = 0x90; /* Block mode, 16bit max */
state->compressed_offset = 3;
- a->compressor.data = state;
+ f->data = state;
return (0);
}
@@ -200,7 +204,7 @@ archive_compressor_compress_init(struct archive_write *a)
* Output the given code.
* Inputs:
* code: A n_bits-bit integer. If == -1, then EOF. This assumes
- * that n_bits =< (long)wordsize - 1.
+ * that n_bits <= (long)wordsize - 1.
* Outputs:
* Outputs code to the file.
* Assumptions:
@@ -211,25 +215,22 @@ archive_compressor_compress_init(struct archive_write *a)
* code in turn. When the buffer fills up empty it and start over.
*/
-static unsigned char rmask[9] =
+static const unsigned char rmask[9] =
{0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
static int
-output_byte(struct archive_write *a, unsigned char c)
+output_byte(struct archive_write_filter *f, unsigned char c)
{
- struct private_data *state = a->compressor.data;
- ssize_t bytes_written;
+ struct private_data *state = f->data;
state->compressed[state->compressed_offset++] = c;
++state->out_count;
if (state->compressed_buffer_size == state->compressed_offset) {
- bytes_written = (a->client_writer)(&a->archive,
- a->client_data,
+ int ret = __archive_write_filter(f->next_filter,
state->compressed, state->compressed_buffer_size);
- if (bytes_written <= 0)
+ if (ret != ARCHIVE_OK)
return ARCHIVE_FATAL;
- a->archive.raw_position += bytes_written;
state->compressed_offset = 0;
}
@@ -237,9 +238,9 @@ output_byte(struct archive_write *a, unsigned char c)
}
static int
-output_code(struct archive_write *a, int ocode)
+output_code(struct archive_write_filter *f, int ocode)
{
- struct private_data *state = a->compressor.data;
+ struct private_data *state = f->data;
int bits, ret, clear_flg, bit_offset;
clear_flg = ocode == CLEAR;
@@ -250,13 +251,13 @@ output_code(struct archive_write *a, int ocode)
*/
bit_offset = state->bit_offset % 8;
state->bit_buf |= (ocode << bit_offset) & 0xff;
- output_byte(a, state->bit_buf);
+ output_byte(f, state->bit_buf);
bits = state->code_len - (8 - bit_offset);
ocode >>= 8 - bit_offset;
/* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
if (bits >= 8) {
- output_byte(a, ocode & 0xff);
+ output_byte(f, ocode & 0xff);
ocode >>= 8;
bits -= 8;
}
@@ -277,7 +278,7 @@ output_code(struct archive_write *a, int ocode)
*/
if (state->bit_offset > 0) {
while (state->bit_offset < state->code_len * 8) {
- ret = output_byte(a, state->bit_buf);
+ ret = output_byte(f, state->bit_buf);
if (ret != ARCHIVE_OK)
return ret;
state->bit_offset += 8;
@@ -303,15 +304,15 @@ output_code(struct archive_write *a, int ocode)
}
static int
-output_flush(struct archive_write *a)
+output_flush(struct archive_write_filter *f)
{
- struct private_data *state = a->compressor.data;
+ struct private_data *state = f->data;
int ret;
/* At EOF, write the rest of the buffer. */
if (state->bit_offset % 8) {
state->code_len = (state->bit_offset % 8 + 7) / 8;
- ret = output_byte(a, state->bit_buf);
+ ret = output_byte(f, state->bit_buf);
if (ret != ARCHIVE_OK)
return ret;
}
@@ -323,23 +324,15 @@ output_flush(struct archive_write *a)
* Write data to the compressed stream.
*/
static int
-archive_compressor_compress_write(struct archive_write *a, const void *buff,
- size_t length)
+archive_compressor_compress_write(struct archive_write_filter *f,
+ const void *buff, size_t length)
{
- struct private_data *state;
+ struct private_data *state = (struct private_data *)f->data;
int i;
int ratio;
int c, disp, ret;
const unsigned char *bp;
- state = (struct private_data *)a->compressor.data;
- if (a->client_writer == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "No write callback is registered? "
- "This is probably an internal programming error.");
- return (ARCHIVE_FATAL);
- }
-
if (length == 0)
return ARCHIVE_OK;
@@ -368,7 +361,7 @@ archive_compressor_compress_write(struct archive_write *a, const void *buff,
disp = 1;
else
disp = HSIZE - i;
- probe:
+ probe:
if ((i -= disp) < 0)
i += HSIZE;
@@ -378,8 +371,8 @@ archive_compressor_compress_write(struct archive_write *a, const void *buff,
}
if (state->hashtab[i] >= 0)
goto probe;
- nomatch:
- ret = output_code(a, state->cur_code);
+ nomatch:
+ ret = output_code(f, state->cur_code);
if (ret != ARCHIVE_OK)
return ret;
state->cur_code = c;
@@ -406,7 +399,7 @@ archive_compressor_compress_write(struct archive_write *a, const void *buff,
state->compress_ratio = 0;
memset(state->hashtab, 0xff, sizeof(state->hashtab));
state->first_free = FIRST;
- ret = output_code(a, CLEAR);
+ ret = output_code(f, CLEAR);
if (ret != ARCHIVE_OK)
return ret;
}
@@ -420,73 +413,33 @@ archive_compressor_compress_write(struct archive_write *a, const void *buff,
* Finish the compression...
*/
static int
-archive_compressor_compress_finish(struct archive_write *a)
+archive_compressor_compress_close(struct archive_write_filter *f)
{
- ssize_t block_length, target_block_length, bytes_written;
- int ret;
- struct private_data *state;
- size_t tocopy;
-
- state = (struct private_data *)a->compressor.data;
- if (a->client_writer == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "No write callback is registered? "
- "This is probably an internal programming error.");
- ret = ARCHIVE_FATAL;
- goto cleanup;
- }
-
- /* By default, always pad the uncompressed data. */
- if (a->pad_uncompressed) {
- while (state->in_count % a->bytes_per_block != 0) {
- tocopy = a->bytes_per_block -
- (state->in_count % a->bytes_per_block);
- if (tocopy > a->null_length)
- tocopy = a->null_length;
- ret = archive_compressor_compress_write(a, a->nulls,
- tocopy);
- if (ret != ARCHIVE_OK)
- goto cleanup;
- }
- }
+ struct private_data *state = (struct private_data *)f->data;
+ int ret, ret2;
- ret = output_code(a, state->cur_code);
+ ret = output_code(f, state->cur_code);
if (ret != ARCHIVE_OK)
goto cleanup;
- ret = output_flush(a);
+ ret = output_flush(f);
if (ret != ARCHIVE_OK)
goto cleanup;
- /* Optionally, pad the final compressed block. */
- block_length = state->compressed_offset;
-
- /* Tricky calculation to determine size of last block. */
- if (a->bytes_in_last_block <= 0)
- /* Default or Zero: pad to full block */
- target_block_length = a->bytes_per_block;
- else
- /* Round length to next multiple of bytes_in_last_block. */
- target_block_length = a->bytes_in_last_block *
- ( (block_length + a->bytes_in_last_block - 1) /
- a->bytes_in_last_block);
- if (target_block_length > a->bytes_per_block)
- target_block_length = a->bytes_per_block;
- if (block_length < target_block_length) {
- memset(state->compressed + state->compressed_offset, 0,
- target_block_length - block_length);
- block_length = target_block_length;
- }
-
/* Write the last block */
- bytes_written = (a->client_writer)(&a->archive, a->client_data,
- state->compressed, block_length);
- if (bytes_written <= 0)
- ret = ARCHIVE_FATAL;
- else
- a->archive.raw_position += bytes_written;
-
+ ret = __archive_write_filter(f->next_filter,
+ state->compressed, state->compressed_offset);
cleanup:
+ ret2 = __archive_write_close_filter(f->next_filter);
+ if (ret > ret2)
+ ret = ret2;
free(state->compressed);
free(state);
return (ret);
}
+
+static int
+archive_compressor_compress_free(struct archive_write_filter *f)
+{
+ (void)f; /* UNUSED */
+ return (ARCHIVE_OK);
+}
diff --git a/libarchive/archive_write_add_filter_gzip.c b/libarchive/archive_write_add_filter_gzip.c
new file mode 100644
index 000000000000..786ae98ac020
--- /dev/null
+++ b/libarchive/archive_write_add_filter_gzip.c
@@ -0,0 +1,356 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+
+__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_gzip.c 201081 2009-12-28 02:04:42Z kientzle $");
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#include <time.h>
+#ifdef HAVE_ZLIB_H
+#include <zlib.h>
+#endif
+
+#include "archive.h"
+#include "archive_private.h"
+#include "archive_write_private.h"
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+int
+archive_write_set_compression_gzip(struct archive *a)
+{
+ __archive_write_filters_free(a);
+ return (archive_write_add_filter_gzip(a));
+}
+#endif
+
+#ifndef HAVE_ZLIB_H
+int
+archive_write_add_filter_gzip(struct archive *a)
+{
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "gzip compression not supported on this platform");
+ return (ARCHIVE_FATAL);
+}
+#else
+/* Don't compile this if we don't have zlib. */
+
+struct private_data {
+ int compression_level;
+ z_stream stream;
+ int64_t total_in;
+ unsigned char *compressed;
+ size_t compressed_buffer_size;
+ unsigned long crc;
+};
+
+/*
+ * Yuck. zlib.h is not const-correct, so I need this one bit
+ * of ugly hackery to convert a const * pointer to a non-const pointer.
+ */
+#define SET_NEXT_IN(st,src) \
+ (st)->stream.next_in = (Bytef *)(uintptr_t)(const void *)(src)
+
+static int archive_compressor_gzip_options(struct archive_write_filter *,
+ const char *, const char *);
+static int archive_compressor_gzip_open(struct archive_write_filter *);
+static int archive_compressor_gzip_write(struct archive_write_filter *,
+ const void *, size_t);
+static int archive_compressor_gzip_close(struct archive_write_filter *);
+static int archive_compressor_gzip_free(struct archive_write_filter *);
+static int drive_compressor(struct archive_write_filter *,
+ struct private_data *, int finishing);
+
+
+/*
+ * Add a gzip compression filter to this write handle.
+ */
+int
+archive_write_add_filter_gzip(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ struct archive_write_filter *f = __archive_write_allocate_filter(_a);
+ struct private_data *data;
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_add_filter_gzip");
+
+ data = calloc(1, sizeof(*data));
+ if (data == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+ f->data = data;
+ data->compression_level = Z_DEFAULT_COMPRESSION;
+ f->open = &archive_compressor_gzip_open;
+ f->options = &archive_compressor_gzip_options;
+ f->close = &archive_compressor_gzip_close;
+ f->free = &archive_compressor_gzip_free;
+ f->code = ARCHIVE_COMPRESSION_GZIP;
+ f->name = "gzip";
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Setup callback.
+ */
+static int
+archive_compressor_gzip_open(struct archive_write_filter *f)
+{
+ struct private_data *data = (struct private_data *)f->data;
+ int ret;
+ time_t t;
+
+ ret = __archive_write_open_filter(f->next_filter);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+
+ if (data->compressed == NULL) {
+ data->compressed_buffer_size = 65536;
+ data->compressed
+ = (unsigned char *)malloc(data->compressed_buffer_size);
+ if (data->compressed == NULL) {
+ archive_set_error(f->archive, ENOMEM,
+ "Can't allocate data for compression buffer");
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ data->crc = crc32(0L, NULL, 0);
+ data->stream.next_out = data->compressed;
+ data->stream.avail_out = data->compressed_buffer_size;
+
+ /* Prime output buffer with a gzip header. */
+ t = time(NULL);
+ data->compressed[0] = 0x1f; /* GZip signature bytes */
+ data->compressed[1] = 0x8b;
+ data->compressed[2] = 0x08; /* "Deflate" compression */
+ data->compressed[3] = 0; /* No options */
+ data->compressed[4] = (t)&0xff; /* Timestamp */
+ data->compressed[5] = (t>>8)&0xff;
+ data->compressed[6] = (t>>16)&0xff;
+ data->compressed[7] = (t>>24)&0xff;
+ data->compressed[8] = 0; /* No deflate options */
+ data->compressed[9] = 3; /* OS=Unix */
+ data->stream.next_out += 10;
+ data->stream.avail_out -= 10;
+
+ f->write = archive_compressor_gzip_write;
+
+ /* Initialize compression library. */
+ ret = deflateInit2(&(data->stream),
+ data->compression_level,
+ Z_DEFLATED,
+ -15 /* < 0 to suppress zlib header */,
+ 8,
+ Z_DEFAULT_STRATEGY);
+
+ if (ret == Z_OK) {
+ f->data = data;
+ return (ARCHIVE_OK);
+ }
+
+ /* Library setup failed: clean up. */
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC, "Internal error "
+ "initializing compression library");
+
+ /* Override the error message if we know what really went wrong. */
+ switch (ret) {
+ case Z_STREAM_ERROR:
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "Internal error initializing "
+ "compression library: invalid setup parameter");
+ break;
+ case Z_MEM_ERROR:
+ archive_set_error(f->archive, ENOMEM, "Internal error initializing "
+ "compression library");
+ break;
+ case Z_VERSION_ERROR:
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "Internal error initializing "
+ "compression library: invalid library version");
+ break;
+ }
+
+ return (ARCHIVE_FATAL);
+}
+
+/*
+ * Set write options.
+ */
+static int
+archive_compressor_gzip_options(struct archive_write_filter *f, const char *key,
+ const char *value)
+{
+ struct private_data *data = (struct private_data *)f->data;
+
+ if (strcmp(key, "compression-level") == 0) {
+ if (value == NULL || !(value[0] >= '0' && value[0] <= '9') ||
+ value[1] != '\0')
+ return (ARCHIVE_WARN);
+ data->compression_level = value[0] - '0';
+ return (ARCHIVE_OK);
+ }
+ return (ARCHIVE_WARN);
+}
+
+/*
+ * Write data to the compressed stream.
+ */
+static int
+archive_compressor_gzip_write(struct archive_write_filter *f, const void *buff,
+ size_t length)
+{
+ struct private_data *data = (struct private_data *)f->data;
+ int ret;
+
+ /* Update statistics */
+ data->crc = crc32(data->crc, (const Bytef *)buff, length);
+ data->total_in += length;
+
+ /* Compress input data to output buffer */
+ SET_NEXT_IN(data, buff);
+ data->stream.avail_in = length;
+ if ((ret = drive_compressor(f, data, 0)) != ARCHIVE_OK)
+ return (ret);
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Finish the compression...
+ */
+static int
+archive_compressor_gzip_close(struct archive_write_filter *f)
+{
+ unsigned char trailer[8];
+ struct private_data *data = (struct private_data *)f->data;
+ int ret, r1;
+
+ /* Finish compression cycle */
+ ret = drive_compressor(f, data, 1);
+ if (ret == ARCHIVE_OK) {
+ /* Write the last compressed data. */
+ ret = __archive_write_filter(f->next_filter,
+ data->compressed,
+ data->compressed_buffer_size - data->stream.avail_out);
+ }
+ if (ret == ARCHIVE_OK) {
+ /* Build and write out 8-byte trailer. */
+ trailer[0] = (data->crc)&0xff;
+ trailer[1] = (data->crc >> 8)&0xff;
+ trailer[2] = (data->crc >> 16)&0xff;
+ trailer[3] = (data->crc >> 24)&0xff;
+ trailer[4] = (data->total_in)&0xff;
+ trailer[5] = (data->total_in >> 8)&0xff;
+ trailer[6] = (data->total_in >> 16)&0xff;
+ trailer[7] = (data->total_in >> 24)&0xff;
+ ret = __archive_write_filter(f->next_filter, trailer, 8);
+ }
+
+ switch (deflateEnd(&(data->stream))) {
+ case Z_OK:
+ break;
+ default:
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "Failed to clean up compressor");
+ ret = ARCHIVE_FATAL;
+ }
+ r1 = __archive_write_close_filter(f->next_filter);
+ return (r1 < ret ? r1 : ret);
+}
+
+static int
+archive_compressor_gzip_free(struct archive_write_filter *f)
+{
+ struct private_data *data = (struct private_data *)f->data;
+ free(data->compressed);
+ free(data);
+ f->data = NULL;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Utility function to push input data through compressor,
+ * writing full output blocks as necessary.
+ *
+ * Note that this handles both the regular write case (finishing ==
+ * false) and the end-of-archive case (finishing == true).
+ */
+static int
+drive_compressor(struct archive_write_filter *f,
+ struct private_data *data, int finishing)
+{
+ int ret;
+
+ for (;;) {
+ if (data->stream.avail_out == 0) {
+ ret = __archive_write_filter(f->next_filter,
+ data->compressed,
+ data->compressed_buffer_size);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ data->stream.next_out = data->compressed;
+ data->stream.avail_out = data->compressed_buffer_size;
+ }
+
+ /* If there's nothing to do, we're done. */
+ if (!finishing && data->stream.avail_in == 0)
+ return (ARCHIVE_OK);
+
+ ret = deflate(&(data->stream),
+ finishing ? Z_FINISH : Z_NO_FLUSH );
+
+ switch (ret) {
+ case Z_OK:
+ /* In non-finishing case, check if compressor
+ * consumed everything */
+ if (!finishing && data->stream.avail_in == 0)
+ return (ARCHIVE_OK);
+ /* In finishing case, this return always means
+ * there's more work */
+ break;
+ case Z_STREAM_END:
+ /* This return can only occur in finishing case. */
+ return (ARCHIVE_OK);
+ default:
+ /* Any other return value indicates an error. */
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "GZip compression failed:"
+ " deflate() call returned status %d",
+ ret);
+ return (ARCHIVE_FATAL);
+ }
+ }
+}
+
+#endif /* HAVE_ZLIB_H */
diff --git a/libarchive/archive_write_add_filter_none.c b/libarchive/archive_write_add_filter_none.c
new file mode 100644
index 000000000000..3c06c642e735
--- /dev/null
+++ b/libarchive/archive_write_add_filter_none.c
@@ -0,0 +1,43 @@
+/*-
+ * Copyright (c) 2003-2010 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_none.c 201080 2009-12-28 02:03:54Z kientzle $");
+
+#include "archive.h"
+
+int
+archive_write_set_compression_none(struct archive *a)
+{
+ (void)a; /* UNUSED */
+ return (ARCHIVE_OK);
+}
+
+int
+archive_write_add_filter_none(struct archive *a)
+{
+ (void)a; /* UNUSED */
+ return (ARCHIVE_OK);
+}
diff --git a/libarchive/archive_write_add_filter_program.c b/libarchive/archive_write_add_filter_program.c
new file mode 100644
index 000000000000..3dcc9df7bcca
--- /dev/null
+++ b/libarchive/archive_write_add_filter_program.c
@@ -0,0 +1,327 @@
+/*-
+ * Copyright (c) 2007 Joerg Sonnenberger
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_program.c 201104 2009-12-28 03:14:30Z kientzle $");
+
+#ifdef HAVE_SYS_WAIT_H
+# include <sys/wait.h>
+#endif
+#ifdef HAVE_ERRNO_H
+# include <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+#ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif
+
+#include "archive.h"
+#include "archive_private.h"
+#include "archive_write_private.h"
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+int
+archive_write_set_compression_program(struct archive *a, const char *cmd)
+{
+ __archive_write_filters_free(a);
+ return (archive_write_add_filter_program(a, cmd));
+}
+#endif
+
+/* This capability is only available on POSIX systems. */
+#if (!defined(HAVE_PIPE) || !defined(HAVE_FCNTL) || \
+ !(defined(HAVE_FORK) || defined(HAVE_VFORK))) && (!defined(_WIN32) || defined(__CYGWIN__))
+
+/*
+ * On non-Posix systems, allow the program to build, but choke if
+ * this function is actually invoked.
+ */
+int
+archive_write_add_filter_program(struct archive *_a, const char *cmd)
+{
+ archive_set_error(_a, -1,
+ "External compression programs not supported on this platform");
+ return (ARCHIVE_FATAL);
+}
+
+#else
+
+#include "filter_fork.h"
+
+struct private_data {
+ char *cmd;
+ char *description;
+ pid_t child;
+ int child_stdin, child_stdout;
+
+ char *child_buf;
+ size_t child_buf_len, child_buf_avail;
+};
+
+static int archive_compressor_program_open(struct archive_write_filter *);
+static int archive_compressor_program_write(struct archive_write_filter *,
+ const void *, size_t);
+static int archive_compressor_program_close(struct archive_write_filter *);
+static int archive_compressor_program_free(struct archive_write_filter *);
+
+/*
+ * Add a filter to this write handle that passes all data through an
+ * external program.
+ */
+int
+archive_write_add_filter_program(struct archive *_a, const char *cmd)
+{
+ struct archive_write_filter *f = __archive_write_allocate_filter(_a);
+ struct archive_write *a = (struct archive_write *)_a;
+ struct private_data *data;
+ static const char *prefix = "Program: ";
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_add_filter_program");
+ data = calloc(1, sizeof(*data));
+ if (data == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+ data->cmd = strdup(cmd);
+ data->description = (char *)malloc(strlen(prefix) + strlen(cmd) + 1);
+ strcpy(data->description, prefix);
+ strcat(data->description, cmd);
+
+ f->name = data->description;
+ f->data = data;
+ f->open = &archive_compressor_program_open;
+ f->code = ARCHIVE_COMPRESSION_PROGRAM;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Setup callback.
+ */
+static int
+archive_compressor_program_open(struct archive_write_filter *f)
+{
+ struct private_data *data = (struct private_data *)f->data;
+ int ret;
+
+ ret = __archive_write_open_filter(f->next_filter);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+
+ if (data->child_buf == NULL) {
+ data->child_buf_len = 65536;
+ data->child_buf_avail = 0;
+ data->child_buf = malloc(data->child_buf_len);
+
+ if (data->child_buf == NULL) {
+ archive_set_error(f->archive, ENOMEM,
+ "Can't allocate compression buffer");
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ if ((data->child = __archive_create_child(data->cmd,
+ &data->child_stdin, &data->child_stdout)) == -1) {
+ archive_set_error(f->archive, EINVAL,
+ "Can't initialise filter");
+ return (ARCHIVE_FATAL);
+ }
+
+ f->write = archive_compressor_program_write;
+ f->close = archive_compressor_program_close;
+ f->free = archive_compressor_program_free;
+ return (0);
+}
+
+static ssize_t
+child_write(struct archive_write_filter *f, const char *buf, size_t buf_len)
+{
+ struct private_data *data = f->data;
+ ssize_t ret;
+
+ if (data->child_stdin == -1)
+ return (-1);
+
+ if (buf_len == 0)
+ return (-1);
+
+restart_write:
+ do {
+ ret = write(data->child_stdin, buf, buf_len);
+ } while (ret == -1 && errno == EINTR);
+
+ if (ret > 0)
+ return (ret);
+ if (ret == 0) {
+ close(data->child_stdin);
+ data->child_stdin = -1;
+ fcntl(data->child_stdout, F_SETFL, 0);
+ return (0);
+ }
+ if (ret == -1 && errno != EAGAIN)
+ return (-1);
+
+ if (data->child_stdout == -1) {
+ fcntl(data->child_stdin, F_SETFL, 0);
+ __archive_check_child(data->child_stdin, data->child_stdout);
+ goto restart_write;
+ }
+
+ do {
+ ret = read(data->child_stdout,
+ data->child_buf + data->child_buf_avail,
+ data->child_buf_len - data->child_buf_avail);
+ } while (ret == -1 && errno == EINTR);
+
+ if (ret == 0 || (ret == -1 && errno == EPIPE)) {
+ close(data->child_stdout);
+ data->child_stdout = -1;
+ fcntl(data->child_stdin, F_SETFL, 0);
+ goto restart_write;
+ }
+ if (ret == -1 && errno == EAGAIN) {
+ __archive_check_child(data->child_stdin, data->child_stdout);
+ goto restart_write;
+ }
+ if (ret == -1)
+ return (-1);
+
+ data->child_buf_avail += ret;
+
+ ret = __archive_write_filter(f->next_filter,
+ data->child_buf, data->child_buf_avail);
+ if (ret <= 0)
+ return (-1);
+
+ if ((size_t)ret < data->child_buf_avail) {
+ memmove(data->child_buf, data->child_buf + ret,
+ data->child_buf_avail - ret);
+ }
+ data->child_buf_avail -= ret;
+ goto restart_write;
+}
+
+/*
+ * Write data to the compressed stream.
+ */
+static int
+archive_compressor_program_write(struct archive_write_filter *f,
+ const void *buff, size_t length)
+{
+ ssize_t ret;
+ const char *buf;
+
+ buf = buff;
+ while (length > 0) {
+ ret = child_write(f, buf, length);
+ if (ret == -1 || ret == 0) {
+ archive_set_error(f->archive, EIO,
+ "Can't write to filter");
+ return (ARCHIVE_FATAL);
+ }
+ length -= ret;
+ buf += ret;
+ }
+ return (ARCHIVE_OK);
+}
+
+
+/*
+ * Finish the compression...
+ */
+static int
+archive_compressor_program_close(struct archive_write_filter *f)
+{
+ struct private_data *data = (struct private_data *)f->data;
+ int ret, r1, status;
+ ssize_t bytes_read;
+
+ ret = 0;
+ close(data->child_stdin);
+ data->child_stdin = -1;
+ fcntl(data->child_stdout, F_SETFL, 0);
+
+ for (;;) {
+ do {
+ bytes_read = read(data->child_stdout,
+ data->child_buf + data->child_buf_avail,
+ data->child_buf_len - data->child_buf_avail);
+ } while (bytes_read == -1 && errno == EINTR);
+
+ if (bytes_read == 0 || (bytes_read == -1 && errno == EPIPE))
+ break;
+
+ if (bytes_read == -1) {
+ archive_set_error(f->archive, errno,
+ "Read from filter failed unexpectedly.");
+ ret = ARCHIVE_FATAL;
+ goto cleanup;
+ }
+ data->child_buf_avail += bytes_read;
+
+ ret = __archive_write_filter(f->next_filter,
+ data->child_buf, data->child_buf_avail);
+ if (ret != ARCHIVE_OK) {
+ ret = ARCHIVE_FATAL;
+ goto cleanup;
+ }
+ data->child_buf_avail = 0;
+ }
+
+cleanup:
+ /* Shut down the child. */
+ if (data->child_stdin != -1)
+ close(data->child_stdin);
+ if (data->child_stdout != -1)
+ close(data->child_stdout);
+ while (waitpid(data->child, &status, 0) == -1 && errno == EINTR)
+ continue;
+
+ if (status != 0) {
+ archive_set_error(f->archive, EIO,
+ "Filter exited with failure.");
+ ret = ARCHIVE_FATAL;
+ }
+ r1 = __archive_write_close_filter(f->next_filter);
+ return (r1 < ret ? r1 : ret);
+}
+
+static int
+archive_compressor_program_free(struct archive_write_filter *f)
+{
+ struct private_data *data = (struct private_data *)f->data;
+ free(data->cmd);
+ free(data->description);
+ free(data->child_buf);
+ free(data);
+ f->data = NULL;
+ return (ARCHIVE_OK);
+}
+
+#endif /* !defined(HAVE_PIPE) || !defined(HAVE_VFORK) || !defined(HAVE_FCNTL) */
diff --git a/libarchive/archive_write_add_filter_xz.c b/libarchive/archive_write_add_filter_xz.c
new file mode 100644
index 000000000000..b0677522455f
--- /dev/null
+++ b/libarchive/archive_write_add_filter_xz.c
@@ -0,0 +1,502 @@
+/*-
+ * Copyright (c) 2009,2010 Michihiro NAKAJIMA
+ * Copyright (c) 2003-2010 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+
+__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_xz.c 201108 2009-12-28 03:28:21Z kientzle $");
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#include <time.h>
+#ifdef HAVE_LZMA_H
+#include <lzma.h>
+#endif
+
+#include "archive.h"
+#include "archive_endian.h"
+#include "archive_private.h"
+#include "archive_write_private.h"
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+int
+archive_write_set_compression_lzip(struct archive *a)
+{
+ __archive_write_filters_free(a);
+ return (archive_write_add_filter_lzip(a));
+}
+
+int
+archive_write_set_compression_lzma(struct archive *a)
+{
+ __archive_write_filters_free(a);
+ return (archive_write_add_filter_lzma(a));
+}
+
+int
+archive_write_set_compression_xz(struct archive *a)
+{
+ __archive_write_filters_free(a);
+ return (archive_write_add_filter_xz(a));
+}
+
+#endif
+
+#ifndef HAVE_LZMA_H
+int
+archive_write_add_filter_xz(struct archive *a)
+{
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "xz compression not supported on this platform");
+ return (ARCHIVE_FATAL);
+}
+
+int
+archive_write_add_filter_lzma(struct archive *a)
+{
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "lzma compression not supported on this platform");
+ return (ARCHIVE_FATAL);
+}
+
+int
+archive_write_add_filter_lzip(struct archive *a)
+{
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "lzma compression not supported on this platform");
+ return (ARCHIVE_FATAL);
+}
+#else
+/* Don't compile this if we don't have liblzma. */
+
+struct private_data {
+ int compression_level;
+ lzma_stream stream;
+ lzma_filter lzmafilters[2];
+ lzma_options_lzma lzma_opt;
+ int64_t total_in;
+ unsigned char *compressed;
+ size_t compressed_buffer_size;
+ int64_t total_out;
+ /* the CRC32 value of uncompressed data for lzip */
+ uint32_t crc32;
+};
+
+static int archive_compressor_xz_options(struct archive_write_filter *,
+ const char *, const char *);
+static int archive_compressor_xz_open(struct archive_write_filter *);
+static int archive_compressor_xz_write(struct archive_write_filter *,
+ const void *, size_t);
+static int archive_compressor_xz_close(struct archive_write_filter *);
+static int archive_compressor_xz_free(struct archive_write_filter *);
+static int drive_compressor(struct archive_write_filter *,
+ struct private_data *, int finishing);
+
+struct option_value {
+ uint32_t dict_size;
+ uint32_t nice_len;
+ lzma_match_finder mf;
+};
+static const struct option_value option_values[] = {
+ { 1 << 16, 32, LZMA_MF_HC3},
+ { 1 << 20, 32, LZMA_MF_HC3},
+ { 3 << 19, 32, LZMA_MF_HC4},
+ { 1 << 21, 32, LZMA_MF_BT4},
+ { 3 << 20, 32, LZMA_MF_BT4},
+ { 1 << 22, 32, LZMA_MF_BT4},
+ { 1 << 23, 64, LZMA_MF_BT4},
+ { 1 << 24, 64, LZMA_MF_BT4},
+ { 3 << 23, 64, LZMA_MF_BT4},
+ { 1 << 25, 64, LZMA_MF_BT4}
+};
+
+static int
+common_setup(struct archive_write_filter *f)
+{
+ struct private_data *data;
+ struct archive_write *a = (struct archive_write *)f->archive;
+ data = calloc(1, sizeof(*data));
+ if (data == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+ f->data = data;
+ data->compression_level = LZMA_PRESET_DEFAULT;
+ f->open = &archive_compressor_xz_open;
+ f->close = archive_compressor_xz_close;
+ f->free = archive_compressor_xz_free;
+ f->options = &archive_compressor_xz_options;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Add an xz compression filter to this write handle.
+ */
+int
+archive_write_add_filter_xz(struct archive *_a)
+{
+ struct archive_write_filter *f;
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_add_filter_xz");
+ f = __archive_write_allocate_filter(_a);
+ r = common_setup(f);
+ if (r == ARCHIVE_OK) {
+ f->code = ARCHIVE_COMPRESSION_XZ;
+ f->name = "xz";
+ }
+ return (r);
+}
+
+/* LZMA is handled identically, we just need a different compression
+ * code set. (The liblzma setup looks at the code to determine
+ * the one place that XZ and LZMA require different handling.) */
+int
+archive_write_add_filter_lzma(struct archive *_a)
+{
+ struct archive_write_filter *f;
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_add_filter_lzma");
+ f = __archive_write_allocate_filter(_a);
+ r = common_setup(f);
+ if (r == ARCHIVE_OK) {
+ f->code = ARCHIVE_COMPRESSION_LZMA;
+ f->name = "lzma";
+ }
+ return (r);
+}
+
+int
+archive_write_add_filter_lzip(struct archive *_a)
+{
+ struct archive_write_filter *f;
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_add_filter_lzip");
+ f = __archive_write_allocate_filter(_a);
+ r = common_setup(f);
+ if (r == ARCHIVE_OK) {
+ f->code = ARCHIVE_COMPRESSION_LZIP;
+ f->name = "lzip";
+ }
+ return (r);
+}
+
+static int
+archive_compressor_xz_init_stream(struct archive_write_filter *f,
+ struct private_data *data)
+{
+ static const lzma_stream lzma_stream_init_data = LZMA_STREAM_INIT;
+ int ret;
+
+ data->stream = lzma_stream_init_data;
+ data->stream.next_out = data->compressed;
+ data->stream.avail_out = data->compressed_buffer_size;
+ if (f->code == ARCHIVE_COMPRESSION_XZ)
+ ret = lzma_stream_encoder(&(data->stream),
+ data->lzmafilters, LZMA_CHECK_CRC64);
+ else if (f->code == ARCHIVE_COMPRESSION_LZMA)
+ ret = lzma_alone_encoder(&(data->stream), &data->lzma_opt);
+ else { /* ARCHIVE_COMPRESSION_LZIP */
+ int dict_size = data->lzma_opt.dict_size;
+ int ds, log2dic, wedges;
+
+ /* Calculate a coded dictionary size */
+ if (dict_size < (1 << 12) || dict_size > (1 << 27)) {
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "Unacceptable dictionary dize for lzip: %d",
+ dict_size);
+ return (ARCHIVE_FATAL);
+ }
+ for (log2dic = 27; log2dic >= 12; log2dic--) {
+ if (dict_size & (1 << log2dic))
+ break;
+ }
+ if (dict_size > (1 << log2dic)) {
+ log2dic++;
+ wedges =
+ ((1 << log2dic) - dict_size) / (1 << (log2dic - 4));
+ } else
+ wedges = 0;
+ ds = ((wedges << 5) & 0xe0) | (log2dic & 0x1f);
+
+ data->crc32 = 0;
+ /* Make a header */
+ data->compressed[0] = 0x4C;
+ data->compressed[1] = 0x5A;
+ data->compressed[2] = 0x49;
+ data->compressed[3] = 0x50;
+ data->compressed[4] = 1;/* Version */
+ data->compressed[5] = (unsigned char)ds;
+ data->stream.next_out += 6;
+ data->stream.avail_out -= 6;
+
+ ret = lzma_raw_encoder(&(data->stream), data->lzmafilters);
+ }
+ if (ret == LZMA_OK)
+ return (ARCHIVE_OK);
+
+ switch (ret) {
+ case LZMA_MEM_ERROR:
+ archive_set_error(f->archive, ENOMEM,
+ "Internal error initializing compression library: "
+ "Cannot allocate memory");
+ break;
+ default:
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "Internal error initializing compression library: "
+ "It's a bug in liblzma");
+ break;
+ }
+ return (ARCHIVE_FATAL);
+}
+
+/*
+ * Setup callback.
+ */
+static int
+archive_compressor_xz_open(struct archive_write_filter *f)
+{
+ struct private_data *data = f->data;
+ int ret;
+
+ ret = __archive_write_open_filter(f->next_filter);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+
+ if (data->compressed == NULL) {
+ data->compressed_buffer_size = 65536;
+ data->compressed
+ = (unsigned char *)malloc(data->compressed_buffer_size);
+ if (data->compressed == NULL) {
+ archive_set_error(f->archive, ENOMEM,
+ "Can't allocate data for compression buffer");
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ f->write = archive_compressor_xz_write;
+
+ /* Initialize compression library. */
+ if (f->code == ARCHIVE_COMPRESSION_LZIP) {
+ const struct option_value *val =
+ &option_values[data->compression_level];
+
+ data->lzma_opt.dict_size = val->dict_size;
+ data->lzma_opt.preset_dict = NULL;
+ data->lzma_opt.preset_dict_size = 0;
+ data->lzma_opt.lc = LZMA_LC_DEFAULT;
+ data->lzma_opt.lp = LZMA_LP_DEFAULT;
+ data->lzma_opt.pb = LZMA_PB_DEFAULT;
+ data->lzma_opt.mode =
+ data->compression_level<= 2? LZMA_MODE_FAST:LZMA_MODE_NORMAL;
+ data->lzma_opt.nice_len = val->nice_len;
+ data->lzma_opt.mf = val->mf;
+ data->lzma_opt.depth = 0;
+ data->lzmafilters[0].id = LZMA_FILTER_LZMA1;
+ data->lzmafilters[0].options = &data->lzma_opt;
+ data->lzmafilters[1].id = LZMA_VLI_UNKNOWN;/* Terminate */
+ } else {
+ if (lzma_lzma_preset(&data->lzma_opt, data->compression_level)) {
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "Internal error initializing compression library");
+ }
+ data->lzmafilters[0].id = LZMA_FILTER_LZMA2;
+ data->lzmafilters[0].options = &data->lzma_opt;
+ data->lzmafilters[1].id = LZMA_VLI_UNKNOWN;/* Terminate */
+ }
+ ret = archive_compressor_xz_init_stream(f, data);
+ if (ret == LZMA_OK) {
+ f->data = data;
+ return (0);
+ }
+ return (ARCHIVE_FATAL);
+}
+
+/*
+ * Set write options.
+ */
+static int
+archive_compressor_xz_options(struct archive_write_filter *f,
+ const char *key, const char *value)
+{
+ struct private_data *data = (struct private_data *)f->data;
+
+ if (strcmp(key, "compression-level") == 0) {
+ if (value == NULL || !(value[0] >= '0' && value[0] <= '9') ||
+ value[1] != '\0')
+ return (ARCHIVE_WARN);
+ data->compression_level = value[0] - '0';
+ if (data->compression_level > 6)
+ data->compression_level = 6;
+ return (ARCHIVE_OK);
+ }
+
+ return (ARCHIVE_WARN);
+}
+
+/*
+ * Write data to the compressed stream.
+ */
+static int
+archive_compressor_xz_write(struct archive_write_filter *f,
+ const void *buff, size_t length)
+{
+ struct private_data *data = (struct private_data *)f->data;
+ int ret;
+
+ /* Update statistics */
+ data->total_in += length;
+ if (f->code == ARCHIVE_COMPRESSION_LZIP)
+ data->crc32 = lzma_crc32(buff, length, data->crc32);
+
+ /* Compress input data to output buffer */
+ data->stream.next_in = buff;
+ data->stream.avail_in = length;
+ if ((ret = drive_compressor(f, data, 0)) != ARCHIVE_OK)
+ return (ret);
+
+ return (ARCHIVE_OK);
+}
+
+
+/*
+ * Finish the compression...
+ */
+static int
+archive_compressor_xz_close(struct archive_write_filter *f)
+{
+ struct private_data *data = (struct private_data *)f->data;
+ int ret, r1;
+
+ ret = drive_compressor(f, data, 1);
+ if (ret == ARCHIVE_OK) {
+ data->total_out +=
+ data->compressed_buffer_size - data->stream.avail_out;
+ ret = __archive_write_filter(f->next_filter,
+ data->compressed,
+ data->compressed_buffer_size - data->stream.avail_out);
+ if (f->code == ARCHIVE_COMPRESSION_LZIP && ret == ARCHIVE_OK) {
+ archive_le32enc(data->compressed, data->crc32);
+ archive_le64enc(data->compressed+4, data->total_in);
+ archive_le64enc(data->compressed+12, data->total_out + 20);
+ ret = __archive_write_filter(f->next_filter,
+ data->compressed, 20);
+ }
+ }
+ lzma_end(&(data->stream));
+ r1 = __archive_write_close_filter(f->next_filter);
+ return (r1 < ret ? r1 : ret);
+}
+
+static int
+archive_compressor_xz_free(struct archive_write_filter *f)
+{
+ struct private_data *data = (struct private_data *)f->data;
+ free(data->compressed);
+ free(data);
+ f->data = NULL;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Utility function to push input data through compressor,
+ * writing full output blocks as necessary.
+ *
+ * Note that this handles both the regular write case (finishing ==
+ * false) and the end-of-archive case (finishing == true).
+ */
+static int
+drive_compressor(struct archive_write_filter *f,
+ struct private_data *data, int finishing)
+{
+ int ret;
+
+ for (;;) {
+ if (data->stream.avail_out == 0) {
+ data->total_out += data->compressed_buffer_size;
+ ret = __archive_write_filter(f->next_filter,
+ data->compressed,
+ data->compressed_buffer_size);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ data->stream.next_out = data->compressed;
+ data->stream.avail_out = data->compressed_buffer_size;
+ }
+
+ /* If there's nothing to do, we're done. */
+ if (!finishing && data->stream.avail_in == 0)
+ return (ARCHIVE_OK);
+
+ ret = lzma_code(&(data->stream),
+ finishing ? LZMA_FINISH : LZMA_RUN );
+
+ switch (ret) {
+ case LZMA_OK:
+ /* In non-finishing case, check if compressor
+ * consumed everything */
+ if (!finishing && data->stream.avail_in == 0)
+ return (ARCHIVE_OK);
+ /* In finishing case, this return always means
+ * there's more work */
+ break;
+ case LZMA_STREAM_END:
+ /* This return can only occur in finishing case. */
+ if (finishing)
+ return (ARCHIVE_OK);
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "lzma compression data error");
+ return (ARCHIVE_FATAL);
+ case LZMA_MEMLIMIT_ERROR:
+ archive_set_error(f->archive, ENOMEM,
+ "lzma compression error: "
+ "%ju MiB would have been needed",
+ (uintmax_t)((lzma_memusage(&(data->stream))
+ + 1024 * 1024 -1)
+ / (1024 * 1024)));
+ return (ARCHIVE_FATAL);
+ default:
+ /* Any other return value indicates an error. */
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "lzma compression failed:"
+ " lzma_code() call returned status %d",
+ ret);
+ return (ARCHIVE_FATAL);
+ }
+ }
+}
+
+#endif /* HAVE_LZMA_H */
diff --git a/libarchive/archive_write_blocksize.3 b/libarchive/archive_write_blocksize.3
new file mode 100644
index 000000000000..96c75382ade0
--- /dev/null
+++ b/libarchive/archive_write_blocksize.3
@@ -0,0 +1,112 @@
+.\" Copyright (c) 2003-2011 Tim Kientzle
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd March 23, 2011
+.Dt ARCHIVE_WRITE_BLOCKSIZE 3
+.Os
+.Sh NAME
+.Nm archive_write_get_bytes_per_block ,
+.Nm archive_write_set_bytes_per_block ,
+.Nm archive_write_get_bytes_in_last_block ,
+.Nm archive_write_set_bytes_in_last_block
+.Nd functions for creating archives
+.Sh SYNOPSIS
+.In archive.h
+.Ft int
+.Fn archive_write_get_bytes_per_block "struct archive *"
+.Ft int
+.Fn archive_write_set_bytes_per_block "struct archive *" "int bytes_per_block"
+.Ft int
+.Fn archive_write_get_bytes_in_last_block "struct archive *"
+.Ft int
+.Fn archive_write_set_bytes_in_last_block "struct archive *" "int"
+.Sh DESCRIPTION
+.Bl -tag -width indent
+.It Fn archive_write_set_bytes_per_block
+Sets the block size used for writing the archive data.
+Every call to the write callback function, except possibly the last one, will
+use this value for the length.
+The default is to use a block size of 10240 bytes.
+Note that a block size of zero will suppress internal blocking
+and cause writes to be sent directly to the write callback as they occur.
+.It Fn archive_write_get_bytes_per_block
+Retrieve the block size to be used for writing.
+A value of -1 here indicates that the library should use default values.
+A value of zero indicates that internal blocking is suppressed.
+.It Fn archive_write_set_bytes_in_last_block
+Sets the block size used for writing the last block.
+If this value is zero, the last block will be padded to the same size
+as the other blocks.
+Otherwise, the final block will be padded to a multiple of this size.
+In particular, setting it to 1 will cause the final block to not be padded.
+For compressed output, any padding generated by this option
+is applied only after the compression.
+The uncompressed data is always unpadded.
+The default is to pad the last block to the full block size (note that
+.Fn archive_write_open_filename
+will set this based on the file type).
+Unlike the other
+.Dq set
+functions, this function can be called after the archive is opened.
+.It Fn archive_write_get_bytes_in_last_block
+Retrieve the currently-set value for last block size.
+A value of -1 here indicates that the library should use default values.
+.El
+.\" .Sh EXAMPLE
+.Sh RETURN VALUES
+.Fn archive_write_set_bytes_per_block
+and
+.Fn archive_write_set_bytes_in_last_block
+return
+.Cm ARCHIVE_OK
+on success, or
+.Cm ARCHIVE_FATAL .
+.Pp
+.Fn archive_write_get_bytes_per_block
+and
+.Fn archive_write_get_bytes_in_last_block
+return currently configured block size
+.Po
+.Li -1
+indicates the default block size
+.Pc ,
+or
+.Cm ARCHIVE_FATAL .
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.\"
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_write_set_options 3 ,
+.Xr cpio 5 ,
+.Xr mtree 5 ,
+.Xr tar 5
diff --git a/libarchive/archive_write_data.3 b/libarchive/archive_write_data.3
new file mode 100644
index 000000000000..fc399bc3054b
--- /dev/null
+++ b/libarchive/archive_write_data.3
@@ -0,0 +1,60 @@
+.\" Copyright (c) 2003-2011 Tim Kientzle
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD: head/lib/libarchive/archive_write.3 201110 2009-12-28 03:31:29Z kientzle $
+.\"
+.Dd March 23, 2011
+.Dt ARCHIVE_WRITE 3
+.Os
+.Sh NAME
+.Nm archive_write_data
+.Nd functions for creating archives
+.Sh SYNOPSIS
+.In archive.h
+.Ft ssize_t
+.Fn archive_write_data "struct archive *" "const void *" "size_t"
+.Sh DESCRIPTION
+Write data corresponding to the header just written.
+.\" .Sh EXAMPLE
+.\"
+.Sh RETURN VALUES
+This function returns the number of bytes actually written, or
+.Li -1
+on error.
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.\"
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_write_finish_entry 3 ,
+.Xr archive_write_set_options 3 ,
+.Xr cpio 5 ,
+.Xr mtree 5 ,
+.Xr tar 5
diff --git a/libarchive/archive_write_disk.3 b/libarchive/archive_write_disk.3
index d7fed6d5ef27..ffadb04fee69 100644
--- a/libarchive/archive_write_disk.3
+++ b/libarchive/archive_write_disk.3
@@ -36,8 +36,10 @@
.Nm archive_write_disk_set_user_lookup ,
.Nm archive_write_header ,
.Nm archive_write_data ,
+.Nm archive_write_data_block ,
.Nm archive_write_finish_entry ,
.Nm archive_write_close ,
+.Nm archive_write_finish
.Nm archive_write_free
.Nd functions for creating objects on disk
.Sh SYNOPSIS
@@ -68,11 +70,15 @@
.Fn archive_write_header "struct archive *" "struct archive_entry *"
.Ft ssize_t
.Fn archive_write_data "struct archive *" "const void *" "size_t"
+.Ft ssize_t
+.Fn archive_write_data_block "struct archive *" "const void *" "size_t size" "int64_t offset"
.Ft int
.Fn archive_write_finish_entry "struct archive *"
.Ft int
.Fn archive_write_close "struct archive *"
.Ft int
+.Fn archive_write_finish "struct archive *"
+.Ft int
.Fn archive_write_free "struct archive *"
.Sh DESCRIPTION
These functions provide a complete API for creating objects on
@@ -221,6 +227,20 @@ objects.
.It Fn archive_write_data
Write data corresponding to the header just written.
Returns number of bytes written or -1 on error.
+.It Fn archive_write_data_block
+Write data corresponding to the header just written.
+This is like
+.Fn archive_write_data
+except that it performs a seek on the file being
+written to the specified offset before writing the data.
+This is useful when restoring sparse files from archive
+formats that support sparse files.
+Returns number of bytes written or -1 on error.
+(Note: This is currently not supported for
+.Tn archive_write
+handles, only for
+.Tn archive_write_disk
+handles.)
.It Fn archive_write_finish_entry
Close out the entry just written.
Ordinarily, clients never need to call this, as it
@@ -229,6 +249,9 @@ is called automatically by
and
.Fn archive_write_close
as needed.
+However, some file attributes are written to disk only
+after the file is closed, so this can be necessary
+if you need to work with the file on disk right away.
.It Fn archive_write_close
Set any attributes that could not be set during the initial restore.
For example, directory timestamps are not restored initially because
@@ -239,6 +262,9 @@ The
.Nm
library maintains a list of all such deferred attributes and
sets them when this function is invoked.
+.It Fn archive_write_finish
+This is a deprecated synonym for
+.Fn archive_write_free .
.It Fn archive_write_free
Invokes
.Fn archive_write_close
@@ -263,12 +289,6 @@ for operations that might succeed if retried,
for unusual conditions that do not prevent further operations, and
.Cm ARCHIVE_FATAL
for serious errors that make remaining operations impossible.
-The
-.Fn archive_errno
-and
-.Fn archive_error_string
-functions can be used to retrieve an appropriate error code and a
-textual error message.
.Pp
.Fn archive_write_disk_new
returns a pointer to a newly-allocated
@@ -276,12 +296,18 @@ returns a pointer to a newly-allocated
object.
.Pp
.Fn archive_write_data
-returns a count of the number of bytes actually written.
-On error, -1 is returned and the
+returns a count of the number of bytes actually written,
+or
+.Li -1
+on error.
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
.Fn archive_errno
and
.Fn archive_error_string
-functions will return appropriate values.
+functions.
+.\"
.Sh SEE ALSO
.Xr archive_read 3 ,
.Xr archive_write 3 ,
@@ -372,4 +398,4 @@ compact implementation when appropriate.
There should be a corresponding
.Nm archive_read_disk
interface that walks a directory hierarchy and returns archive
-entry objects. \ No newline at end of file
+entry objects.
diff --git a/libarchive/archive_write_disk.c b/libarchive/archive_write_disk_posix.c
index 6518807ba063..9937930dc901 100644
--- a/libarchive/archive_write_disk.c
+++ b/libarchive/archive_write_disk_posix.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2003-2010 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,9 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_disk.c 201159 2009-12-29 05:35:40Z kientzle $");
+__FBSDID("$FreeBSD$");
+
+#if !defined(_WIN32) || defined(__CYGWIN__)
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
@@ -39,6 +41,9 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_disk.c 201159 2009-12-29 0
#ifdef HAVE_SYS_XATTR_H
#include <sys/xattr.h>
#endif
+#ifdef HAVE_SYS_EA_H
+#include <sys/ea.h>
+#endif
#ifdef HAVE_ATTR_XATTR_H
#include <attr/xattr.h>
#endif
@@ -54,6 +59,9 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_disk.c 201159 2009-12-29 0
#ifdef HAVE_SYS_UTIME_H
#include <sys/utime.h>
#endif
+#ifdef HAVE_COPYFILE_H
+#include <copyfile.h>
+#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
@@ -63,6 +71,9 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_disk.c 201159 2009-12-29 0
#ifdef HAVE_GRP_H
#include <grp.h>
#endif
+#ifdef HAVE_LANGINFO_H
+#include <langinfo.h>
+#endif
#ifdef HAVE_LINUX_FS_H
#include <linux/fs.h> /* for Linux file flags */
#endif
@@ -95,8 +106,26 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_disk.c 201159 2009-12-29 0
#ifdef HAVE_UTIME_H
#include <utime.h>
#endif
+#ifdef F_GETTIMES /* Tru64 specific */
+#include <sys/fcntl1.h>
+#endif
+
+#if __APPLE__
+#include <TargetConditionals.h>
+#if TARGET_OS_MAC && !TARGET_OS_EMBEDDED && HAVE_QUARANTINE_H
+#include <quarantine.h>
+#define HAVE_QUARANTINE 1
+#endif
+#endif
+
+/* TODO: Support Mac OS 'quarantine' feature. This is really just a
+ * standard tag to mark files that have been downloaded as "tainted".
+ * On Mac OS, we should mark the extracted files as tainted if the
+ * archive being read was tainted. Windows has a similar feature; we
+ * should investigate ways to support this generically. */
#include "archive.h"
+#include "archive_acl_private.h"
#include "archive_string.h"
#include "archive_entry.h"
#include "archive_private.h"
@@ -107,14 +136,19 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_disk.c 201159 2009-12-29 0
struct fixup_entry {
struct fixup_entry *next;
+ struct archive_acl acl;
mode_t mode;
int64_t atime;
int64_t birthtime;
int64_t mtime;
+ int64_t ctime;
unsigned long atime_nanos;
unsigned long birthtime_nanos;
unsigned long mtime_nanos;
+ unsigned long ctime_nanos;
unsigned long fflags_set;
+ size_t mac_metadata_size;
+ void *mac_metadata;
int fixup; /* bitmask of what needs fixing */
char *name;
};
@@ -144,6 +178,7 @@ struct fixup_entry {
#define TODO_FFLAGS ARCHIVE_EXTRACT_FFLAGS
#define TODO_ACLS ARCHIVE_EXTRACT_ACL
#define TODO_XATTR ARCHIVE_EXTRACT_XATTR
+#define TODO_MAC_METADATA ARCHIVE_EXTRACT_MAC_METADATA
struct archive_write_disk {
struct archive archive;
@@ -151,15 +186,16 @@ struct archive_write_disk {
mode_t user_umask;
struct fixup_entry *fixup_list;
struct fixup_entry *current_fixup;
- uid_t user_uid;
+ int64_t user_uid;
+ int skip_file_set;
dev_t skip_file_dev;
ino_t skip_file_ino;
time_t start_time;
- gid_t (*lookup_gid)(void *private, const char *gname, gid_t gid);
+ int64_t (*lookup_gid)(void *private, const char *gname, int64_t gid);
void (*cleanup_gid)(void *private);
void *lookup_gid_data;
- uid_t (*lookup_uid)(void *private, const char *gname, gid_t gid);
+ int64_t (*lookup_uid)(void *private, const char *uname, int64_t uid);
void (*cleanup_uid)(void *private);
void *lookup_uid_data;
@@ -189,23 +225,25 @@ struct archive_write_disk {
/* Handle for the file we're restoring. */
int fd;
/* Current offset for writing data to the file. */
- off_t offset;
+ int64_t offset;
/* Last offset actually written to disk. */
- off_t fd_offset;
+ int64_t fd_offset;
+ /* Total bytes actually written to files. */
+ int64_t total_bytes_written;
/* Maximum size of file, -1 if unknown. */
- off_t filesize;
+ int64_t filesize;
/* Dir we were in before this restore; only for deep paths. */
int restore_pwd;
/* Mode we should use for this entry; affected by _PERM and umask. */
mode_t mode;
/* UID/GID to use in restoring this entry. */
- uid_t uid;
- gid_t gid;
+ int64_t uid;
+ int64_t gid;
};
/*
* Default mode for dirs created automatically (will be modified by umask).
- * Note that POSIX specifies 0777 for implicity-created dirs, "modified
+ * Note that POSIX specifies 0777 for implicitly-created dirs, "modified
* by the process' file creation mask."
*/
#define DEFAULT_DIR_MODE 0777
@@ -221,7 +259,7 @@ struct archive_write_disk {
static int check_symlinks(struct archive_write_disk *);
static int create_filesystem_object(struct archive_write_disk *);
static struct fixup_entry *current_fixup(struct archive_write_disk *, const char *pathname);
-#ifdef HAVE_FCHDIR
+#if defined(HAVE_FCHDIR) && defined(PATH_MAX)
static void edit_deep_directories(struct archive_write_disk *ad);
#endif
static int cleanup_pathname(struct archive_write_disk *);
@@ -230,10 +268,12 @@ static int create_parent_dir(struct archive_write_disk *, char *);
static int older(struct stat *, struct archive_entry *);
static int restore_entry(struct archive_write_disk *);
#ifdef HAVE_POSIX_ACL
-static int set_acl(struct archive_write_disk *, int fd, struct archive_entry *,
+static int set_acl(struct archive_write_disk *, int fd, const char *, struct archive_acl *,
acl_type_t, int archive_entry_acl_type, const char *tn);
#endif
-static int set_acls(struct archive_write_disk *);
+static int set_acls(struct archive_write_disk *, int fd, const char *, struct archive_acl *);
+static int set_mac_metadata(struct archive_write_disk *, const char *,
+ const void *, size_t);
static int set_xattrs(struct archive_write_disk *);
static int set_fflags(struct archive_write_disk *);
static int set_fflags_platform(struct archive_write_disk *, int fd,
@@ -242,24 +282,25 @@ static int set_fflags_platform(struct archive_write_disk *, int fd,
static int set_ownership(struct archive_write_disk *);
static int set_mode(struct archive_write_disk *, int mode);
static int set_time(int, int, const char *, time_t, long, time_t, long);
-static int set_times(struct archive_write_disk *);
+static int set_times(struct archive_write_disk *, int, int, const char *,
+ time_t, long, time_t, long, time_t, long, time_t, long);
+static int set_times_from_entry(struct archive_write_disk *);
static struct fixup_entry *sort_dir_list(struct fixup_entry *p);
-static gid_t trivial_lookup_gid(void *, const char *, gid_t);
-static uid_t trivial_lookup_uid(void *, const char *, uid_t);
static ssize_t write_data_block(struct archive_write_disk *,
const char *, size_t);
static struct archive_vtable *archive_write_disk_vtable(void);
-static int _archive_write_close(struct archive *);
-static int _archive_write_free(struct archive *);
-static int _archive_write_header(struct archive *, struct archive_entry *);
-static int _archive_write_finish_entry(struct archive *);
-static ssize_t _archive_write_data(struct archive *, const void *, size_t);
-static ssize_t _archive_write_data_block(struct archive *, const void *, size_t, off_t);
+static int _archive_write_disk_close(struct archive *);
+static int _archive_write_disk_free(struct archive *);
+static int _archive_write_disk_header(struct archive *, struct archive_entry *);
+static int64_t _archive_write_disk_filter_bytes(struct archive *, int);
+static int _archive_write_disk_finish_entry(struct archive *);
+static ssize_t _archive_write_disk_data(struct archive *, const void *, size_t);
+static ssize_t _archive_write_disk_data_block(struct archive *, const void *, size_t, int64_t);
static int
-_archive_write_disk_lazy_stat(struct archive_write_disk *a)
+lazy_stat(struct archive_write_disk *a)
{
if (a->pst != NULL) {
/* Already have stat() data available. */
@@ -273,7 +314,7 @@ _archive_write_disk_lazy_stat(struct archive_write_disk *a)
#endif
/*
* XXX At this point, symlinks should not be hit, otherwise
- * XXX a race occured. Do we want to check explicitly for that?
+ * XXX a race occurred. Do we want to check explicitly for that?
*/
if (lstat(a->name, &a->st) == 0) {
a->pst = &a->st;
@@ -290,16 +331,29 @@ archive_write_disk_vtable(void)
static int inited = 0;
if (!inited) {
- av.archive_close = _archive_write_close;
- av.archive_free = _archive_write_free;
- av.archive_write_header = _archive_write_header;
- av.archive_write_finish_entry = _archive_write_finish_entry;
- av.archive_write_data = _archive_write_data;
- av.archive_write_data_block = _archive_write_data_block;
+ av.archive_close = _archive_write_disk_close;
+ av.archive_filter_bytes = _archive_write_disk_filter_bytes;
+ av.archive_free = _archive_write_disk_free;
+ av.archive_write_header = _archive_write_disk_header;
+ av.archive_write_finish_entry
+ = _archive_write_disk_finish_entry;
+ av.archive_write_data = _archive_write_disk_data;
+ av.archive_write_data_block = _archive_write_disk_data_block;
+ inited = 1;
}
return (&av);
}
+static int64_t
+_archive_write_disk_filter_bytes(struct archive *_a, int n)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ (void)n; /* UNUSED */
+ if (n == -1 || n == 0)
+ return (a->total_bytes_written);
+ return (-1);
+}
+
int
archive_write_disk_set_options(struct archive *_a, int flags)
@@ -323,18 +377,18 @@ archive_write_disk_set_options(struct archive *_a, int flags)
*
*/
static int
-_archive_write_header(struct archive *_a, struct archive_entry *entry)
+_archive_write_disk_header(struct archive *_a, struct archive_entry *entry)
{
struct archive_write_disk *a = (struct archive_write_disk *)_a;
struct fixup_entry *fe;
int ret, r;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
"archive_write_disk_header");
archive_clear_error(&a->archive);
if (a->archive.state & ARCHIVE_STATE_DATA) {
- r = _archive_write_finish_entry(&a->archive);
+ r = _archive_write_disk_finish_entry(&a->archive);
if (r == ARCHIVE_FATAL)
return (r);
}
@@ -351,6 +405,7 @@ _archive_write_header(struct archive *_a, struct archive_entry *entry)
a->fd = -1;
a->fd_offset = 0;
a->offset = 0;
+ a->restore_pwd = -1;
a->uid = a->user_uid;
a->mode = archive_entry_mode(a->entry);
if (archive_entry_size_is_set(a->entry))
@@ -371,15 +426,12 @@ _archive_write_header(struct archive *_a, struct archive_entry *entry)
return (ret);
/*
- * Set the umask to zero so we get predictable mode settings.
+ * Query the umask so we get predictable mode settings.
* This gets done on every call to _write_header in case the
* user edits their umask during the extraction for some
- * reason. This will be reset before we return. Note that we
- * don't need to do this in _finish_entry, as the chmod(), etc,
- * system calls don't obey umask.
+ * reason.
*/
- a->user_umask = umask(0);
- /* From here on, early exit requires "goto done" to clean up. */
+ umask(a->user_umask = umask(0));
/* Figure out what we need to do for this entry. */
a->todo = TODO_MODE_BASE;
@@ -417,14 +469,22 @@ _archive_write_header(struct archive *_a, struct archive_entry *entry)
a->mode &= ~S_ISVTX;
a->mode &= ~a->user_umask;
}
-#if !defined(_WIN32) || defined(__CYGWIN__)
if (a->flags & ARCHIVE_EXTRACT_OWNER)
a->todo |= TODO_OWNER;
-#endif
if (a->flags & ARCHIVE_EXTRACT_TIME)
a->todo |= TODO_TIMES;
- if (a->flags & ARCHIVE_EXTRACT_ACL)
- a->todo |= TODO_ACLS;
+ if (a->flags & ARCHIVE_EXTRACT_ACL) {
+ if (archive_entry_filetype(a->entry) == AE_IFDIR)
+ a->deferred |= TODO_ACLS;
+ else
+ a->todo |= TODO_ACLS;
+ }
+ if (a->flags & ARCHIVE_EXTRACT_MAC_METADATA) {
+ if (archive_entry_filetype(a->entry) == AE_IFDIR)
+ a->deferred |= TODO_MAC_METADATA;
+ else
+ a->todo |= TODO_MAC_METADATA;
+ }
if (a->flags & ARCHIVE_EXTRACT_XATTR)
a->todo |= TODO_XATTR;
if (a->flags & ARCHIVE_EXTRACT_FFLAGS)
@@ -432,9 +492,9 @@ _archive_write_header(struct archive *_a, struct archive_entry *entry)
if (a->flags & ARCHIVE_EXTRACT_SECURE_SYMLINKS) {
ret = check_symlinks(a);
if (ret != ARCHIVE_OK)
- goto done;
+ return (ret);
}
-#ifdef HAVE_FCHDIR
+#if defined(HAVE_FCHDIR) && defined(PATH_MAX)
/* If path exceeds PATH_MAX, shorten the path. */
edit_deep_directories(a);
#endif
@@ -480,6 +540,7 @@ _archive_write_header(struct archive *_a, struct archive_entry *entry)
&& (archive_entry_mtime_is_set(entry)
|| archive_entry_atime_is_set(entry))) {
fe = current_fixup(a, archive_entry_pathname(entry));
+ fe->mode = a->mode;
fe->fixup |= TODO_TIMES;
if (archive_entry_atime_is_set(entry)) {
fe->atime = archive_entry_atime(entry);
@@ -507,6 +568,26 @@ _archive_write_header(struct archive *_a, struct archive_entry *entry)
}
}
+ if (a->deferred & TODO_ACLS) {
+ fe = current_fixup(a, archive_entry_pathname(entry));
+ archive_acl_copy(&fe->acl, archive_entry_acl(entry));
+ }
+
+ if (a->deferred & TODO_MAC_METADATA) {
+ const void *metadata;
+ size_t metadata_size;
+ metadata = archive_entry_mac_metadata(a->entry, &metadata_size);
+ if (metadata != NULL && metadata_size > 0) {
+ fe = current_fixup(a, archive_entry_pathname(entry));
+ fe->mac_metadata = malloc(metadata_size);
+ if (fe->mac_metadata != NULL) {
+ memcpy(fe->mac_metadata, metadata, metadata_size);
+ fe->mac_metadata_size = metadata_size;
+ fe->fixup |= TODO_MAC_METADATA;
+ }
+ }
+ }
+
if (a->deferred & TODO_FFLAGS) {
fe = current_fixup(a, archive_entry_pathname(entry));
fe->fixup |= TODO_FFLAGS;
@@ -524,19 +605,17 @@ _archive_write_header(struct archive *_a, struct archive_entry *entry)
archive_entry_set_size(entry, 0);
a->filesize = 0;
}
-done:
- /* Restore the user's umask before returning. */
- umask(a->user_umask);
return (ret);
}
int
-archive_write_disk_set_skip_file(struct archive *_a, dev_t d, ino_t i)
+archive_write_disk_set_skip_file(struct archive *_a, int64_t d, int64_t i)
{
struct archive_write_disk *a = (struct archive_write_disk *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_disk_set_skip_file");
+ a->skip_file_set = 1;
a->skip_file_dev = d;
a->skip_file_ino = i;
return (ARCHIVE_OK);
@@ -561,7 +640,7 @@ write_data_block(struct archive_write_disk *a, const char *buff, size_t size)
if (a->flags & ARCHIVE_EXTRACT_SPARSE) {
#if HAVE_STRUCT_STAT_ST_BLKSIZE
int r;
- if ((r = _archive_write_disk_lazy_stat(a)) != ARCHIVE_OK)
+ if ((r = lazy_stat(a)) != ARCHIVE_OK)
return (r);
block_size = a->pst->st_blksize;
#else
@@ -572,7 +651,7 @@ write_data_block(struct archive_write_disk *a, const char *buff, size_t size)
}
/* If this write would run beyond the file size, truncate it. */
- if (a->filesize >= 0 && (off_t)(a->offset + size) > a->filesize)
+ if (a->filesize >= 0 && (int64_t)(a->offset + size) > a->filesize)
start_size = size = (size_t)(a->filesize - a->offset);
/* Write the data. */
@@ -582,7 +661,7 @@ write_data_block(struct archive_write_disk *a, const char *buff, size_t size)
} else {
/* We're sparsifying the file. */
const char *p, *end;
- off_t block_end;
+ int64_t block_end;
/* Skip leading zero bytes. */
for (p = buff, end = buff + size; p < end; ++p) {
@@ -613,9 +692,7 @@ write_data_block(struct archive_write_disk *a, const char *buff, size_t size)
return (ARCHIVE_FATAL);
}
a->fd_offset = a->offset;
- a->archive.file_position = a->offset;
- a->archive.raw_position = a->offset;
- }
+ }
bytes_written = write(a->fd, buff, bytes_to_write);
if (bytes_written < 0) {
archive_set_error(&a->archive, errno, "Write failed");
@@ -623,23 +700,22 @@ write_data_block(struct archive_write_disk *a, const char *buff, size_t size)
}
buff += bytes_written;
size -= bytes_written;
+ a->total_bytes_written += bytes_written;
a->offset += bytes_written;
- a->archive.file_position += bytes_written;
- a->archive.raw_position += bytes_written;
a->fd_offset = a->offset;
}
return (start_size - size);
}
static ssize_t
-_archive_write_data_block(struct archive *_a,
- const void *buff, size_t size, off_t offset)
+_archive_write_disk_data_block(struct archive *_a,
+ const void *buff, size_t size, int64_t offset)
{
struct archive_write_disk *a = (struct archive_write_disk *)_a;
ssize_t r;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
- ARCHIVE_STATE_DATA, "archive_write_disk_block");
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_DATA, "archive_write_data_block");
a->offset = offset;
r = write_data_block(a, buff, size);
@@ -654,23 +730,23 @@ _archive_write_data_block(struct archive *_a,
}
static ssize_t
-_archive_write_data(struct archive *_a, const void *buff, size_t size)
+_archive_write_disk_data(struct archive *_a, const void *buff, size_t size)
{
struct archive_write_disk *a = (struct archive_write_disk *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_DATA, "archive_write_data");
return (write_data_block(a, buff, size));
}
static int
-_archive_write_finish_entry(struct archive *_a)
+_archive_write_disk_finish_entry(struct archive *_a)
{
struct archive_write_disk *a = (struct archive_write_disk *)_a;
int ret = ARCHIVE_OK;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
"archive_write_finish_entry");
if (a->archive.state & ARCHIVE_STATE_HEADER)
@@ -700,7 +776,7 @@ _archive_write_finish_entry(struct archive *_a)
* to see what happened.
*/
a->pst = NULL;
- if ((ret = _archive_write_disk_lazy_stat(a)) != ARCHIVE_OK)
+ if ((ret = lazy_stat(a)) != ARCHIVE_OK)
return (ret);
/* We can use lseek()/write() to extend the file if
* ftruncate didn't work or isn't available. */
@@ -727,32 +803,34 @@ _archive_write_finish_entry(struct archive *_a)
* TODO: the TODO_SGID condition can be dropped here, can't it?
*/
if (a->todo & (TODO_OWNER | TODO_SUID | TODO_SGID)) {
- a->uid = a->lookup_uid(a->lookup_uid_data,
+ a->uid = archive_write_disk_uid(&a->archive,
archive_entry_uname(a->entry),
archive_entry_uid(a->entry));
}
/* Look up the "real" GID only if we're going to need it. */
/* TODO: the TODO_SUID condition can be dropped here, can't it? */
if (a->todo & (TODO_OWNER | TODO_SGID | TODO_SUID)) {
- a->gid = a->lookup_gid(a->lookup_gid_data,
+ a->gid = archive_write_disk_gid(&a->archive,
archive_entry_gname(a->entry),
archive_entry_gid(a->entry));
}
+
/*
- * If restoring ownership, do it before trying to restore suid/sgid
+ * Restore ownership before set_mode tries to restore suid/sgid
* bits. If we set the owner, we know what it is and can skip
* a stat() call to examine the ownership of the file on disk.
*/
if (a->todo & TODO_OWNER)
ret = set_ownership(a);
+
+ /*
+ * set_mode must precede ACLs on systems such as Solaris and
+ * FreeBSD where setting the mode implicitly clears extended ACLs
+ */
if (a->todo & TODO_MODE) {
int r2 = set_mode(a, a->mode);
if (r2 < ret) ret = r2;
}
- if (a->todo & TODO_ACLS) {
- int r2 = set_acls(a);
- if (r2 < ret) ret = r2;
- }
/*
* Security-related extended attributes (such as
@@ -772,12 +850,37 @@ _archive_write_finish_entry(struct archive *_a)
int r2 = set_fflags(a);
if (r2 < ret) ret = r2;
}
+
/*
- * Time has to be restored after all other metadata;
+ * Time must follow most other metadata;
* otherwise atime will get changed.
*/
if (a->todo & TODO_TIMES) {
- int r2 = set_times(a);
+ int r2 = set_times_from_entry(a);
+ if (r2 < ret) ret = r2;
+ }
+
+ /*
+ * Mac extended metadata includes ACLs.
+ */
+ if (a->todo & TODO_MAC_METADATA) {
+ const void *metadata;
+ size_t metadata_size;
+ metadata = archive_entry_mac_metadata(a->entry, &metadata_size);
+ if (metadata != NULL && metadata_size > 0) {
+ int r2 = set_mac_metadata(a, archive_entry_pathname(a->entry), metadata, metadata_size);
+ if (r2 < ret) ret = r2;
+ }
+ }
+
+ /*
+ * ACLs must be restored after timestamps because there are
+ * ACLs that prevent attribute changes (including time).
+ */
+ if (a->todo & TODO_ACLS) {
+ int r2 = set_acls(a, a->fd,
+ archive_entry_pathname(a->entry),
+ archive_entry_acl(a->entry));
if (r2 < ret) ret = r2;
}
@@ -798,13 +901,16 @@ _archive_write_finish_entry(struct archive *_a)
int
archive_write_disk_set_group_lookup(struct archive *_a,
void *private_data,
- gid_t (*lookup_gid)(void *private, const char *gname, gid_t gid),
+ int64_t (*lookup_gid)(void *private, const char *gname, int64_t gid),
void (*cleanup_gid)(void *private))
{
struct archive_write_disk *a = (struct archive_write_disk *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_disk_set_group_lookup");
+ if (a->cleanup_gid != NULL && a->lookup_gid_data != NULL)
+ (a->cleanup_gid)(a->lookup_gid_data);
+
a->lookup_gid = lookup_gid;
a->cleanup_gid = cleanup_gid;
a->lookup_gid_data = private_data;
@@ -814,19 +920,43 @@ archive_write_disk_set_group_lookup(struct archive *_a,
int
archive_write_disk_set_user_lookup(struct archive *_a,
void *private_data,
- uid_t (*lookup_uid)(void *private, const char *uname, uid_t uid),
+ int64_t (*lookup_uid)(void *private, const char *uname, int64_t uid),
void (*cleanup_uid)(void *private))
{
struct archive_write_disk *a = (struct archive_write_disk *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_disk_set_user_lookup");
+ if (a->cleanup_uid != NULL && a->lookup_uid_data != NULL)
+ (a->cleanup_uid)(a->lookup_uid_data);
+
a->lookup_uid = lookup_uid;
a->cleanup_uid = cleanup_uid;
a->lookup_uid_data = private_data;
return (ARCHIVE_OK);
}
+int64_t
+archive_write_disk_gid(struct archive *_a, const char *name, int64_t id)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_write_disk_gid");
+ if (a->lookup_gid)
+ return (a->lookup_gid)(a->lookup_gid_data, name, id);
+ return (id);
+}
+
+int64_t
+archive_write_disk_uid(struct archive *_a, const char *name, int64_t id)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_write_disk_uid");
+ if (a->lookup_uid)
+ return (a->lookup_uid)(a->lookup_uid_data, name, id);
+ return (id);
+}
/*
* Create a new archive_write_disk object and initialize it with global state.
@@ -844,9 +974,9 @@ archive_write_disk_new(void)
/* We're ready to write a header immediately. */
a->archive.state = ARCHIVE_STATE_HEADER;
a->archive.vtable = archive_write_disk_vtable();
- a->lookup_uid = trivial_lookup_uid;
- a->lookup_gid = trivial_lookup_gid;
a->start_time = time(NULL);
+ /* Query and restore the umask. */
+ umask(a->user_umask = umask(0));
#ifdef HAVE_GETEUID
a->user_uid = geteuid();
#endif /* HAVE_GETEUID */
@@ -866,15 +996,13 @@ archive_write_disk_new(void)
* object creation is likely to fail, but any error will get handled
* at that time.
*/
-#ifdef HAVE_FCHDIR
+#if defined(HAVE_FCHDIR) && defined(PATH_MAX)
static void
edit_deep_directories(struct archive_write_disk *a)
{
int ret;
char *tail = a->name;
- a->restore_pwd = -1;
-
/* If path is short, avoid the open() below. */
if (strlen(tail) <= PATH_MAX)
return;
@@ -956,8 +1084,8 @@ restore_entry(struct archive_write_disk *a)
if ((en == EISDIR || en == EEXIST)
&& (a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE)) {
/* If we're not overwriting, we're done. */
- archive_set_error(&a->archive, en, "Already exists");
- return (ARCHIVE_FAILED);
+ archive_entry_unset_size(a->entry);
+ return (ARCHIVE_OK);
}
/*
@@ -984,7 +1112,7 @@ restore_entry(struct archive_write_disk *a)
*/
int r = 0;
/*
- * The SECURE_SYMLINK logic has already removed a
+ * The SECURE_SYMLINKS logic has already removed a
* symlink to a dir if the client wants that. So
* follow the symlink if we're creating a dir.
*/
@@ -1008,15 +1136,13 @@ restore_entry(struct archive_write_disk *a)
if ((a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER)
&& !S_ISDIR(a->st.st_mode)) {
if (!older(&(a->st), a->entry)) {
- archive_set_error(&a->archive, 0,
- "File on disk is not older; skipping.");
- return (ARCHIVE_FAILED);
+ archive_entry_unset_size(a->entry);
+ return (ARCHIVE_OK);
}
}
/* If it's our archive, we're done. */
- if (a->skip_file_dev > 0 &&
- a->skip_file_ino > 0 &&
+ if (a->skip_file_set &&
a->st.st_dev == a->skip_file_dev &&
a->st.st_ino == a->skip_file_ino) {
archive_set_error(&a->archive, 0, "Refusing to overwrite archive");
@@ -1097,7 +1223,7 @@ create_filesystem_object(struct archive_write_disk *a)
*
* If the hardlink was successfully created and
* the archive doesn't have carry data for it,
- * consider it to be non-authoritive for meta data.
+ * consider it to be non-authoritative for meta data.
* This is consistent with GNU tar and BSD pax.
* If the hardlink does carry data, let the last
* archive entry decide ownership.
@@ -1105,7 +1231,7 @@ create_filesystem_object(struct archive_write_disk *a)
if (r == 0 && a->filesize <= 0) {
a->todo = 0;
a->deferred = 0;
- } if (r == 0 && a->filesize > 0) {
+ } else if (r == 0 && a->filesize > 0) {
a->fd = open(a->name, O_WRONLY | O_TRUNC | O_BINARY);
if (a->fd < 0)
r = errno;
@@ -1135,7 +1261,7 @@ create_filesystem_object(struct archive_write_disk *a)
* that SUID, SGID, etc, require additional work to ensure
* security, so we never restore them at this point.
*/
- mode = final_mode & 0777;
+ mode = final_mode & 0777 & a->user_umask;
switch (a->mode & AE_IFMT) {
default:
@@ -1216,6 +1342,7 @@ create_filesystem_object(struct archive_write_disk *a)
* timestamps at the end as well.
* * Some file flags can interfere with the restore by, for example,
* preventing the creation of hardlinks to those files.
+ * * Mac OS extended metadata includes ACLs, so must be deferred on dirs.
*
* Note that tar/cpio do not require that archives be in a particular
* order; there is no way to know when the last file has been restored
@@ -1227,16 +1354,16 @@ create_filesystem_object(struct archive_write_disk *a)
* reason we set directory perms here. XXX
*/
static int
-_archive_write_close(struct archive *_a)
+_archive_write_disk_close(struct archive *_a)
{
struct archive_write_disk *a = (struct archive_write_disk *)_a;
struct fixup_entry *next, *p;
int ret;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
"archive_write_disk_close");
- ret = _archive_write_finish_entry(&a->archive);
+ ret = _archive_write_disk_finish_entry(&a->archive);
/* Sort dir list so directories are fixed up in depth-first order. */
p = sort_dir_list(a->fixup_list);
@@ -1244,48 +1371,25 @@ _archive_write_close(struct archive *_a)
while (p != NULL) {
a->pst = NULL; /* Mark stat cache as out-of-date. */
if (p->fixup & TODO_TIMES) {
-#ifdef HAVE_UTIMES
- /* {f,l,}utimes() are preferred, when available. */
-#if defined(_WIN32) && !defined(__CYGWIN__)
- struct __timeval times[2];
-#else
- struct timeval times[2];
-#endif
- times[0].tv_sec = p->atime;
- times[0].tv_usec = p->atime_nanos / 1000;
-#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
- /* if it's valid and not mtime, push the birthtime first */
- if (((times[1].tv_sec = p->birthtime) < p->mtime) &&
- (p->birthtime > 0))
- {
- times[1].tv_usec = p->birthtime_nanos / 1000;
- utimes(p->name, times);
- }
-#endif
- times[1].tv_sec = p->mtime;
- times[1].tv_usec = p->mtime_nanos / 1000;
-#ifdef HAVE_LUTIMES
- lutimes(p->name, times);
-#else
- utimes(p->name, times);
-#endif
-#else
- /* utime() is more portable, but less precise. */
- struct utimbuf times;
- times.modtime = p->mtime;
- times.actime = p->atime;
-
- utime(p->name, &times);
-#endif
+ set_times(a, -1, p->mode, p->name,
+ p->atime, p->atime_nanos,
+ p->birthtime, p->birthtime_nanos,
+ p->mtime, p->mtime_nanos,
+ p->ctime, p->ctime_nanos);
}
if (p->fixup & TODO_MODE_BASE)
chmod(p->name, p->mode);
-
+ if (p->fixup & TODO_ACLS)
+ set_acls(a, -1, p->name, &p->acl);
if (p->fixup & TODO_FFLAGS)
set_fflags_platform(a, -1, p->name,
p->mode, p->fflags_set, 0);
-
+ if (p->fixup & TODO_MAC_METADATA)
+ set_mac_metadata(a, p->name, p->mac_metadata,
+ p->mac_metadata_size);
next = p->next;
+ archive_acl_clear(&p->acl);
+ free(p->mac_metadata);
free(p->name);
free(p);
p = next;
@@ -1295,20 +1399,25 @@ _archive_write_close(struct archive *_a)
}
static int
-_archive_write_free(struct archive *_a)
+_archive_write_disk_free(struct archive *_a)
{
- struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ struct archive_write_disk *a;
int ret;
- ret = _archive_write_close(&a->archive);
- if (a->cleanup_gid != NULL && a->lookup_gid_data != NULL)
- (a->cleanup_gid)(a->lookup_gid_data);
- if (a->cleanup_uid != NULL && a->lookup_uid_data != NULL)
- (a->cleanup_uid)(a->lookup_uid_data);
+ if (_a == NULL)
+ return (ARCHIVE_OK);
+ archive_check_magic(_a, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_write_disk_free");
+ a = (struct archive_write_disk *)_a;
+ ret = _archive_write_disk_close(&a->archive);
+ archive_write_disk_set_group_lookup(&a->archive, NULL, NULL, NULL);
+ archive_write_disk_set_user_lookup(&a->archive, NULL, NULL, NULL);
if (a->entry)
archive_entry_free(a->entry);
archive_string_free(&a->_name_data);
archive_string_free(&a->archive.error_string);
archive_string_free(&a->path_safe);
+ a->archive.magic = 0;
+ __archive_clean(&a->archive);
free(a);
return (ret);
}
@@ -1389,7 +1498,7 @@ new_fixup(struct archive_write_disk *a, const char *pathname)
{
struct fixup_entry *fe;
- fe = (struct fixup_entry *)malloc(sizeof(struct fixup_entry));
+ fe = (struct fixup_entry *)calloc(1, sizeof(struct fixup_entry));
if (fe == NULL)
return (NULL);
fe->next = a->fixup_list;
@@ -1429,7 +1538,7 @@ check_symlinks(struct archive_write_disk *a)
(void)a; /* UNUSED */
return (ARCHIVE_OK);
#else
- char *pn, *p;
+ char *pn;
char c;
int r;
struct stat st;
@@ -1440,9 +1549,11 @@ check_symlinks(struct archive_write_disk *a)
*/
/* Whatever we checked last time doesn't need to be re-checked. */
pn = a->name;
- p = a->path_safe.s;
- while ((*pn != '\0') && (*p == *pn))
- ++p, ++pn;
+ if (archive_strlen(&(a->path_safe)) > 0) {
+ char *p = a->path_safe.s;
+ while ((*pn != '\0') && (*p == *pn))
+ ++p, ++pn;
+ }
c = pn[0];
/* Keep going until we've checked the entire name. */
while (pn[0] != '\0' && (pn[0] != '/' || pn[1] != '\0')) {
@@ -1512,119 +1623,51 @@ check_symlinks(struct archive_write_disk *a)
#endif
}
-#if defined(_WIN32) || defined(__CYGWIN__)
-static int
-guidword(const char *p, int n)
-{
- int i;
-
- for (i = 0; i < n; i++) {
- if ((*p >= '0' && *p <= '9') ||
- (*p >= 'a' && *p <= 'f') ||
- (*p >= 'A' && *p <= 'F'))
- p++;
- else
- return (-1);
- }
- return (0);
-}
-
+#if defined(__CYGWIN__)
/*
* 1. Convert a path separator from '\' to '/' .
- * We shouldn't check multi-byte character directly because some
+ * We shouldn't check multibyte character directly because some
* character-set have been using the '\' character for a part of
* its multibyte character code.
* 2. Replace unusable characters in Windows with underscore('_').
* See also : http://msdn.microsoft.com/en-us/library/aa365247.aspx
*/
-static int
+static void
cleanup_pathname_win(struct archive_write_disk *a)
{
wchar_t wc;
char *p;
size_t alen, l;
-
- p = a->name;
- /* Skip leading "\\.\" or "\\?\" or "\\?\UNC\" or
- * "\\?\Volume{GUID}\"
- * (absolute path prefixes used by Windows API) */
- if ((p[0] == '\\' || p[0] == '/') && (p[1] == '\\' || p[1] == '/' ) &&
- (p[2] == '.' || p[2] == '?') && (p[3] == '\\' || p[3] == '/'))
- {
- /* A path begin with "\\?\UNC\" */
- if (p[2] == '?' &&
- (p[4] == 'U' || p[4] == 'u') &&
- (p[5] == 'N' || p[5] == 'n') &&
- (p[6] == 'C' || p[6] == 'c') &&
- (p[7] == '\\' || p[7] == '/'))
- p += 8;
- /* A path begin with "\\?\Volume{GUID}\" */
- else if (p[2] == '?' &&
- (p[4] == 'V' || p[4] == 'v') &&
- (p[5] == 'O' || p[5] == 'o') &&
- (p[6] == 'L' || p[6] == 'l') &&
- (p[7] == 'U' || p[7] == 'u') &&
- (p[8] == 'M' || p[8] == 'm') &&
- (p[9] == 'E' || p[9] == 'e') &&
- p[10] == '{') {
- if (guidword(p+11, 8) == 0 && p[19] == '-' &&
- guidword(p+20, 4) == 0 && p[24] == '-' &&
- guidword(p+25, 4) == 0 && p[29] == '-' &&
- guidword(p+30, 4) == 0 && p[34] == '-' &&
- guidword(p+35, 12) == 0 && p[47] == '}' &&
- (p[48] == '\\' || p[48] == '/'))
- p += 49;
+ int mb, complete, utf8;
+
+ alen = 0;
+ mb = 0;
+ complete = 1;
+ utf8 = (strcmp(nl_langinfo(CODESET), "UTF-8") == 0)? 1: 0;
+ for (p = a->name; *p != '\0'; p++) {
+ ++alen;
+ if (*p == '\\') {
+ /* If previous byte is smaller than 128,
+ * this is not second byte of multibyte characters,
+ * so we can replace '\' with '/'. */
+ if (utf8 || !mb)
+ *p = '/';
else
- p += 4;
- /* A path begin with "\\.\PhysicalDriveX" */
- } else if (p[2] == '.' &&
- (p[4] == 'P' || p[4] == 'p') &&
- (p[5] == 'H' || p[5] == 'h') &&
- (p[6] == 'Y' || p[6] == 'y') &&
- (p[7] == 'S' || p[7] == 's') &&
- (p[8] == 'I' || p[8] == 'i') &&
- (p[9] == 'C' || p[9] == 'c') &&
- (p[9] == 'A' || p[9] == 'a') &&
- (p[9] == 'L' || p[9] == 'l') &&
- (p[9] == 'D' || p[9] == 'd') &&
- (p[9] == 'R' || p[9] == 'r') &&
- (p[9] == 'I' || p[9] == 'i') &&
- (p[9] == 'V' || p[9] == 'v') &&
- (p[9] == 'E' || p[9] == 'e') &&
- (p[10] >= '0' && p[10] <= '9') &&
- p[11] == '\0') {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Path is a physical drive name");
- return (ARCHIVE_FAILED);
- } else
- p += 4;
- }
-
- /* Skip leading drive letter from archives created
- * on Windows. */
- if (((p[0] >= 'a' && p[0] <= 'z') ||
- (p[0] >= 'A' && p[0] <= 'Z')) &&
- p[1] == ':') {
- if (p[2] == '\0') {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Path is a drive name");
- return (ARCHIVE_FAILED);
- }
- if (p[2] == '\\' || p[2] == '/')
- p += 3;
- }
-
- for (; *p != '\0'; p++) {
- /* Rewrite the path name if its character is a unusable. */
+ complete = 0;/* uncompleted. */
+ } else if (*(unsigned char *)p > 127)
+ mb = 1;
+ else
+ mb = 0;
+ /* Rewrite the path name if its next character is unusable. */
if (*p == ':' || *p == '*' || *p == '?' || *p == '"' ||
*p == '<' || *p == '>' || *p == '|')
*p = '_';
}
- alen = p - a->name;
- if (alen == 0 || strchr(a->name, '\\') == NULL)
- return (ARCHIVE_OK);
+ if (complete)
+ return;
+
/*
- * Convert path separator.
+ * Convert path separator in wide-character.
*/
p = a->name;
while (*p != '\0' && alen) {
@@ -1642,7 +1685,6 @@ cleanup_pathname_win(struct archive_write_disk *a)
p += l;
alen -= l;
}
- return (ARCHIVE_OK);
}
#endif
@@ -1665,9 +1707,8 @@ cleanup_pathname(struct archive_write_disk *a)
return (ARCHIVE_FAILED);
}
-#if defined(_WIN32) || defined(__CYGWIN__)
- if (cleanup_pathname_win(a) != ARCHIVE_OK)
- return (ARCHIVE_FAILED);
+#if defined(__CYGWIN__)
+ cleanup_pathname_win(a);
#endif
/* Skip leading '/'. */
if (*src == '/')
@@ -1814,7 +1855,8 @@ create_dir(struct archive_write_disk *a, char *path)
if (unlink(path) != 0) {
archive_set_error(&a->archive, errno,
"Can't create directory '%s': "
- "Conflicting file cannot be removed", path);
+ "Conflicting file cannot be removed",
+ path);
return (ARCHIVE_FAILED);
}
} else if (errno != ENOENT && errno != ENOTDIR) {
@@ -1885,7 +1927,7 @@ set_ownership(struct archive_write_disk *a)
/* If we know we can't change it, don't bother trying. */
if (a->user_uid != 0 && a->user_uid != a->uid) {
archive_set_error(&a->archive, errno,
- "Can't set UID=%d", a->uid);
+ "Can't set UID=%jd", (intmax_t)a->uid);
return (ARCHIVE_WARN);
}
#endif
@@ -1916,22 +1958,26 @@ set_ownership(struct archive_write_disk *a)
#endif
archive_set_error(&a->archive, errno,
- "Can't set user=%d/group=%d for %s", a->uid, a->gid,
- a->name);
+ "Can't set user=%jd/group=%jd for %s",
+ (intmax_t)a->uid, (intmax_t)a->gid, a->name);
return (ARCHIVE_WARN);
}
-
-#if defined(HAVE_UTIMENSAT) && defined(HAVE_FUTIMENS)
-/*
- * utimensat() and futimens() are defined in POSIX.1-2008. They provide ns
- * resolution and setting times on fd and on symlinks, too.
+/*
+ * Note: Returns 0 on success, non-zero on failure.
*/
static int
set_time(int fd, int mode, const char *name,
time_t atime, long atime_nsec,
time_t mtime, long mtime_nsec)
{
+ /* Select the best implementation for this platform. */
+#if defined(HAVE_UTIMENSAT) && defined(HAVE_FUTIMENS)
+ /*
+ * utimensat() and futimens() are defined in
+ * POSIX.1-2008. They support ns resolution and setting times
+ * on fds and symlinks.
+ */
struct timespec ts[2];
ts[0].tv_sec = atime;
ts[0].tv_nsec = atime_nsec;
@@ -1940,23 +1986,15 @@ set_time(int fd, int mode, const char *name,
if (fd >= 0)
return futimens(fd, ts);
return utimensat(AT_FDCWD, name, ts, AT_SYMLINK_NOFOLLOW);
-}
+
#elif HAVE_UTIMES
-/*
- * The utimes()-family functions provide µs-resolution and
- * a way to set time on an fd or a symlink. We prefer them
- * when they're available and utimensat/futimens aren't there.
- */
-static int
-set_time(int fd, int mode, const char *name,
- time_t atime, long atime_nsec,
- time_t mtime, long mtime_nsec)
-{
-#if defined(_WIN32) && !defined(__CYGWIN__)
- struct __timeval times[2];
-#else
+ /*
+ * The utimes()-family functions support µs-resolution and
+ * setting times fds and symlinks. utimes() is documented as
+ * LEGACY by POSIX, futimes() and lutimes() are not described
+ * in POSIX.
+ */
struct timeval times[2];
-#endif
times[0].tv_sec = atime;
times[0].tv_usec = atime_nsec / 1000;
@@ -1977,17 +2015,12 @@ set_time(int fd, int mode, const char *name,
return (0);
return (utimes(name, times));
#endif
-}
+
#elif defined(HAVE_UTIME)
-/*
- * utime() is an older, more standard interface that we'll use
- * if utimes() isn't available.
- */
-static int
-set_time(int fd, int mode, const char *name,
- time_t atime, long atime_nsec,
- time_t mtime, long mtime_nsec)
-{
+ /*
+ * utime() is POSIX-standard but only supports 1s resolution and
+ * does not support fds or symlinks.
+ */
struct utimbuf times;
(void)fd; /* UNUSED */
(void)name; /* UNUSED */
@@ -1998,22 +2031,98 @@ set_time(int fd, int mode, const char *name,
if (S_ISLNK(mode))
return (ARCHIVE_OK);
return (utime(name, &times));
-}
+
#else
+ /*
+ * We don't know how to set the time on this platform.
+ */
+ return (ARCHIVE_WARN);
+#endif
+}
+
+#ifdef F_SETTIMES /* Tru64 */
static int
-set_time(int fd, int mode, const char *name,
+set_time_tru64(int fd, int mode, const char *name,
time_t atime, long atime_nsec,
- time_t mtime, long mtime_nsec)
+ time_t mtime, long mtime_nsec,
+ time_t ctime, long ctime_nsec)
{
- return (ARCHIVE_WARN);
+ struct attr_timbuf tstamp;
+ struct timeval times[3];
+ times[0].tv_sec = atime;
+ times[0].tv_usec = atime_nsec / 1000;
+ times[1].tv_sec = mtime;
+ times[1].tv_usec = mtime_nsec / 1000;
+ times[2].tv_sec = ctime;
+ times[2].tv_usec = ctime_nsec / 1000;
+ tstamp.atime = times[0];
+ tstamp.mtime = times[1];
+ tstamp.ctime = times[2];
+ return (fcntl(fd,F_SETTIMES,&tstamp));
}
-#endif
+#endif /* Tru64 */
static int
-set_times(struct archive_write_disk *a)
+set_times(struct archive_write_disk *a,
+ int fd, int mode, const char *name,
+ time_t atime, long atime_nanos,
+ time_t birthtime, long birthtime_nanos,
+ time_t mtime, long mtime_nanos,
+ time_t ctime, long ctime_nanos)
{
- time_t atime = a->start_time, mtime = a->start_time;
- long atime_nsec = 0, mtime_nsec = 0;
+ /* Note: set_time doesn't use libarchive return conventions!
+ * It uses syscall conventions. So 0 here instead of ARCHIVE_OK. */
+ int r1 = 0, r2 = 0;
+
+#ifdef F_SETTIMES
+ /*
+ * on Tru64 try own fcntl first which can restore even the
+ * ctime, fall back to default code path below if it fails
+ * or if we are not running as root
+ */
+ if (a->user_uid == 0 &&
+ set_time_tru64(fd, mode, name,
+ atime, atime_nanos, mtime,
+ mtime_nanos, ctime, ctime_nanos) == 0) {
+ return (ARCHIVE_OK);
+ }
+#endif /* Tru64 */
+
+#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
+ /*
+ * If you have struct stat.st_birthtime, we assume BSD
+ * birthtime semantics, in which {f,l,}utimes() updates
+ * birthtime to earliest mtime. So we set the time twice,
+ * first using the birthtime, then using the mtime. If
+ * birthtime == mtime, this isn't necessary, so we skip it.
+ * If birthtime > mtime, then this won't work, so we skip it.
+ */
+ if (birthtime < mtime
+ || (birthtime == mtime && birthtime_nanos < mtime_nanos))
+ r1 = set_time(fd, mode, name,
+ atime, atime_nanos,
+ birthtime, birthtime_nanos);
+#endif
+ r2 = set_time(fd, mode, name,
+ atime, atime_nanos,
+ mtime, mtime_nanos);
+ if (r1 != 0 || r2 != 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't restore time");
+ return (ARCHIVE_WARN);
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+set_times_from_entry(struct archive_write_disk *a)
+{
+ time_t atime, birthtime, mtime, ctime;
+ long atime_nsec, birthtime_nsec, mtime_nsec, ctime_nsec;
+
+ /* Suitable defaults. */
+ atime = birthtime = mtime = ctime = a->start_time;
+ atime_nsec = birthtime_nsec = mtime_nsec = ctime_nsec = 0;
/* If no time was provided, we're done. */
if (!archive_entry_atime_is_set(a->entry)
@@ -2023,53 +2132,28 @@ set_times(struct archive_write_disk *a)
&& !archive_entry_mtime_is_set(a->entry))
return (ARCHIVE_OK);
- /* If no atime was specified, use start time instead. */
- /* In theory, it would be marginally more correct to use
- * time(NULL) here, but that would cost us an extra syscall
- * for little gain. */
if (archive_entry_atime_is_set(a->entry)) {
atime = archive_entry_atime(a->entry);
atime_nsec = archive_entry_atime_nsec(a->entry);
}
-
- /*
- * If you have struct stat.st_birthtime, we assume BSD birthtime
- * semantics, in which {f,l,}utimes() updates birthtime to earliest
- * mtime. So we set the time twice, first using the birthtime,
- * then using the mtime.
- */
-#if HAVE_STRUCT_STAT_ST_BIRTHTIME
- /* If birthtime is set, flush that through to disk first. */
- if (archive_entry_birthtime_is_set(a->entry))
- if (set_time(a->fd, a->mode, a->name, atime, atime_nsec,
- archive_entry_birthtime(a->entry),
- archive_entry_birthtime_nsec(a->entry))) {
- archive_set_error(&a->archive, errno,
- "Can't update time for %s",
- a->name);
- return (ARCHIVE_WARN);
- }
-#endif
-
+ if (archive_entry_birthtime_is_set(a->entry)) {
+ birthtime = archive_entry_birthtime(a->entry);
+ birthtime_nsec = archive_entry_birthtime_nsec(a->entry);
+ }
if (archive_entry_mtime_is_set(a->entry)) {
mtime = archive_entry_mtime(a->entry);
mtime_nsec = archive_entry_mtime_nsec(a->entry);
}
- if (set_time(a->fd, a->mode, a->name,
- atime, atime_nsec, mtime, mtime_nsec)) {
- archive_set_error(&a->archive, errno,
- "Can't update time for %s",
- a->name);
- return (ARCHIVE_WARN);
+ if (archive_entry_ctime_is_set(a->entry)) {
+ ctime = archive_entry_ctime(a->entry);
+ ctime_nsec = archive_entry_ctime_nsec(a->entry);
}
- /*
- * Note: POSIX does not provide a portable way to restore ctime.
- * (Apart from resetting the system clock, which is distasteful.)
- * So, any restoration of ctime will necessarily be OS-specific.
- */
-
- return (ARCHIVE_OK);
+ return set_times(a, a->fd, a->mode, a->name,
+ atime, atime_nsec,
+ birthtime, birthtime_nsec,
+ mtime, mtime_nsec,
+ ctime, ctime_nsec);
}
static int
@@ -2085,11 +2169,10 @@ set_mode(struct archive_write_disk *a, int mode)
* process, since systems sometimes set GID from
* the enclosing dir or based on ACLs.
*/
- if ((r = _archive_write_disk_lazy_stat(a)) != ARCHIVE_OK)
+ if ((r = lazy_stat(a)) != ARCHIVE_OK)
return (r);
if (a->pst->st_gid != a->gid) {
mode &= ~ S_ISGID;
-#if !defined(_WIN32) || defined(__CYGWIN__)
if (a->flags & ARCHIVE_EXTRACT_OWNER) {
/*
* This is only an error if you
@@ -2102,19 +2185,16 @@ set_mode(struct archive_write_disk *a, int mode)
"Can't restore SGID bit");
r = ARCHIVE_WARN;
}
-#endif
}
/* While we're here, double-check the UID. */
if (a->pst->st_uid != a->uid
&& (a->todo & TODO_SUID)) {
mode &= ~ S_ISUID;
-#if !defined(_WIN32) || defined(__CYGWIN__)
if (a->flags & ARCHIVE_EXTRACT_OWNER) {
archive_set_error(&a->archive, -1,
"Can't restore SUID bit");
r = ARCHIVE_WARN;
}
-#endif
}
a->todo &= ~TODO_SGID_CHECK;
a->todo &= ~TODO_SUID_CHECK;
@@ -2126,13 +2206,11 @@ set_mode(struct archive_write_disk *a, int mode)
*/
if (a->user_uid != a->uid) {
mode &= ~ S_ISUID;
-#if !defined(_WIN32) || defined(__CYGWIN__)
if (a->flags & ARCHIVE_EXTRACT_OWNER) {
archive_set_error(&a->archive, -1,
"Can't make file SUID");
r = ARCHIVE_WARN;
}
-#endif
}
a->todo &= ~TODO_SUID_CHECK;
}
@@ -2270,7 +2348,7 @@ set_fflags_platform(struct archive_write_disk *a, int fd, const char *name,
* about the correct approach if we're overwriting an existing
* file that already has flags on it. XXX
*/
- if ((r = _archive_write_disk_lazy_stat(a)) != ARCHIVE_OK)
+ if ((r = lazy_stat(a)) != ARCHIVE_OK)
return (r);
a->st.st_flags &= ~clear;
@@ -2302,7 +2380,7 @@ set_fflags_platform(struct archive_write_disk *a, int fd, const char *name,
return (ARCHIVE_WARN);
}
-#elif defined(EXT2_IOC_GETFLAGS) && defined(EXT2_IOC_SETFLAGS)
+#elif defined(EXT2_IOC_GETFLAGS) && defined(EXT2_IOC_SETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)
/*
* Linux uses ioctl() to read and write file flags.
*/
@@ -2345,22 +2423,25 @@ set_fflags_platform(struct archive_write_disk *a, int fd, const char *name,
* to read the current flags from disk. XXX
*/
ret = ARCHIVE_OK;
+
+ /* Read the current file flags. */
+ if (ioctl(myfd, EXT2_IOC_GETFLAGS, &oldflags) < 0)
+ goto fail;
+
/* Try setting the flags as given. */
- if (ioctl(myfd, EXT2_IOC_GETFLAGS, &oldflags) >= 0) {
- newflags = (oldflags & ~clear) | set;
- if (ioctl(myfd, EXT2_IOC_SETFLAGS, &newflags) >= 0)
- goto cleanup;
- if (errno != EPERM)
- goto fail;
- }
+ newflags = (oldflags & ~clear) | set;
+ if (ioctl(myfd, EXT2_IOC_SETFLAGS, &newflags) >= 0)
+ goto cleanup;
+ if (errno != EPERM)
+ goto fail;
+
/* If we couldn't set all the flags, try again with a subset. */
- if (ioctl(myfd, EXT2_IOC_GETFLAGS, &oldflags) >= 0) {
- newflags &= ~sf_mask;
- oldflags &= sf_mask;
- newflags |= oldflags;
- if (ioctl(myfd, EXT2_IOC_SETFLAGS, &newflags) >= 0)
- goto cleanup;
- }
+ newflags &= ~sf_mask;
+ oldflags &= sf_mask;
+ newflags |= oldflags;
+ if (ioctl(myfd, EXT2_IOC_SETFLAGS, &newflags) >= 0)
+ goto cleanup;
+
/* We couldn't set the flags, so report the failure. */
fail:
archive_set_error(&a->archive, errno,
@@ -2393,12 +2474,72 @@ set_fflags_platform(struct archive_write_disk *a, int fd, const char *name,
#endif /* __linux */
+#ifndef HAVE_COPYFILE_H
+/* Default is to simply drop Mac extended metadata. */
+static int
+set_mac_metadata(struct archive_write_disk *a, const char *pathname,
+ const void *metadata, size_t metadata_size)
+{
+ (void)a; /* UNUSED */
+ (void)pathname; /* UNUSED */
+ (void)metadata; /* UNUSED */
+ (void)metadata_size; /* UNUSED */
+ return (ARCHIVE_OK);
+}
+#else
+
+/*
+ * On Mac OS, we use copyfile() to unpack the metadata and
+ * apply it to the target file.
+ */
+static int
+set_mac_metadata(struct archive_write_disk *a, const char *pathname,
+ const void *metadata, size_t metadata_size)
+{
+ struct archive_string tmp;
+ ssize_t written;
+ int fd;
+ int ret = ARCHIVE_OK;
+
+ /* This would be simpler if copyfile() could just accept the
+ * metadata as a block of memory; then we could sidestep this
+ * silly dance of writing the data to disk just so that
+ * copyfile() can read it back in again. */
+ archive_string_init(&tmp);
+ archive_strcpy(&tmp, pathname);
+ archive_strcat(&tmp, ".XXXXXX");
+ fd = mkstemp(tmp.s);
+
+ if (fd < 0) {
+ archive_set_error(&a->archive, errno,
+ "Failed to restore metadata");
+ return (ARCHIVE_WARN);
+ }
+ written = write(fd, metadata, metadata_size);
+ close(fd);
+ if (written != metadata_size
+ || copyfile(tmp.s, pathname, 0,
+ COPYFILE_UNPACK | COPYFILE_NOFOLLOW
+ | COPYFILE_ACL | COPYFILE_XATTR)) {
+ archive_set_error(&a->archive, errno,
+ "Failed to restore metadata");
+ ret = ARCHIVE_WARN;
+ }
+ unlink(tmp.s);
+ return (ret);
+}
+#endif
+
#ifndef HAVE_POSIX_ACL
/* Default empty function body to satisfy mainline code. */
static int
-set_acls(struct archive_write_disk *a)
+set_acls(struct archive_write_disk *a, int fd, const char *name,
+ struct archive_acl *acl)
{
(void)a; /* UNUSED */
+ (void)fd; /* UNUSED */
+ (void)name; /* UNUSED */
+ (void)acl; /* UNUSED */
return (ARCHIVE_OK);
}
@@ -2408,22 +2549,24 @@ set_acls(struct archive_write_disk *a)
* XXX TODO: What about ACL types other than ACCESS and DEFAULT?
*/
static int
-set_acls(struct archive_write_disk *a)
+set_acls(struct archive_write_disk *a, int fd, const char *name,
+ struct archive_acl *abstract_acl)
{
int ret;
- ret = set_acl(a, a->fd, a->entry, ACL_TYPE_ACCESS,
+ ret = set_acl(a, fd, name, abstract_acl, ACL_TYPE_ACCESS,
ARCHIVE_ENTRY_ACL_TYPE_ACCESS, "access");
if (ret != ARCHIVE_OK)
return (ret);
- ret = set_acl(a, a->fd, a->entry, ACL_TYPE_DEFAULT,
+ ret = set_acl(a, fd, name, abstract_acl, ACL_TYPE_DEFAULT,
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, "default");
return (ret);
}
static int
-set_acl(struct archive_write_disk *a, int fd, struct archive_entry *entry,
+set_acl(struct archive_write_disk *a, int fd, const char *name,
+ struct archive_acl *abstract_acl,
acl_type_t acl_type, int ae_requested_type, const char *tname)
{
acl_t acl;
@@ -2435,27 +2578,27 @@ set_acl(struct archive_write_disk *a, int fd, struct archive_entry *entry,
gid_t ae_gid;
const char *ae_name;
int entries;
- const char *name;
ret = ARCHIVE_OK;
- entries = archive_entry_acl_reset(entry, ae_requested_type);
+ entries = archive_acl_reset(abstract_acl, ae_requested_type);
if (entries == 0)
return (ARCHIVE_OK);
acl = acl_init(entries);
- while (archive_entry_acl_next(entry, ae_requested_type, &ae_type,
- &ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) {
+ while (archive_acl_next(&a->archive, abstract_acl,
+ ae_requested_type, &ae_type, &ae_permset, &ae_tag, &ae_id,
+ &ae_name) == ARCHIVE_OK) {
acl_create_entry(&acl, &acl_entry);
switch (ae_tag) {
case ARCHIVE_ENTRY_ACL_USER:
acl_set_tag_type(acl_entry, ACL_USER);
- ae_uid = a->lookup_uid(a->lookup_uid_data,
+ ae_uid = archive_write_disk_uid(&a->archive,
ae_name, ae_id);
acl_set_qualifier(acl_entry, &ae_uid);
break;
case ARCHIVE_ENTRY_ACL_GROUP:
acl_set_tag_type(acl_entry, ACL_GROUP);
- ae_gid = a->lookup_gid(a->lookup_gid_data,
+ ae_gid = archive_write_disk_gid(&a->archive,
ae_name, ae_id);
acl_set_qualifier(acl_entry, &ae_gid);
break;
@@ -2486,8 +2629,6 @@ set_acl(struct archive_write_disk *a, int fd, struct archive_entry *entry,
acl_add_perm(acl_permset, ACL_READ);
}
- name = archive_entry_pathname(entry);
-
/* Try restoring the ACL through 'fd' if we can. */
#if HAVE_ACL_SET_FD
if (fd >= 0 && acl_type == ACL_TYPE_ACCESS && acl_set_fd(fd, acl) == 0)
@@ -2509,9 +2650,10 @@ set_acl(struct archive_write_disk *a, int fd, struct archive_entry *entry,
}
#endif
-#if HAVE_LSETXATTR
+#if HAVE_LSETXATTR || HAVE_LSETEA
/*
- * Restore extended attributes - Linux implementation
+ * Restore extended attributes - Linux and AIX implementations:
+ * AIX' ea interface is syntaxwise identical to the Linux xattr interface.
*/
static int
set_xattrs(struct archive_write_disk *a)
@@ -2534,13 +2676,22 @@ set_xattrs(struct archive_write_disk *a)
if (a->fd >= 0)
e = fsetxattr(a->fd, name, value, size, 0);
else
+#elif HAVE_FSETEA
+ if (a->fd >= 0)
+ e = fsetea(a->fd, name, value, size, 0);
+ else
#endif
{
+#if HAVE_LSETXATTR
e = lsetxattr(archive_entry_pathname(entry),
name, value, size, 0);
+#elif HAVE_LSETEA
+ e = lsetea(archive_entry_pathname(entry),
+ name, value, size, 0);
+#endif
}
if (e == -1) {
- if (errno == ENOTSUP) {
+ if (errno == ENOTSUP || errno == ENOSYS) {
if (!warning_done) {
warning_done = 1;
archive_set_error(&a->archive, errno,
@@ -2607,7 +2758,7 @@ set_xattrs(struct archive_write_disk *a)
namespace, name, value, size);
}
if (e != (int)size) {
- if (errno == ENOTSUP) {
+ if (errno == ENOTSUP || errno == ENOSYS) {
if (!warning_done) {
warning_done = 1;
archive_set_error(&a->archive, errno,
@@ -2648,28 +2799,6 @@ set_xattrs(struct archive_write_disk *a)
}
#endif
-
-/*
- * Trivial implementations of gid/uid lookup functions.
- * These are normally overridden by the client, but these stub
- * versions ensure that we always have something that works.
- */
-static gid_t
-trivial_lookup_gid(void *private_data, const char *gname, gid_t gid)
-{
- (void)private_data; /* UNUSED */
- (void)gname; /* UNUSED */
- return (gid);
-}
-
-static uid_t
-trivial_lookup_uid(void *private_data, const char *uname, uid_t uid)
-{
- (void)private_data; /* UNUSED */
- (void)uname; /* UNUSED */
- return (uid);
-}
-
/*
* Test if file on disk is older than entry.
*/
@@ -2710,3 +2839,6 @@ older(struct stat *st, struct archive_entry *entry)
/* Same age or newer, so not older. */
return (0);
}
+
+#endif /* !_WIN32 || __CYGWIN__ */
+
diff --git a/libarchive/archive_write_disk_set_standard_lookup.c b/libarchive/archive_write_disk_set_standard_lookup.c
index cbc31a6f4ed0..5ee89a79a9c4 100644
--- a/libarchive/archive_write_disk_set_standard_lookup.c
+++ b/libarchive/archive_write_disk_set_standard_lookup.c
@@ -58,8 +58,8 @@ struct bucket {
static const size_t cache_size = 127;
static unsigned int hash(const char *);
-static gid_t lookup_gid(void *, const char *uname, gid_t);
-static uid_t lookup_uid(void *, const char *uname, uid_t);
+static int64_t lookup_gid(void *, const char *uname, int64_t);
+static int64_t lookup_uid(void *, const char *uname, int64_t);
static void cleanup(void *);
/*
@@ -93,8 +93,8 @@ archive_write_disk_set_standard_lookup(struct archive *a)
return (ARCHIVE_OK);
}
-static gid_t
-lookup_gid(void *private_data, const char *gname, gid_t gid)
+static int64_t
+lookup_gid(void *private_data, const char *gname, int64_t gid)
{
int h;
struct bucket *b;
@@ -163,8 +163,8 @@ lookup_gid(void *private_data, const char *gname, gid_t gid)
return (gid);
}
-static uid_t
-lookup_uid(void *private_data, const char *uname, uid_t uid)
+static int64_t
+lookup_uid(void *private_data, const char *uname, int64_t uid)
{
int h;
struct bucket *b;
diff --git a/libarchive/archive_write_disk_windows.c b/libarchive/archive_write_disk_windows.c
new file mode 100644
index 000000000000..8300e2e91c19
--- /dev/null
+++ b/libarchive/archive_write_disk_windows.c
@@ -0,0 +1,2514 @@
+/*-
+ * Copyright (c) 2003-2010 Tim Kientzle
+ * Copyright (c) 2011 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+__FBSDID("$FreeBSD$");
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_UTIME_H
+#include <sys/utime.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#include <winioctl.h>
+
+/* TODO: Support Mac OS 'quarantine' feature. This is really just a
+ * standard tag to mark files that have been downloaded as "tainted".
+ * On Mac OS, we should mark the extracted files as tainted if the
+ * archive being read was tainted. Windows has a similar feature; we
+ * should investigate ways to support this generically. */
+
+#include "archive.h"
+#include "archive_acl_private.h"
+#include "archive_string.h"
+#include "archive_entry.h"
+#include "archive_private.h"
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+#ifndef IO_REPARSE_TAG_SYMLINK
+/* Old SDKs do not provide IO_REPARSE_TAG_SYMLINK */
+#define IO_REPARSE_TAG_SYMLINK 0xA000000CL
+#endif
+
+static BOOL SetFilePointerEx_perso(HANDLE hFile,
+ LARGE_INTEGER liDistanceToMove,
+ PLARGE_INTEGER lpNewFilePointer,
+ DWORD dwMoveMethod)
+{
+ LARGE_INTEGER li;
+ li.QuadPart = liDistanceToMove.QuadPart;
+ li.LowPart = SetFilePointer(
+ hFile, li.LowPart, &li.HighPart, dwMoveMethod);
+ if(lpNewFilePointer) {
+ lpNewFilePointer->QuadPart = li.QuadPart;
+ }
+ return li.LowPart != -1 || GetLastError() == NO_ERROR;
+}
+
+struct fixup_entry {
+ struct fixup_entry *next;
+ struct archive_acl acl;
+ mode_t mode;
+ int64_t atime;
+ int64_t birthtime;
+ int64_t mtime;
+ int64_t ctime;
+ unsigned long atime_nanos;
+ unsigned long birthtime_nanos;
+ unsigned long mtime_nanos;
+ unsigned long ctime_nanos;
+ unsigned long fflags_set;
+ int fixup; /* bitmask of what needs fixing */
+ wchar_t *name;
+};
+
+/*
+ * We use a bitmask to track which operations remain to be done for
+ * this file. In particular, this helps us avoid unnecessary
+ * operations when it's possible to take care of one step as a
+ * side-effect of another. For example, mkdir() can specify the mode
+ * for the newly-created object but symlink() cannot. This means we
+ * can skip chmod() if mkdir() succeeded, but we must explicitly
+ * chmod() if we're trying to create a directory that already exists
+ * (mkdir() failed) or if we're restoring a symlink. Similarly, we
+ * need to verify UID/GID before trying to restore SUID/SGID bits;
+ * that verification can occur explicitly through a stat() call or
+ * implicitly because of a successful chown() call.
+ */
+#define TODO_MODE_FORCE 0x40000000
+#define TODO_MODE_BASE 0x20000000
+#define TODO_SUID 0x10000000
+#define TODO_SUID_CHECK 0x08000000
+#define TODO_SGID 0x04000000
+#define TODO_SGID_CHECK 0x02000000
+#define TODO_MODE (TODO_MODE_BASE|TODO_SUID|TODO_SGID)
+#define TODO_TIMES ARCHIVE_EXTRACT_TIME
+#define TODO_OWNER ARCHIVE_EXTRACT_OWNER
+#define TODO_FFLAGS ARCHIVE_EXTRACT_FFLAGS
+#define TODO_ACLS ARCHIVE_EXTRACT_ACL
+#define TODO_XATTR ARCHIVE_EXTRACT_XATTR
+#define TODO_MAC_METADATA ARCHIVE_EXTRACT_MAC_METADATA
+
+struct archive_write_disk {
+ struct archive archive;
+
+ mode_t user_umask;
+ struct fixup_entry *fixup_list;
+ struct fixup_entry *current_fixup;
+ int64_t user_uid;
+ int skip_file_set;
+ dev_t skip_file_dev;
+ ino_t skip_file_ino;
+ time_t start_time;
+
+ int64_t (*lookup_gid)(void *private, const char *gname, int64_t gid);
+ void (*cleanup_gid)(void *private);
+ void *lookup_gid_data;
+ int64_t (*lookup_uid)(void *private, const char *uname, int64_t uid);
+ void (*cleanup_uid)(void *private);
+ void *lookup_uid_data;
+
+ /*
+ * Full path of last file to satisfy symlink checks.
+ */
+ struct archive_wstring path_safe;
+
+ /*
+ * Cached stat data from disk for the current entry.
+ * If this is valid, pst points to st. Otherwise,
+ * pst is null.
+ */
+ BY_HANDLE_FILE_INFORMATION st;
+ BY_HANDLE_FILE_INFORMATION *pst;
+
+ /* Information about the object being restored right now. */
+ struct archive_entry *entry; /* Entry being extracted. */
+ wchar_t *name; /* Name of entry, possibly edited. */
+ struct archive_wstring _name_data; /* backing store for 'name' */
+ /* Tasks remaining for this object. */
+ int todo;
+ /* Tasks deferred until end-of-archive. */
+ int deferred;
+ /* Options requested by the client. */
+ int flags;
+ /* Handle for the file we're restoring. */
+ HANDLE fh;
+ /* Current offset for writing data to the file. */
+ int64_t offset;
+ /* Last offset actually written to disk. */
+ int64_t fd_offset;
+ /* Total bytes actually written to files. */
+ int64_t total_bytes_written;
+ /* Maximum size of file, -1 if unknown. */
+ int64_t filesize;
+ /* Dir we were in before this restore; only for deep paths. */
+ int restore_pwd;
+ /* Mode we should use for this entry; affected by _PERM and umask. */
+ mode_t mode;
+ /* UID/GID to use in restoring this entry. */
+ int64_t uid;
+ int64_t gid;
+};
+
+/*
+ * Default mode for dirs created automatically (will be modified by umask).
+ * Note that POSIX specifies 0777 for implicity-created dirs, "modified
+ * by the process' file creation mask."
+ */
+#define DEFAULT_DIR_MODE 0777
+/*
+ * Dir modes are restored in two steps: During the extraction, the permissions
+ * in the archive are modified to match the following limits. During
+ * the post-extract fixup pass, the permissions from the archive are
+ * applied.
+ */
+#define MINIMUM_DIR_MODE 0700
+#define MAXIMUM_DIR_MODE 0775
+
+static int check_symlinks(struct archive_write_disk *);
+static int create_filesystem_object(struct archive_write_disk *);
+static struct fixup_entry *current_fixup(struct archive_write_disk *, const wchar_t *pathname);
+#if defined(HAVE_FCHDIR) && defined(PATH_MAX)
+static void edit_deep_directories(struct archive_write_disk *ad);
+#endif
+static int cleanup_pathname(struct archive_write_disk *);
+static int create_dir(struct archive_write_disk *, wchar_t *);
+static int create_parent_dir(struct archive_write_disk *, wchar_t *);
+static int older(BY_HANDLE_FILE_INFORMATION *, struct archive_entry *);
+static int restore_entry(struct archive_write_disk *);
+#ifdef HAVE_POSIX_ACL
+static int set_acl(struct archive_write_disk *, int fd, const char *, struct archive_acl *,
+ acl_type_t, int archive_entry_acl_type, const char *tn);
+#endif
+static int set_acls(struct archive_write_disk *, HANDLE h, const wchar_t *, struct archive_acl *);
+static int set_xattrs(struct archive_write_disk *);
+static int set_fflags(struct archive_write_disk *);
+static int set_ownership(struct archive_write_disk *);
+static int set_mode(struct archive_write_disk *, int mode);
+static int set_times(struct archive_write_disk *, HANDLE, int, const wchar_t *,
+ time_t, long, time_t, long, time_t, long, time_t, long);
+static int set_times_from_entry(struct archive_write_disk *);
+static struct fixup_entry *sort_dir_list(struct fixup_entry *p);
+static ssize_t write_data_block(struct archive_write_disk *,
+ const char *, size_t);
+
+static struct archive_vtable *archive_write_disk_vtable(void);
+
+static int _archive_write_disk_close(struct archive *);
+static int _archive_write_disk_free(struct archive *);
+static int _archive_write_disk_header(struct archive *, struct archive_entry *);
+static int64_t _archive_write_disk_filter_bytes(struct archive *, int);
+static int _archive_write_disk_finish_entry(struct archive *);
+static ssize_t _archive_write_disk_data(struct archive *, const void *, size_t);
+static ssize_t _archive_write_disk_data_block(struct archive *, const void *, size_t, int64_t);
+
+#define bhfi_dev(bhfi) ((bhfi)->dwVolumeSerialNumber)
+/* Treat FileIndex as i-node. We should remove a sequence number
+ * which is high-16-bits of nFileIndexHigh. */
+#define bhfi_ino(bhfi) \
+ ((((int64_t)((bhfi)->nFileIndexHigh & 0x0000FFFFUL)) << 32) \
+ + (bhfi)->nFileIndexLow)
+#define bhfi_size(bhfi) \
+ ((((int64_t)(bhfi)->nFileSizeHigh) << 32) + (bhfi)->nFileSizeLow)
+
+static int
+file_information(struct archive_write_disk *a, wchar_t *path,
+ BY_HANDLE_FILE_INFORMATION *st, mode_t *mode, int sim_lstat)
+{
+ HANDLE h;
+ int r;
+ DWORD flag = FILE_FLAG_BACKUP_SEMANTICS;
+ WIN32_FIND_DATAW findData;
+
+ if (sim_lstat || mode != NULL) {
+ h = FindFirstFileW(path, &findData);
+ if (h == INVALID_HANDLE_VALUE &&
+ GetLastError() == ERROR_INVALID_NAME) {
+ wchar_t *full;
+ full = __la_win_permissive_name_w(path);
+ h = FindFirstFileW(full, &findData);
+ free(full);
+ }
+ if (h == INVALID_HANDLE_VALUE) {
+ la_dosmaperr(GetLastError());
+ return (-1);
+ }
+ FindClose(h);
+ }
+
+ /* Is symlink file ? */
+ if (sim_lstat &&
+ ((findData.dwFileAttributes
+ & FILE_ATTRIBUTE_REPARSE_POINT) &&
+ (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK)))
+ flag |= FILE_FLAG_OPEN_REPARSE_POINT;
+
+ h = CreateFileW(a->name, 0, 0, NULL,
+ OPEN_EXISTING, flag, NULL);
+ if (h == INVALID_HANDLE_VALUE &&
+ GetLastError() == ERROR_INVALID_NAME) {
+ wchar_t *full;
+ full = __la_win_permissive_name_w(path);
+ h = CreateFileW(full, 0, 0, NULL,
+ OPEN_EXISTING, flag, NULL);
+ free(full);
+ }
+ if (h == INVALID_HANDLE_VALUE) {
+ la_dosmaperr(GetLastError());
+ return (-1);
+ }
+ r = GetFileInformationByHandle(h, st);
+ CloseHandle(h);
+ if (r == 0) {
+ la_dosmaperr(GetLastError());
+ return (-1);
+ }
+
+ if (mode == NULL)
+ return (0);
+
+ *mode = S_IRUSR | S_IRGRP | S_IROTH;
+ if ((st->dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0)
+ *mode |= S_IWUSR | S_IWGRP | S_IWOTH;
+ if ((st->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
+ findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK)
+ *mode |= S_IFLNK;
+ else if (st->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ *mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
+ else {
+ const wchar_t *p;
+
+ *mode |= S_IFREG;
+ p = wcsrchr(path, L'.');
+ if (p != NULL && wcslen(p) == 4) {
+ switch (p[1]) {
+ case L'B': case L'b':
+ if ((p[2] == L'A' || p[2] == L'a' ) &&
+ (p[3] == L'T' || p[3] == L't' ))
+ *mode |= S_IXUSR | S_IXGRP | S_IXOTH;
+ break;
+ case L'C': case L'c':
+ if (((p[2] == L'M' || p[2] == L'm' ) &&
+ (p[3] == L'D' || p[3] == L'd' )) ||
+ ((p[2] == L'M' || p[2] == L'm' ) &&
+ (p[3] == L'D' || p[3] == L'd' )))
+ *mode |= S_IXUSR | S_IXGRP | S_IXOTH;
+ break;
+ case L'E': case L'e':
+ if ((p[2] == L'X' || p[2] == L'x' ) &&
+ (p[3] == L'E' || p[3] == L'e' ))
+ *mode |= S_IXUSR | S_IXGRP | S_IXOTH;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return (0);
+}
+
+/*
+ * Note: The path, for example, "aa/a/../b../c" will be converted to "aa/c"
+ * by GetFullPathNameW() W32 API, which __la_win_permissive_name_w uses.
+ * It means we cannot handle multiple dirs in one archive_entry.
+ * So we have to make the full-pathname in another way, which does not
+ * break "../" path string.
+ */
+int
+permissive_name_w(struct archive_write_disk *a)
+{
+ wchar_t *wn, *wnp;
+ wchar_t *ws, *wsp;
+ DWORD l;
+
+ wnp = a->name;
+ if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
+ wnp[2] == L'?' && wnp[3] == L'\\')
+ /* We have already a permissive name. */
+ return (0);
+
+ if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
+ wnp[2] == L'.' && wnp[3] == L'\\') {
+ /* This is a device name */
+ if (((wnp[4] >= L'a' && wnp[4] <= L'z') ||
+ (wnp[4] >= L'A' && wnp[4] <= L'Z')) &&
+ wnp[5] == L':' && wnp[6] == L'\\') {
+ wnp[2] = L'?';/* Not device name. */
+ return (0);
+ }
+ }
+
+ /*
+ * A full-pathname starting with a drive name like "C:\abc".
+ */
+ if (((wnp[0] >= L'a' && wnp[0] <= L'z') ||
+ (wnp[0] >= L'A' && wnp[0] <= L'Z')) &&
+ wnp[1] == L':' && wnp[2] == L'\\') {
+ wn = _wcsdup(wnp);
+ if (wn == NULL)
+ return (-1);
+ archive_wstring_ensure(&(a->_name_data), 4 + wcslen(wn) + 1);
+ a->name = a->_name_data.s;
+ /* Prepend "\\?\" */
+ archive_wstrncpy(&(a->_name_data), L"\\\\?\\", 4);
+ archive_wstrcat(&(a->_name_data), wn);
+ free(wn);
+ return (0);
+ }
+
+ /*
+ * A full-pathname pointig a network drive
+ * like "\\<server-name>\<share-name>\file".
+ */
+ if (wnp[0] == L'\\' && wnp[1] == L'\\' && wnp[2] != L'\\') {
+ const wchar_t *p = &wnp[2];
+
+ /* Skip server-name letters. */
+ while (*p != L'\\' && *p != L'\0')
+ ++p;
+ if (*p == L'\\') {
+ const wchar_t *rp = ++p;
+ /* Skip share-name letters. */
+ while (*p != L'\\' && *p != L'\0')
+ ++p;
+ if (*p == L'\\' && p != rp) {
+ /* Now, match patterns such as
+ * "\\server-name\share-name\" */
+ wn = _wcsdup(wnp);
+ if (wn == NULL)
+ return (-1);
+ archive_wstring_ensure(&(a->_name_data), 8 + wcslen(wn) + 1);
+ a->name = a->_name_data.s;
+ /* Prepend "\\?\UNC\" */
+ archive_wstrncpy(&(a->_name_data), L"\\\\?\\UNC\\", 8);
+ archive_wstrcat(&(a->_name_data), wn+2);
+ free(wn);
+ return (0);
+ }
+ }
+ return (0);
+ }
+
+ /*
+ * Get current working directory.
+ */
+ l = GetCurrentDirectoryW(0, NULL);
+ if (l == 0)
+ return (-1);
+ ws = malloc(l * sizeof(wchar_t));
+ l = GetCurrentDirectoryW(l, ws);
+ if (l == 0) {
+ free(ws);
+ return (-1);
+ }
+ wsp = ws;
+
+ /*
+ * A full-pathname starting without a drive name like "\abc".
+ */
+ if (wnp[0] == L'\\') {
+ wn = _wcsdup(wnp);
+ if (wn == NULL)
+ return (-1);
+ archive_wstring_ensure(&(a->_name_data), 4 + 2 + wcslen(wn) + 1);
+ a->name = a->_name_data.s;
+ /* Prepend "\\?\" and drive name. */
+ archive_wstrncpy(&(a->_name_data), L"\\\\?\\", 4);
+ archive_wstrncat(&(a->_name_data), wsp, 2);
+ archive_wstrcat(&(a->_name_data), wn);
+ free(wsp);
+ free(wn);
+ return (0);
+ }
+
+ wn = _wcsdup(wnp);
+ if (wn == NULL)
+ return (-1);
+ archive_wstring_ensure(&(a->_name_data), 4 + l + 1 + wcslen(wn) + 1);
+ a->name = a->_name_data.s;
+ /* Prepend "\\?\" and drive name. */
+ archive_wstrncpy(&(a->_name_data), L"\\\\?\\", 4);
+ archive_wstrncat(&(a->_name_data), wsp, l);
+ archive_wstrncat(&(a->_name_data), L"\\", 1);
+ archive_wstrcat(&(a->_name_data), wn);
+ a->name = a->_name_data.s;
+ free(wsp);
+ free(wn);
+ return (0);
+}
+
+int
+la_chmod(const wchar_t *path, mode_t mode)
+{
+ DWORD attr;
+ BOOL r;
+ wchar_t *fullname;
+ int ret = 0;
+
+ fullname = NULL;
+ attr = GetFileAttributesW(path);
+ if (attr == (DWORD)-1 &&
+ GetLastError() == ERROR_INVALID_NAME) {
+ fullname = __la_win_permissive_name_w(path);
+ attr = GetFileAttributesW(fullname);
+ }
+ if (attr == (DWORD)-1) {
+ la_dosmaperr(GetLastError());
+ ret = -1;
+ goto exit_chmode;
+ }
+ if (mode & _S_IWRITE)
+ attr &= ~FILE_ATTRIBUTE_READONLY;
+ else
+ attr |= FILE_ATTRIBUTE_READONLY;
+ if (fullname != NULL)
+ r = SetFileAttributesW(fullname, attr);
+ else
+ r = SetFileAttributesW(path, attr);
+ if (r == 0) {
+ la_dosmaperr(GetLastError());
+ ret = -1;
+ }
+exit_chmode:
+ free(fullname);
+ return (ret);
+}
+
+static void *
+la_GetFunctionKernel32(const char *name)
+{
+ static HINSTANCE lib;
+ static int set;
+ if (!set) {
+ set = 1;
+ lib = LoadLibrary("kernel32.dll");
+ }
+ if (lib == NULL) {
+ fprintf(stderr, "Can't load kernel32.dll?!\n");
+ exit(1);
+ }
+ return (void *)GetProcAddress(lib, name);
+}
+
+static int
+la_CreateHardLinkW(wchar_t *linkname, wchar_t *target)
+{
+ static BOOLEAN (WINAPI *f)(LPWSTR, LPWSTR, LPSECURITY_ATTRIBUTES);
+ static int set;
+ BOOL ret;
+
+ if (!set) {
+ set = 1;
+ f = la_GetFunctionKernel32("CreateHardLinkW");
+ }
+ if (!f)
+ return (0);
+ ret = (*f)(linkname, target, NULL);
+ if (!ret) {
+ /* Under windows 2000, it is necessary to remove
+ * the "\\?\" prefix. */
+#define IS_UNC(name) ((name[0] == L'U' || name[0] == L'u') && \
+ (name[1] == L'N' || name[1] == L'n') && \
+ (name[2] == L'C' || name[2] == L'c') && \
+ name[3] == L'\\')
+ if (!wcsncmp(linkname,L"\\\\?\\", 4)) {
+ linkname += 4;
+ if (IS_UNC(linkname))
+ linkname += 4;
+ }
+ if (!wcsncmp(target,L"\\\\?\\", 4)) {
+ target += 4;
+ if (IS_UNC(target))
+ target += 4;
+ }
+#undef IS_UNC
+ ret = (*f)(linkname, target, NULL);
+ }
+ return (ret);
+}
+
+static int
+la_ftruncate(HANDLE handle, int64_t length)
+{
+ LARGE_INTEGER distance;
+
+ if (GetFileType(handle) != FILE_TYPE_DISK) {
+ errno = EBADF;
+ return (-1);
+ }
+ distance.QuadPart = length;
+ if (!SetFilePointerEx_perso(handle, distance, NULL, FILE_BEGIN)) {
+ la_dosmaperr(GetLastError());
+ return (-1);
+ }
+ if (!SetEndOfFile(handle)) {
+ la_dosmaperr(GetLastError());
+ return (-1);
+ }
+ return (0);
+}
+
+static int
+lazy_stat(struct archive_write_disk *a)
+{
+ if (a->pst != NULL) {
+ /* Already have stat() data available. */
+ return (ARCHIVE_OK);
+ }
+ if (a->fh != INVALID_HANDLE_VALUE &&
+ GetFileInformationByHandle(a->fh, &a->st) == 0) {
+ a->pst = &a->st;
+ return (ARCHIVE_OK);
+ }
+
+ /*
+ * XXX At this point, symlinks should not be hit, otherwise
+ * XXX a race occurred. Do we want to check explicitly for that?
+ */
+ if (file_information(a, a->name, &a->st, NULL, 1) == 0) {
+ a->pst = &a->st;
+ return (ARCHIVE_OK);
+ }
+ archive_set_error(&a->archive, errno, "Couldn't stat file");
+ return (ARCHIVE_WARN);
+}
+
+static struct archive_vtable *
+archive_write_disk_vtable(void)
+{
+ static struct archive_vtable av;
+ static int inited = 0;
+
+ if (!inited) {
+ av.archive_close = _archive_write_disk_close;
+ av.archive_filter_bytes = _archive_write_disk_filter_bytes;
+ av.archive_free = _archive_write_disk_free;
+ av.archive_write_header = _archive_write_disk_header;
+ av.archive_write_finish_entry
+ = _archive_write_disk_finish_entry;
+ av.archive_write_data = _archive_write_disk_data;
+ av.archive_write_data_block = _archive_write_disk_data_block;
+ inited = 1;
+ }
+ return (&av);
+}
+
+static int64_t
+_archive_write_disk_filter_bytes(struct archive *_a, int n)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ (void)n; /* UNUSED */
+ if (n == -1 || n == 0)
+ return (a->total_bytes_written);
+ return (-1);
+}
+
+
+int
+archive_write_disk_set_options(struct archive *_a, int flags)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+
+ a->flags = flags;
+ return (ARCHIVE_OK);
+}
+
+
+/*
+ * Extract this entry to disk.
+ *
+ * TODO: Validate hardlinks. According to the standards, we're
+ * supposed to check each extracted hardlink and squawk if it refers
+ * to a file that we didn't restore. I'm not entirely convinced this
+ * is a good idea, but more importantly: Is there any way to validate
+ * hardlinks without keeping a complete list of filenames from the
+ * entire archive?? Ugh.
+ *
+ */
+static int
+_archive_write_disk_header(struct archive *_a, struct archive_entry *entry)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ struct fixup_entry *fe;
+ int ret, r;
+
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
+ "archive_write_disk_header");
+ archive_clear_error(&a->archive);
+ if (a->archive.state & ARCHIVE_STATE_DATA) {
+ r = _archive_write_disk_finish_entry(&a->archive);
+ if (r == ARCHIVE_FATAL)
+ return (r);
+ }
+
+ /* Set up for this particular entry. */
+ a->pst = NULL;
+ a->current_fixup = NULL;
+ a->deferred = 0;
+ if (a->entry) {
+ archive_entry_free(a->entry);
+ a->entry = NULL;
+ }
+ a->entry = archive_entry_clone(entry);
+ a->fh = INVALID_HANDLE_VALUE;
+ a->fd_offset = 0;
+ a->offset = 0;
+ a->restore_pwd = -1;
+ a->uid = a->user_uid;
+ a->mode = archive_entry_mode(a->entry);
+ if (archive_entry_size_is_set(a->entry))
+ a->filesize = archive_entry_size(a->entry);
+ else
+ a->filesize = -1;
+ archive_wstrcpy(&(a->_name_data), archive_entry_pathname_w(a->entry));
+ a->name = a->_name_data.s;
+ archive_clear_error(&a->archive);
+
+ /*
+ * Clean up the requested path. This is necessary for correct
+ * dir restores; the dir restore logic otherwise gets messed
+ * up by nonsense like "dir/.".
+ */
+ ret = cleanup_pathname(a);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+
+ /*
+ * Generate a full-pathname and use it from here.
+ */
+ if (permissive_name_w(a) < 0) {
+ errno = EINVAL;
+ return (ARCHIVE_FAILED);
+ }
+
+ /*
+ * Query the umask so we get predictable mode settings.
+ * This gets done on every call to _write_header in case the
+ * user edits their umask during the extraction for some
+ * reason.
+ */
+ umask(a->user_umask = umask(0));
+
+ /* Figure out what we need to do for this entry. */
+ a->todo = TODO_MODE_BASE;
+ if (a->flags & ARCHIVE_EXTRACT_PERM) {
+ a->todo |= TODO_MODE_FORCE; /* Be pushy about permissions. */
+ /*
+ * SGID requires an extra "check" step because we
+ * cannot easily predict the GID that the system will
+ * assign. (Different systems assign GIDs to files
+ * based on a variety of criteria, including process
+ * credentials and the gid of the enclosing
+ * directory.) We can only restore the SGID bit if
+ * the file has the right GID, and we only know the
+ * GID if we either set it (see set_ownership) or if
+ * we've actually called stat() on the file after it
+ * was restored. Since there are several places at
+ * which we might verify the GID, we need a TODO bit
+ * to keep track.
+ */
+ if (a->mode & S_ISGID)
+ a->todo |= TODO_SGID | TODO_SGID_CHECK;
+ /*
+ * Verifying the SUID is simpler, but can still be
+ * done in multiple ways, hence the separate "check" bit.
+ */
+ if (a->mode & S_ISUID)
+ a->todo |= TODO_SUID | TODO_SUID_CHECK;
+ } else {
+ /*
+ * User didn't request full permissions, so don't
+ * restore SUID, SGID bits and obey umask.
+ */
+ a->mode &= ~S_ISUID;
+ a->mode &= ~S_ISGID;
+ a->mode &= ~S_ISVTX;
+ a->mode &= ~a->user_umask;
+ }
+#if 0
+ if (a->flags & ARCHIVE_EXTRACT_OWNER)
+ a->todo |= TODO_OWNER;
+#endif
+ if (a->flags & ARCHIVE_EXTRACT_TIME)
+ a->todo |= TODO_TIMES;
+ if (a->flags & ARCHIVE_EXTRACT_ACL) {
+ if (archive_entry_filetype(a->entry) == AE_IFDIR)
+ a->deferred |= TODO_ACLS;
+ else
+ a->todo |= TODO_ACLS;
+ }
+ if (a->flags & ARCHIVE_EXTRACT_XATTR)
+ a->todo |= TODO_XATTR;
+ if (a->flags & ARCHIVE_EXTRACT_FFLAGS)
+ a->todo |= TODO_FFLAGS;
+ if (a->flags & ARCHIVE_EXTRACT_SECURE_SYMLINKS) {
+ ret = check_symlinks(a);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ }
+
+ ret = restore_entry(a);
+
+ /*
+ * TODO: There are rumours that some extended attributes must
+ * be restored before file data is written. If this is true,
+ * then we either need to write all extended attributes both
+ * before and after restoring the data, or find some rule for
+ * determining which must go first and which last. Due to the
+ * many ways people are using xattrs, this may prove to be an
+ * intractable problem.
+ */
+
+ /*
+ * Fixup uses the unedited pathname from archive_entry_pathname(),
+ * because it is relative to the base dir and the edited path
+ * might be relative to some intermediate dir as a result of the
+ * deep restore logic.
+ */
+ if (a->deferred & TODO_MODE) {
+ fe = current_fixup(a, archive_entry_pathname_w(entry));
+ fe->fixup |= TODO_MODE_BASE;
+ fe->mode = a->mode;
+ }
+
+ if ((a->deferred & TODO_TIMES)
+ && (archive_entry_mtime_is_set(entry)
+ || archive_entry_atime_is_set(entry))) {
+ fe = current_fixup(a, archive_entry_pathname_w(entry));
+ fe->mode = a->mode;
+ fe->fixup |= TODO_TIMES;
+ if (archive_entry_atime_is_set(entry)) {
+ fe->atime = archive_entry_atime(entry);
+ fe->atime_nanos = archive_entry_atime_nsec(entry);
+ } else {
+ /* If atime is unset, use start time. */
+ fe->atime = a->start_time;
+ fe->atime_nanos = 0;
+ }
+ if (archive_entry_mtime_is_set(entry)) {
+ fe->mtime = archive_entry_mtime(entry);
+ fe->mtime_nanos = archive_entry_mtime_nsec(entry);
+ } else {
+ /* If mtime is unset, use start time. */
+ fe->mtime = a->start_time;
+ fe->mtime_nanos = 0;
+ }
+ if (archive_entry_birthtime_is_set(entry)) {
+ fe->birthtime = archive_entry_birthtime(entry);
+ fe->birthtime_nanos = archive_entry_birthtime_nsec(entry);
+ } else {
+ /* If birthtime is unset, use mtime. */
+ fe->birthtime = fe->mtime;
+ fe->birthtime_nanos = fe->mtime_nanos;
+ }
+ }
+
+ if (a->deferred & TODO_ACLS) {
+ fe = current_fixup(a, archive_entry_pathname_w(entry));
+ archive_acl_copy(&fe->acl, archive_entry_acl(entry));
+ }
+
+ if (a->deferred & TODO_FFLAGS) {
+ fe = current_fixup(a, archive_entry_pathname_w(entry));
+ fe->fixup |= TODO_FFLAGS;
+ /* TODO: Complete this.. defer fflags from below. */
+ }
+
+ /*
+ * On Windows, A creating sparse file requires a special mark.
+ */
+ if (a->fh != INVALID_HANDLE_VALUE &&
+ archive_entry_sparse_count(entry) > 0) {
+ int64_t base = 0, offset, length;
+ int i, cnt = archive_entry_sparse_reset(entry);
+ int sparse = 0;
+
+ for (i = 0; i < cnt; i++) {
+ archive_entry_sparse_next(entry, &offset, &length);
+ if (offset - base >= 4096) {
+ sparse = 1;/* we have a hole. */
+ break;
+ }
+ base = offset + length;
+ }
+ if (sparse) {
+ DWORD dmy;
+ /* Mark this file as sparse. */
+ DeviceIoControl(a->fh, FSCTL_SET_SPARSE,
+ NULL, 0, NULL, 0, &dmy, NULL);
+ }
+ }
+
+ /* We've created the object and are ready to pour data into it. */
+ if (ret >= ARCHIVE_WARN)
+ a->archive.state = ARCHIVE_STATE_DATA;
+ /*
+ * If it's not open, tell our client not to try writing.
+ * In particular, dirs, links, etc, don't get written to.
+ */
+ if (a->fh == INVALID_HANDLE_VALUE) {
+ archive_entry_set_size(entry, 0);
+ a->filesize = 0;
+ }
+
+ return (ret);
+}
+
+int
+archive_write_disk_set_skip_file(struct archive *_a, int64_t d, int64_t i)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_write_disk_set_skip_file");
+ a->skip_file_set = 1;
+ a->skip_file_dev = d;
+ a->skip_file_ino = i;
+ return (ARCHIVE_OK);
+}
+
+static ssize_t
+write_data_block(struct archive_write_disk *a, const char *buff, size_t size)
+{
+ uint64_t start_size = size;
+ DWORD bytes_written = 0;
+ ssize_t block_size = 0, bytes_to_write;
+
+ if (size == 0)
+ return (ARCHIVE_OK);
+
+ if (a->filesize == 0 || a->fh == INVALID_HANDLE_VALUE) {
+ archive_set_error(&a->archive, 0,
+ "Attempt to write to an empty file");
+ return (ARCHIVE_WARN);
+ }
+
+ if (a->flags & ARCHIVE_EXTRACT_SPARSE) {
+ /* XXX TODO XXX Is there a more appropriate choice here ? */
+ /* This needn't match the filesystem allocation size. */
+ block_size = 16*1024;
+ }
+
+ /* If this write would run beyond the file size, truncate it. */
+ if (a->filesize >= 0 && (int64_t)(a->offset + size) > a->filesize)
+ start_size = size = (size_t)(a->filesize - a->offset);
+
+ /* Write the data. */
+ while (size > 0) {
+ if (block_size == 0) {
+ bytes_to_write = size;
+ } else {
+ /* We're sparsifying the file. */
+ const char *p, *end;
+ int64_t block_end;
+
+ /* Skip leading zero bytes. */
+ for (p = buff, end = buff + size; p < end; ++p) {
+ if (*p != '\0')
+ break;
+ }
+ a->offset += p - buff;
+ size -= p - buff;
+ buff = p;
+ if (size == 0)
+ break;
+
+ /* Calculate next block boundary after offset. */
+ block_end
+ = (a->offset / block_size + 1) * block_size;
+
+ /* If the adjusted write would cross block boundary,
+ * truncate it to the block boundary. */
+ bytes_to_write = size;
+ if (a->offset + bytes_to_write > block_end)
+ bytes_to_write = block_end - a->offset;
+ }
+ /* Seek if necessary to the specified offset. */
+ if (a->offset != a->fd_offset) {
+ LARGE_INTEGER distance;
+ distance.QuadPart = a->offset;
+ if (SetFilePointerEx_perso(a->fh, distance, NULL, FILE_BEGIN) == 0) {
+ DWORD lasterr = GetLastError();
+ if (lasterr == ERROR_ACCESS_DENIED)
+ errno = EBADF;
+ else
+ la_dosmaperr(lasterr);
+ archive_set_error(&a->archive, errno,
+ "Seek failed");
+ return (ARCHIVE_FATAL);
+ }
+ a->fd_offset = a->offset;
+ }
+ if (!WriteFile(a->fh, buff, (uint32_t)bytes_to_write,
+ &bytes_written, NULL)) {
+ DWORD lasterr;
+
+ lasterr = GetLastError();
+ if (lasterr == ERROR_ACCESS_DENIED)
+ errno = EBADF;
+ else
+ la_dosmaperr(lasterr);
+ archive_set_error(&a->archive, errno, "Write failed");
+ return (ARCHIVE_WARN);
+ }
+ buff += bytes_written;
+ size -= bytes_written;
+ a->total_bytes_written += bytes_written;
+ a->offset += bytes_written;
+ a->fd_offset = a->offset;
+ }
+ return (start_size - size);
+}
+
+static ssize_t
+_archive_write_disk_data_block(struct archive *_a,
+ const void *buff, size_t size, int64_t offset)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ ssize_t r;
+
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_DATA, "archive_write_data_block");
+
+ a->offset = offset;
+ r = write_data_block(a, buff, size);
+ if (r < ARCHIVE_OK)
+ return (r);
+ if ((size_t)r < size) {
+ archive_set_error(&a->archive, 0,
+ "Write request too large");
+ return (ARCHIVE_WARN);
+ }
+ return (ARCHIVE_OK);
+}
+
+static ssize_t
+_archive_write_disk_data(struct archive *_a, const void *buff, size_t size)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_DATA, "archive_write_data");
+
+ return (write_data_block(a, buff, size));
+}
+
+static int
+_archive_write_disk_finish_entry(struct archive *_a)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ int ret = ARCHIVE_OK;
+
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
+ "archive_write_finish_entry");
+ if (a->archive.state & ARCHIVE_STATE_HEADER)
+ return (ARCHIVE_OK);
+ archive_clear_error(&a->archive);
+
+ /* Pad or truncate file to the right size. */
+ if (a->fh == INVALID_HANDLE_VALUE) {
+ /* There's no file. */
+ } else if (a->filesize < 0) {
+ /* File size is unknown, so we can't set the size. */
+ } else if (a->fd_offset == a->filesize) {
+ /* Last write ended at exactly the filesize; we're done. */
+ /* Hopefully, this is the common case. */
+ } else {
+ if (la_ftruncate(a->fh, a->filesize) == -1) {
+ archive_set_error(&a->archive, errno,
+ "File size could not be restored");
+ return (ARCHIVE_FAILED);
+ }
+ }
+
+ /* Restore metadata. */
+
+ /*
+ * Look up the "real" UID only if we're going to need it.
+ * TODO: the TODO_SGID condition can be dropped here, can't it?
+ */
+ if (a->todo & (TODO_OWNER | TODO_SUID | TODO_SGID)) {
+ a->uid = archive_write_disk_uid(&a->archive,
+ archive_entry_uname(a->entry),
+ archive_entry_uid(a->entry));
+ }
+ /* Look up the "real" GID only if we're going to need it. */
+ /* TODO: the TODO_SUID condition can be dropped here, can't it? */
+ if (a->todo & (TODO_OWNER | TODO_SGID | TODO_SUID)) {
+ a->gid = archive_write_disk_gid(&a->archive,
+ archive_entry_gname(a->entry),
+ archive_entry_gid(a->entry));
+ }
+
+ /*
+ * Restore ownership before set_mode tries to restore suid/sgid
+ * bits. If we set the owner, we know what it is and can skip
+ * a stat() call to examine the ownership of the file on disk.
+ */
+ if (a->todo & TODO_OWNER)
+ ret = set_ownership(a);
+
+ /*
+ * set_mode must precede ACLs on systems such as Solaris and
+ * FreeBSD where setting the mode implicitly clears extended ACLs
+ */
+ if (a->todo & TODO_MODE) {
+ int r2 = set_mode(a, a->mode);
+ if (r2 < ret) ret = r2;
+ }
+
+ /*
+ * Security-related extended attributes (such as
+ * security.capability on Linux) have to be restored last,
+ * since they're implicitly removed by other file changes.
+ */
+ if (a->todo & TODO_XATTR) {
+ int r2 = set_xattrs(a);
+ if (r2 < ret) ret = r2;
+ }
+
+ /*
+ * Some flags prevent file modification; they must be restored after
+ * file contents are written.
+ */
+ if (a->todo & TODO_FFLAGS) {
+ int r2 = set_fflags(a);
+ if (r2 < ret) ret = r2;
+ }
+
+ /*
+ * Time must follow most other metadata;
+ * otherwise atime will get changed.
+ */
+ if (a->todo & TODO_TIMES) {
+ int r2 = set_times_from_entry(a);
+ if (r2 < ret) ret = r2;
+ }
+
+ /*
+ * ACLs must be restored after timestamps because there are
+ * ACLs that prevent attribute changes (including time).
+ */
+ if (a->todo & TODO_ACLS) {
+ int r2 = set_acls(a, a->fh,
+ archive_entry_pathname_w(a->entry),
+ archive_entry_acl(a->entry));
+ if (r2 < ret) ret = r2;
+ }
+
+ /* If there's an fd, we can close it now. */
+ if (a->fh != INVALID_HANDLE_VALUE) {
+ CloseHandle(a->fh);
+ a->fh = INVALID_HANDLE_VALUE;
+ }
+ /* If there's an entry, we can release it now. */
+ if (a->entry) {
+ archive_entry_free(a->entry);
+ a->entry = NULL;
+ }
+ a->archive.state = ARCHIVE_STATE_HEADER;
+ return (ret);
+}
+
+int
+archive_write_disk_set_group_lookup(struct archive *_a,
+ void *private_data,
+ int64_t (*lookup_gid)(void *private, const char *gname, int64_t gid),
+ void (*cleanup_gid)(void *private))
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_write_disk_set_group_lookup");
+
+ if (a->cleanup_gid != NULL && a->lookup_gid_data != NULL)
+ (a->cleanup_gid)(a->lookup_gid_data);
+
+ a->lookup_gid = lookup_gid;
+ a->cleanup_gid = cleanup_gid;
+ a->lookup_gid_data = private_data;
+ return (ARCHIVE_OK);
+}
+
+int
+archive_write_disk_set_user_lookup(struct archive *_a,
+ void *private_data,
+ int64_t (*lookup_uid)(void *private, const char *uname, int64_t uid),
+ void (*cleanup_uid)(void *private))
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_write_disk_set_user_lookup");
+
+ if (a->cleanup_uid != NULL && a->lookup_uid_data != NULL)
+ (a->cleanup_uid)(a->lookup_uid_data);
+
+ a->lookup_uid = lookup_uid;
+ a->cleanup_uid = cleanup_uid;
+ a->lookup_uid_data = private_data;
+ return (ARCHIVE_OK);
+}
+
+int64_t
+archive_write_disk_gid(struct archive *_a, const char *name, int64_t id)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_write_disk_gid");
+ if (a->lookup_gid)
+ return (a->lookup_gid)(a->lookup_gid_data, name, id);
+ return (id);
+}
+
+int64_t
+archive_write_disk_uid(struct archive *_a, const char *name, int64_t id)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_write_disk_uid");
+ if (a->lookup_uid)
+ return (a->lookup_uid)(a->lookup_uid_data, name, id);
+ return (id);
+}
+
+/*
+ * Create a new archive_write_disk object and initialize it with global state.
+ */
+struct archive *
+archive_write_disk_new(void)
+{
+ struct archive_write_disk *a;
+
+ a = (struct archive_write_disk *)malloc(sizeof(*a));
+ if (a == NULL)
+ return (NULL);
+ memset(a, 0, sizeof(*a));
+ a->archive.magic = ARCHIVE_WRITE_DISK_MAGIC;
+ /* We're ready to write a header immediately. */
+ a->archive.state = ARCHIVE_STATE_HEADER;
+ a->archive.vtable = archive_write_disk_vtable();
+ a->start_time = time(NULL);
+ /* Query and restore the umask. */
+ umask(a->user_umask = umask(0));
+ if (archive_wstring_ensure(&a->path_safe, 512) == NULL) {
+ free(a);
+ return (NULL);
+ }
+ return (&a->archive);
+}
+
+static int
+disk_unlink(wchar_t *path)
+{
+ wchar_t *fullname;
+ int r;
+
+ r = _wunlink(path);
+ if (r != 0 && GetLastError() == ERROR_INVALID_NAME) {
+ fullname = __la_win_permissive_name_w(path);
+ r = _wunlink(fullname);
+ free(fullname);
+ }
+ return (r);
+}
+
+static int
+disk_rmdir(wchar_t *path)
+{
+ wchar_t *fullname;
+ int r;
+
+ r = _wrmdir(path);
+ if (r != 0 && GetLastError() == ERROR_INVALID_NAME) {
+ fullname = __la_win_permissive_name_w(path);
+ r = _wrmdir(fullname);
+ free(fullname);
+ }
+ return (r);
+}
+
+/*
+ * The main restore function.
+ */
+static int
+restore_entry(struct archive_write_disk *a)
+{
+ int ret = ARCHIVE_OK, en;
+
+ if (a->flags & ARCHIVE_EXTRACT_UNLINK && !S_ISDIR(a->mode)) {
+ /*
+ * TODO: Fix this. Apparently, there are platforms
+ * that still allow root to hose the entire filesystem
+ * by unlinking a dir. The S_ISDIR() test above
+ * prevents us from using unlink() here if the new
+ * object is a dir, but that doesn't mean the old
+ * object isn't a dir.
+ */
+ if (disk_unlink(a->name) == 0) {
+ /* We removed it, reset cached stat. */
+ a->pst = NULL;
+ } else if (errno == ENOENT) {
+ /* File didn't exist, that's just as good. */
+ } else if (disk_rmdir(a->name) == 0) {
+ /* It was a dir, but now it's gone. */
+ a->pst = NULL;
+ } else {
+ /* We tried, but couldn't get rid of it. */
+ archive_set_error(&a->archive, errno,
+ "Could not unlink");
+ return(ARCHIVE_FAILED);
+ }
+ }
+
+ /* Try creating it first; if this fails, we'll try to recover. */
+ en = create_filesystem_object(a);
+
+ if ((en == ENOTDIR || en == ENOENT)
+ && !(a->flags & ARCHIVE_EXTRACT_NO_AUTODIR)) {
+ wchar_t *full;
+ /* If the parent dir doesn't exist, try creating it. */
+ create_parent_dir(a, a->name);
+ /* Now try to create the object again. */
+ full = __la_win_permissive_name_w(a->name);
+ if (full == NULL) {
+ en = EINVAL;
+ } else {
+ /* Remove multiple directories such as "a/../b../c" */
+ archive_wstrcpy(&(a->_name_data), full);
+ a->name = a->_name_data.s;
+ free(full);
+ en = create_filesystem_object(a);
+ }
+ }
+
+ if ((en == EISDIR || en == EEXIST)
+ && (a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE)) {
+ /* If we're not overwriting, we're done. */
+ archive_entry_unset_size(a->entry);
+ return (ARCHIVE_OK);
+ }
+
+ /*
+ * Some platforms return EISDIR if you call
+ * open(O_WRONLY | O_EXCL | O_CREAT) on a directory, some
+ * return EEXIST. POSIX is ambiguous, requiring EISDIR
+ * for open(O_WRONLY) on a dir and EEXIST for open(O_EXCL | O_CREAT)
+ * on an existing item.
+ */
+ if (en == EISDIR) {
+ /* A dir is in the way of a non-dir, rmdir it. */
+ if (disk_rmdir(a->name) != 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't remove already-existing dir");
+ return (ARCHIVE_FAILED);
+ }
+ a->pst = NULL;
+ /* Try again. */
+ en = create_filesystem_object(a);
+ } else if (en == EEXIST) {
+ mode_t st_mode;
+ /*
+ * We know something is in the way, but we don't know what;
+ * we need to find out before we go any further.
+ */
+ int r = 0;
+ /*
+ * The SECURE_SYMLINK logic has already removed a
+ * symlink to a dir if the client wants that. So
+ * follow the symlink if we're creating a dir.
+ */
+ if (S_ISDIR(a->mode))
+ r = file_information(a, a->name, &a->st, &st_mode, 0);
+ /*
+ * If it's not a dir (or it's a broken symlink),
+ * then don't follow it.
+ */
+ if (r != 0 || !S_ISDIR(a->mode))
+ r = file_information(a, a->name, &a->st, &st_mode, 1);
+ if (r != 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't stat existing object");
+ return (ARCHIVE_FAILED);
+ }
+
+ /*
+ * NO_OVERWRITE_NEWER doesn't apply to directories.
+ */
+ if ((a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER)
+ && !S_ISDIR(st_mode)) {
+ if (!older(&(a->st), a->entry)) {
+ archive_entry_unset_size(a->entry);
+ return (ARCHIVE_OK);
+ }
+ }
+
+ /* If it's our archive, we're done. */
+ if (a->skip_file_set &&
+ bhfi_dev(&a->st) == a->skip_file_dev &&
+ bhfi_ino(&a->st) == a->skip_file_ino) {
+ archive_set_error(&a->archive, 0, "Refusing to overwrite archive");
+ return (ARCHIVE_FAILED);
+ }
+
+ if (!S_ISDIR(st_mode)) {
+ /* A non-dir is in the way, unlink it. */
+ if (disk_unlink(a->name) != 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't unlink already-existing object");
+ return (ARCHIVE_FAILED);
+ }
+ a->pst = NULL;
+ /* Try again. */
+ en = create_filesystem_object(a);
+ } else if (!S_ISDIR(a->mode)) {
+ /* A dir is in the way of a non-dir, rmdir it. */
+ if (disk_rmdir(a->name) != 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't remove already-existing dir");
+ return (ARCHIVE_FAILED);
+ }
+ /* Try again. */
+ en = create_filesystem_object(a);
+ } else {
+ /*
+ * There's a dir in the way of a dir. Don't
+ * waste time with rmdir()/mkdir(), just fix
+ * up the permissions on the existing dir.
+ * Note that we don't change perms on existing
+ * dirs unless _EXTRACT_PERM is specified.
+ */
+ if ((a->mode != st_mode)
+ && (a->todo & TODO_MODE_FORCE))
+ a->deferred |= (a->todo & TODO_MODE);
+ /* Ownership doesn't need deferred fixup. */
+ en = 0; /* Forget the EEXIST. */
+ }
+ }
+
+ if (en) {
+ /* Everything failed; give up here. */
+ archive_set_error(&a->archive, en, "Can't create '%s'",
+ a->name);
+ return (ARCHIVE_FAILED);
+ }
+
+ a->pst = NULL; /* Cached stat data no longer valid. */
+ return (ret);
+}
+
+/*
+ * Returns 0 if creation succeeds, or else returns errno value from
+ * the failed system call. Note: This function should only ever perform
+ * a single system call.
+ */
+static int
+create_filesystem_object(struct archive_write_disk *a)
+{
+ /* Create the entry. */
+ const wchar_t *linkname;
+ wchar_t *fullname;
+ mode_t final_mode, mode;
+ int r;
+
+ /* We identify hard/symlinks according to the link names. */
+ /* Since link(2) and symlink(2) don't handle modes, we're done here. */
+ linkname = archive_entry_hardlink_w(a->entry);
+ if (linkname != NULL) {
+ wchar_t *linkfull, *namefull;
+
+ linkfull = __la_win_permissive_name_w(linkname);
+ namefull = __la_win_permissive_name_w(a->name);
+ if (linkfull == NULL || namefull == NULL) {
+ errno = EINVAL;
+ r = -1;
+ } else {
+ r = la_CreateHardLinkW(namefull, linkfull);
+ if (r == 0) {
+ la_dosmaperr(GetLastError());
+ r = errno;
+ } else
+ r = 0;
+ }
+ /*
+ * New cpio and pax formats allow hardlink entries
+ * to carry data, so we may have to open the file
+ * for hardlink entries.
+ *
+ * If the hardlink was successfully created and
+ * the archive doesn't have carry data for it,
+ * consider it to be non-authoritative for meta data.
+ * This is consistent with GNU tar and BSD pax.
+ * If the hardlink does carry data, let the last
+ * archive entry decide ownership.
+ */
+ if (r == 0 && a->filesize <= 0) {
+ a->todo = 0;
+ a->deferred = 0;
+ } else if (r == 0 && a->filesize > 0) {
+ a->fh = CreateFileW(namefull, GENERIC_WRITE, 0, NULL,
+ TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (a->fh == INVALID_HANDLE_VALUE) {
+ la_dosmaperr(GetLastError());
+ r = errno;
+ }
+ }
+ free(linkfull);
+ free(namefull);
+ return (r);
+ }
+ linkname = archive_entry_symlink_w(a->entry);
+ if (linkname != NULL) {
+#if HAVE_SYMLINK
+ return symlink(linkname, a->name) ? errno : 0;
+#else
+ return (EPERM);
+#endif
+ }
+
+ /*
+ * The remaining system calls all set permissions, so let's
+ * try to take advantage of that to avoid an extra chmod()
+ * call. (Recall that umask is set to zero right now!)
+ */
+
+ /* Mode we want for the final restored object (w/o file type bits). */
+ final_mode = a->mode & 07777;
+ /*
+ * The mode that will actually be restored in this step. Note
+ * that SUID, SGID, etc, require additional work to ensure
+ * security, so we never restore them at this point.
+ */
+ mode = final_mode & 0777 & a->user_umask;
+
+ switch (a->mode & AE_IFMT) {
+ default:
+ /* POSIX requires that we fall through here. */
+ /* FALLTHROUGH */
+ case AE_IFREG:
+ fullname = a->name;
+ /* O_WRONLY | O_CREAT | O_EXCL */
+ a->fh = CreateFileW(fullname, GENERIC_WRITE, 0, NULL,
+ CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (a->fh == INVALID_HANDLE_VALUE &&
+ GetLastError() == ERROR_INVALID_NAME &&
+ fullname == a->name) {
+ fullname = __la_win_permissive_name_w(a->name);
+ a->fh = CreateFileW(fullname, GENERIC_WRITE, 0, NULL,
+ CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
+ }
+ if (a->fh == INVALID_HANDLE_VALUE) {
+ if (GetLastError() == ERROR_ACCESS_DENIED) {
+ DWORD attr;
+ /* Simulate an errno of POSIX system. */
+ attr = GetFileAttributesW(fullname);
+ if (attr == (DWORD)-1)
+ la_dosmaperr(GetLastError());
+ else if (attr & FILE_ATTRIBUTE_DIRECTORY)
+ errno = EISDIR;
+ else
+ errno = EACCES;
+ } else
+ la_dosmaperr(GetLastError());
+ r = 1;
+ } else
+ r = 0;
+ if (fullname != a->name)
+ free(fullname);
+ break;
+ case AE_IFCHR:
+ case AE_IFBLK:
+ /* TODO: Find a better way to warn about our inability
+ * to restore a block device node. */
+ return (EINVAL);
+ case AE_IFDIR:
+ mode = (mode | MINIMUM_DIR_MODE) & MAXIMUM_DIR_MODE;
+ fullname = a->name;
+ r = CreateDirectoryW(fullname, NULL);
+ if (r == 0 && GetLastError() == ERROR_INVALID_NAME &&
+ fullname == a->name) {
+ fullname = __la_win_permissive_name_w(a->name);
+ r = CreateDirectoryW(fullname, NULL);
+ }
+ if (r != 0) {
+ r = 0;
+ /* Defer setting dir times. */
+ a->deferred |= (a->todo & TODO_TIMES);
+ a->todo &= ~TODO_TIMES;
+ /* Never use an immediate chmod(). */
+ /* We can't avoid the chmod() entirely if EXTRACT_PERM
+ * because of SysV SGID inheritance. */
+ if ((mode != final_mode)
+ || (a->flags & ARCHIVE_EXTRACT_PERM))
+ a->deferred |= (a->todo & TODO_MODE);
+ a->todo &= ~TODO_MODE;
+ } else {
+ la_dosmaperr(GetLastError());
+ r = -1;
+ }
+ if (fullname != a->name)
+ free(fullname);
+ break;
+ case AE_IFIFO:
+ /* TODO: Find a better way to warn about our inability
+ * to restore a fifo. */
+ return (EINVAL);
+ }
+
+ /* All the system calls above set errno on failure. */
+ if (r)
+ return (errno);
+
+ /* If we managed to set the final mode, we've avoided a chmod(). */
+ if (mode == final_mode)
+ a->todo &= ~TODO_MODE;
+ return (0);
+}
+
+/*
+ * Cleanup function for archive_extract. Mostly, this involves processing
+ * the fixup list, which is used to address a number of problems:
+ * * Dir permissions might prevent us from restoring a file in that
+ * dir, so we restore the dir with minimum 0700 permissions first,
+ * then correct the mode at the end.
+ * * Similarly, the act of restoring a file touches the directory
+ * and changes the timestamp on the dir, so we have to touch-up dir
+ * timestamps at the end as well.
+ * * Some file flags can interfere with the restore by, for example,
+ * preventing the creation of hardlinks to those files.
+ * * Mac OS extended metadata includes ACLs, so must be deferred on dirs.
+ *
+ * Note that tar/cpio do not require that archives be in a particular
+ * order; there is no way to know when the last file has been restored
+ * within a directory, so there's no way to optimize the memory usage
+ * here by fixing up the directory any earlier than the
+ * end-of-archive.
+ *
+ * XXX TODO: Directory ACLs should be restored here, for the same
+ * reason we set directory perms here. XXX
+ */
+static int
+_archive_write_disk_close(struct archive *_a)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ struct fixup_entry *next, *p;
+ int ret;
+
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
+ "archive_write_disk_close");
+ ret = _archive_write_disk_finish_entry(&a->archive);
+
+ /* Sort dir list so directories are fixed up in depth-first order. */
+ p = sort_dir_list(a->fixup_list);
+
+ while (p != NULL) {
+ a->pst = NULL; /* Mark stat cache as out-of-date. */
+ if (p->fixup & TODO_TIMES) {
+ set_times(a, INVALID_HANDLE_VALUE, p->mode, p->name,
+ p->atime, p->atime_nanos,
+ p->birthtime, p->birthtime_nanos,
+ p->mtime, p->mtime_nanos,
+ p->ctime, p->ctime_nanos);
+ }
+ if (p->fixup & TODO_MODE_BASE)
+ la_chmod(p->name, p->mode);
+ if (p->fixup & TODO_ACLS)
+ set_acls(a, INVALID_HANDLE_VALUE, p->name, &p->acl);
+ next = p->next;
+ archive_acl_clear(&p->acl);
+ free(p->name);
+ free(p);
+ p = next;
+ }
+ a->fixup_list = NULL;
+ return (ret);
+}
+
+static int
+_archive_write_disk_free(struct archive *_a)
+{
+ struct archive_write_disk *a;
+ int ret;
+ if (_a == NULL)
+ return (ARCHIVE_OK);
+ archive_check_magic(_a, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_write_disk_free");
+ a = (struct archive_write_disk *)_a;
+ ret = _archive_write_disk_close(&a->archive);
+ archive_write_disk_set_group_lookup(&a->archive, NULL, NULL, NULL);
+ archive_write_disk_set_user_lookup(&a->archive, NULL, NULL, NULL);
+ if (a->entry)
+ archive_entry_free(a->entry);
+ archive_wstring_free(&a->_name_data);
+ archive_string_free(&a->archive.error_string);
+ archive_wstring_free(&a->path_safe);
+ a->archive.magic = 0;
+ __archive_clean(&a->archive);
+ free(a);
+ return (ret);
+}
+
+/*
+ * Simple O(n log n) merge sort to order the fixup list. In
+ * particular, we want to restore dir timestamps depth-first.
+ */
+static struct fixup_entry *
+sort_dir_list(struct fixup_entry *p)
+{
+ struct fixup_entry *a, *b, *t;
+
+ if (p == NULL)
+ return (NULL);
+ /* A one-item list is already sorted. */
+ if (p->next == NULL)
+ return (p);
+
+ /* Step 1: split the list. */
+ t = p;
+ a = p->next->next;
+ while (a != NULL) {
+ /* Step a twice, t once. */
+ a = a->next;
+ if (a != NULL)
+ a = a->next;
+ t = t->next;
+ }
+ /* Now, t is at the mid-point, so break the list here. */
+ b = t->next;
+ t->next = NULL;
+ a = p;
+
+ /* Step 2: Recursively sort the two sub-lists. */
+ a = sort_dir_list(a);
+ b = sort_dir_list(b);
+
+ /* Step 3: Merge the returned lists. */
+ /* Pick the first element for the merged list. */
+ if (wcscmp(a->name, b->name) > 0) {
+ t = p = a;
+ a = a->next;
+ } else {
+ t = p = b;
+ b = b->next;
+ }
+
+ /* Always put the later element on the list first. */
+ while (a != NULL && b != NULL) {
+ if (wcscmp(a->name, b->name) > 0) {
+ t->next = a;
+ a = a->next;
+ } else {
+ t->next = b;
+ b = b->next;
+ }
+ t = t->next;
+ }
+
+ /* Only one list is non-empty, so just splice it on. */
+ if (a != NULL)
+ t->next = a;
+ if (b != NULL)
+ t->next = b;
+
+ return (p);
+}
+
+/*
+ * Returns a new, initialized fixup entry.
+ *
+ * TODO: Reduce the memory requirements for this list by using a tree
+ * structure rather than a simple list of names.
+ */
+static struct fixup_entry *
+new_fixup(struct archive_write_disk *a, const wchar_t *pathname)
+{
+ struct fixup_entry *fe;
+
+ fe = (struct fixup_entry *)calloc(1, sizeof(struct fixup_entry));
+ if (fe == NULL)
+ return (NULL);
+ fe->next = a->fixup_list;
+ a->fixup_list = fe;
+ fe->fixup = 0;
+ fe->name = _wcsdup(pathname);
+ return (fe);
+}
+
+/*
+ * Returns a fixup structure for the current entry.
+ */
+static struct fixup_entry *
+current_fixup(struct archive_write_disk *a, const wchar_t *pathname)
+{
+ if (a->current_fixup == NULL)
+ a->current_fixup = new_fixup(a, pathname);
+ return (a->current_fixup);
+}
+
+/* TODO: Make this work. */
+/*
+ * TODO: The deep-directory support bypasses this; disable deep directory
+ * support if we're doing symlink checks.
+ */
+/*
+ * TODO: Someday, integrate this with the deep dir support; they both
+ * scan the path and both can be optimized by comparing against other
+ * recent paths.
+ */
+/* TODO: Extend this to support symlinks on Windows Vista and later. */
+static int
+check_symlinks(struct archive_write_disk *a)
+{
+ wchar_t *pn, *p;
+ wchar_t c;
+ int r;
+ BY_HANDLE_FILE_INFORMATION st;
+ mode_t st_mode;
+
+ /*
+ * Guard against symlink tricks. Reject any archive entry whose
+ * destination would be altered by a symlink.
+ */
+ /* Whatever we checked last time doesn't need to be re-checked. */
+ pn = a->name;
+ p = a->path_safe.s;
+ while ((*pn != '\0') && (*p == *pn))
+ ++p, ++pn;
+ c = pn[0];
+ /* Keep going until we've checked the entire name. */
+ while (pn[0] != '\0' && (pn[0] != '\\' || pn[1] != '\0')) {
+ /* Skip the next path element. */
+ while (*pn != '\0' && *pn != '\\')
+ ++pn;
+ c = pn[0];
+ pn[0] = '\0';
+ /* Check that we haven't hit a symlink. */
+ r = file_information(a, a->name, &st, &st_mode, 1);
+ if (r != 0) {
+ /* We've hit a dir that doesn't exist; stop now. */
+ if (errno == ENOENT)
+ break;
+ } else if (S_ISLNK(st_mode)) {
+ if (c == '\0') {
+ /*
+ * Last element is symlink; remove it
+ * so we can overwrite it with the
+ * item being extracted.
+ */
+ if (disk_unlink(a->name)) {
+ archive_set_error(&a->archive, errno,
+ "Could not remove symlink %s",
+ a->name);
+ pn[0] = c;
+ return (ARCHIVE_FAILED);
+ }
+ a->pst = NULL;
+ /*
+ * Even if we did remove it, a warning
+ * is in order. The warning is silly,
+ * though, if we're just replacing one
+ * symlink with another symlink.
+ */
+ if (!S_ISLNK(a->mode)) {
+ archive_set_error(&a->archive, 0,
+ "Removing symlink %s",
+ a->name);
+ }
+ /* Symlink gone. No more problem! */
+ pn[0] = c;
+ return (0);
+ } else if (a->flags & ARCHIVE_EXTRACT_UNLINK) {
+ /* User asked us to remove problems. */
+ if (disk_unlink(a->name) != 0) {
+ archive_set_error(&a->archive, 0,
+ "Cannot remove intervening symlink %s",
+ a->name);
+ pn[0] = c;
+ return (ARCHIVE_FAILED);
+ }
+ a->pst = NULL;
+ } else {
+ archive_set_error(&a->archive, 0,
+ "Cannot extract through symlink %s",
+ a->name);
+ pn[0] = c;
+ return (ARCHIVE_FAILED);
+ }
+ }
+ }
+ pn[0] = c;
+ /* We've checked and/or cleaned the whole path, so remember it. */
+ archive_wstrcpy(&a->path_safe, a->name);
+ return (ARCHIVE_OK);
+}
+
+static int
+guidword(wchar_t *p, int n)
+{
+ int i;
+
+ for (i = 0; i < n; i++) {
+ if ((*p >= L'0' && *p <= L'9') ||
+ (*p >= L'a' && *p <= L'f') ||
+ (*p >= L'A' && *p <= L'F'))
+ p++;
+ else
+ return (-1);
+ }
+ return (0);
+}
+
+/*
+ * Canonicalize the pathname. In particular, this strips duplicate
+ * '\' characters, '.' elements, and trailing '\'. It also raises an
+ * error for an empty path, a trailing '..' or (if _SECURE_NODOTDOT is
+ * set) any '..' in the path.
+ */
+static int
+cleanup_pathname(struct archive_write_disk *a)
+{
+ wchar_t *dest, *src, *p, *top;
+ wchar_t separator = L'\0';
+
+ p = a->name;
+ if (*p == L'\0') {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Invalid empty pathname");
+ return (ARCHIVE_FAILED);
+ }
+
+ /* Replace '/' by '\' */
+ for (; *p != L'\0'; p++) {
+ if (*p == L'/')
+ *p = L'\\';
+ }
+ p = a->name;
+
+ /* Skip leading "\\.\" or "\\?\" or "\\?\UNC\" or
+ * "\\?\Volume{GUID}\"
+ * (absolute path prefixes used by Windows API) */
+ if (p[0] == L'\\' && p[1] == L'\\' &&
+ (p[2] == L'.' || p[2] == L'?') && p[3] == L'\\')
+ {
+ /* A path begin with "\\?\UNC\" */
+ if (p[2] == L'?' &&
+ (p[4] == L'U' || p[4] == L'u') &&
+ (p[5] == L'N' || p[5] == L'n') &&
+ (p[6] == L'C' || p[6] == L'c') &&
+ p[7] == L'\\')
+ p += 8;
+ /* A path begin with "\\?\Volume{GUID}\" */
+ else if (p[2] == L'?' &&
+ (p[4] == L'V' || p[4] == L'v') &&
+ (p[5] == L'O' || p[5] == L'o') &&
+ (p[6] == L'L' || p[6] == L'l') &&
+ (p[7] == L'U' || p[7] == L'u') &&
+ (p[8] == L'M' || p[8] == L'm') &&
+ (p[9] == L'E' || p[9] == L'e') &&
+ p[10] == L'{') {
+ if (guidword(p+11, 8) == 0 && p[19] == L'-' &&
+ guidword(p+20, 4) == 0 && p[24] == L'-' &&
+ guidword(p+25, 4) == 0 && p[29] == L'-' &&
+ guidword(p+30, 4) == 0 && p[34] == L'-' &&
+ guidword(p+35, 12) == 0 && p[47] == L'}' &&
+ p[48] == L'\\')
+ p += 49;
+ else
+ p += 4;
+ /* A path begin with "\\.\PhysicalDriveX" */
+ } else if (p[2] == L'.' &&
+ (p[4] == L'P' || p[4] == L'p') &&
+ (p[5] == L'H' || p[5] == L'h') &&
+ (p[6] == L'Y' || p[6] == L'y') &&
+ (p[7] == L'S' || p[7] == L's') &&
+ (p[8] == L'I' || p[8] == L'i') &&
+ (p[9] == L'C' || p[9] == L'c') &&
+ (p[9] == L'A' || p[9] == L'a') &&
+ (p[9] == L'L' || p[9] == L'l') &&
+ (p[9] == L'D' || p[9] == L'd') &&
+ (p[9] == L'R' || p[9] == L'r') &&
+ (p[9] == L'I' || p[9] == L'i') &&
+ (p[9] == L'V' || p[9] == L'v') &&
+ (p[9] == L'E' || p[9] == L'e') &&
+ (p[10] >= L'0' && p[10] <= L'9') &&
+ p[11] == L'\0') {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Path is a physical drive name");
+ return (ARCHIVE_FAILED);
+ } else
+ p += 4;
+ }
+
+ /* Skip leading drive letter from archives created
+ * on Windows. */
+ if (((p[0] >= L'a' && p[0] <= L'z') ||
+ (p[0] >= L'A' && p[0] <= L'Z')) &&
+ p[1] == L':') {
+ if (p[2] == L'\0') {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Path is a drive name");
+ return (ARCHIVE_FAILED);
+ }
+ if (p[2] == L'\\')
+ p += 2;
+ }
+
+ top = dest = src = p;
+ /* Rewrite the path name if its character is a unusable. */
+ for (; *p != L'\0'; p++) {
+ if (*p == L':' || *p == L'*' || *p == L'?' || *p == L'"' ||
+ *p == L'<' || *p == L'>' || *p == L'|')
+ *p = L'_';
+ }
+ /* Skip leading '\'. */
+ if (*src == L'\\')
+ separator = *src++;
+
+ /* Scan the pathname one element at a time. */
+ for (;;) {
+ /* src points to first char after '\' */
+ if (src[0] == L'\0') {
+ break;
+ } else if (src[0] == L'\\') {
+ /* Found '\\'('//'), ignore second one. */
+ src++;
+ continue;
+ } else if (src[0] == L'.') {
+ if (src[1] == L'\0') {
+ /* Ignore trailing '.' */
+ break;
+ } else if (src[1] == L'\\') {
+ /* Skip '.\'. */
+ src += 2;
+ continue;
+ } else if (src[1] == L'.') {
+ if (src[2] == L'\\' || src[2] == L'\0') {
+ /* Conditionally warn about '..' */
+ if (a->flags &
+ ARCHIVE_EXTRACT_SECURE_NODOTDOT) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Path contains '..'");
+ return (ARCHIVE_FAILED);
+ }
+ }
+ /*
+ * Note: Under no circumstances do we
+ * remove '..' elements. In
+ * particular, restoring
+ * '\foo\..\bar\' should create the
+ * 'foo' dir as a side-effect.
+ */
+ }
+ }
+
+ /* Copy current element, including leading '\'. */
+ if (separator)
+ *dest++ = L'\\';
+ while (*src != L'\0' && *src != L'\\') {
+ *dest++ = *src++;
+ }
+
+ if (*src == L'\0')
+ break;
+
+ /* Skip '\' separator. */
+ separator = *src++;
+ }
+ /*
+ * We've just copied zero or more path elements, not including the
+ * final '\'.
+ */
+ if (dest == top) {
+ /*
+ * Nothing got copied. The path must have been something
+ * like '.' or '\' or './' or '/././././/./'.
+ */
+ if (separator)
+ *dest++ = L'\\';
+ else
+ *dest++ = L'.';
+ }
+ /* Terminate the result. */
+ *dest = L'\0';
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Create the parent directory of the specified path, assuming path
+ * is already in mutable storage.
+ */
+static int
+create_parent_dir(struct archive_write_disk *a, wchar_t *path)
+{
+ wchar_t *slash;
+ int r;
+
+ /* Remove tail element to obtain parent name. */
+ slash = wcsrchr(path, L'\\');
+ if (slash == NULL)
+ return (ARCHIVE_OK);
+ *slash = L'\0';
+ r = create_dir(a, path);
+ *slash = L'\\';
+ return (r);
+}
+
+/*
+ * Create the specified dir, recursing to create parents as necessary.
+ *
+ * Returns ARCHIVE_OK if the path exists when we're done here.
+ * Otherwise, returns ARCHIVE_FAILED.
+ * Assumes path is in mutable storage; path is unchanged on exit.
+ */
+static int
+create_dir(struct archive_write_disk *a, wchar_t *path)
+{
+ BY_HANDLE_FILE_INFORMATION st;
+ struct fixup_entry *le;
+ wchar_t *slash, *base, *full;
+ mode_t mode_final, mode, st_mode;
+ int r;
+
+ /* Check for special names and just skip them. */
+ slash = wcsrchr(path, L'\\');
+ if (slash == NULL)
+ base = path;
+ else
+ base = slash + 1;
+
+ if (base[0] == L'\0' ||
+ (base[0] == L'.' && base[1] == L'\0') ||
+ (base[0] == L'.' && base[1] == L'.' && base[2] == L'\0')) {
+ /* Don't bother trying to create null path, '.', or '..'. */
+ if (slash != NULL) {
+ *slash = L'\0';
+ r = create_dir(a, path);
+ *slash = L'\\';
+ return (r);
+ }
+ return (ARCHIVE_OK);
+ }
+
+ /*
+ * Yes, this should be stat() and not lstat(). Using lstat()
+ * here loses the ability to extract through symlinks. Also note
+ * that this should not use the a->st cache.
+ */
+ if (file_information(a, path, &st, &st_mode, 0) == 0) {
+ if (S_ISDIR(st_mode))
+ return (ARCHIVE_OK);
+ if ((a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE)) {
+ archive_set_error(&a->archive, EEXIST,
+ "Can't create directory '%s'", path);
+ return (ARCHIVE_FAILED);
+ }
+ if (disk_unlink(path) != 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't create directory '%s': "
+ "Conflicting file cannot be removed",
+ path);
+ return (ARCHIVE_FAILED);
+ }
+ } else if (errno != ENOENT && errno != ENOTDIR) {
+ /* Stat failed? */
+ archive_set_error(&a->archive, errno, "Can't test directory '%s'", path);
+ return (ARCHIVE_FAILED);
+ } else if (slash != NULL) {
+ *slash = '\0';
+ r = create_dir(a, path);
+ *slash = '\\';
+ if (r != ARCHIVE_OK)
+ return (r);
+ }
+
+ /*
+ * Mode we want for the final restored directory. Per POSIX,
+ * implicitly-created dirs must be created obeying the umask.
+ * There's no mention whether this is different for privileged
+ * restores (which the rest of this code handles by pretending
+ * umask=0). I've chosen here to always obey the user's umask for
+ * implicit dirs, even if _EXTRACT_PERM was specified.
+ */
+ mode_final = DEFAULT_DIR_MODE & ~a->user_umask;
+ /* Mode we want on disk during the restore process. */
+ mode = mode_final;
+ mode |= MINIMUM_DIR_MODE;
+ mode &= MAXIMUM_DIR_MODE;
+ /*
+ * Apply __la_win_permissive_name_w to path in order to
+ * remove '../' path string.
+ */
+ full = __la_win_permissive_name_w(path);
+ if (full == NULL)
+ errno = EINVAL;
+ else if (CreateDirectoryW(full, NULL) != 0) {
+ if (mode != mode_final) {
+ le = new_fixup(a, path);
+ le->fixup |=TODO_MODE_BASE;
+ le->mode = mode_final;
+ }
+ free(full);
+ return (ARCHIVE_OK);
+ } else {
+ la_dosmaperr(GetLastError());
+ }
+ free(full);
+
+ /*
+ * Without the following check, a/b/../b/c/d fails at the
+ * second visit to 'b', so 'd' can't be created. Note that we
+ * don't add it to the fixup list here, as it's already been
+ * added.
+ */
+ if (file_information(a, path, &st, &st_mode, 0) == 0 && S_ISDIR(st_mode))
+ return (ARCHIVE_OK);
+
+ archive_set_error(&a->archive, errno, "Failed to create dir '%s'",
+ path);
+ return (ARCHIVE_FAILED);
+}
+
+/*
+ * Note: Although we can skip setting the user id if the desired user
+ * id matches the current user, we cannot skip setting the group, as
+ * many systems set the gid based on the containing directory. So
+ * we have to perform a chown syscall if we want to set the SGID
+ * bit. (The alternative is to stat() and then possibly chown(); it's
+ * more efficient to skip the stat() and just always chown().) Note
+ * that a successful chown() here clears the TODO_SGID_CHECK bit, which
+ * allows set_mode to skip the stat() check for the GID.
+ */
+static int
+set_ownership(struct archive_write_disk *a)
+{
+/* unfortunately, on win32 there is no 'root' user with uid 0,
+ so we just have to try the chown and see if it works */
+
+ /* If we know we can't change it, don't bother trying. */
+ if (a->user_uid != 0 && a->user_uid != a->uid) {
+ archive_set_error(&a->archive, errno,
+ "Can't set UID=%jd", (intmax_t)a->uid);
+ return (ARCHIVE_WARN);
+ }
+
+ archive_set_error(&a->archive, errno,
+ "Can't set user=%jd/group=%jd for %s",
+ (intmax_t)a->uid, (intmax_t)a->gid, a->name);
+ return (ARCHIVE_WARN);
+}
+
+static int
+set_times(struct archive_write_disk *a,
+ HANDLE h, int mode, const wchar_t *name,
+ time_t atime, long atime_nanos,
+ time_t birthtime, long birthtime_nanos,
+ time_t mtime, long mtime_nanos,
+ time_t ctime, long ctime_nanos)
+{
+#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
+#define WINTIME(sec, nsec) ((Int32x32To64(sec, 10000000) + EPOC_TIME)\
+ + (((nsec)/1000)*10))
+
+ HANDLE hw = 0;
+ ULARGE_INTEGER wintm;
+ FILETIME *pfbtime;
+ FILETIME fatime, fbtime, fmtime;
+
+ (void)ctime; /* UNUSED */
+ (void)ctime_nanos; /* UNUSED */
+
+ if (h != INVALID_HANDLE_VALUE) {
+ hw = NULL;
+ } else {
+ wchar_t *ws;
+
+ if (S_ISLNK(mode))
+ return (ARCHIVE_OK);
+ ws = __la_win_permissive_name_w(name);
+ if (ws == NULL)
+ goto settimes_failed;
+ hw = CreateFileW(ws, FILE_WRITE_ATTRIBUTES,
+ 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ free(ws);
+ if (hw == INVALID_HANDLE_VALUE)
+ goto settimes_failed;
+ h = hw;
+ }
+
+ wintm.QuadPart = WINTIME(atime, atime_nanos);
+ fatime.dwLowDateTime = wintm.LowPart;
+ fatime.dwHighDateTime = wintm.HighPart;
+ wintm.QuadPart = WINTIME(mtime, mtime_nanos);
+ fmtime.dwLowDateTime = wintm.LowPart;
+ fmtime.dwHighDateTime = wintm.HighPart;
+ /*
+ * SetFileTime() supports birthtime.
+ */
+ if (birthtime > 0 || birthtime_nanos > 0) {
+ wintm.QuadPart = WINTIME(birthtime, birthtime_nanos);
+ fbtime.dwLowDateTime = wintm.LowPart;
+ fbtime.dwHighDateTime = wintm.HighPart;
+ pfbtime = &fbtime;
+ } else
+ pfbtime = NULL;
+ if (SetFileTime(h, pfbtime, &fatime, &fmtime) == 0)
+ goto settimes_failed;
+ CloseHandle(hw);
+ return (ARCHIVE_OK);
+
+settimes_failed:
+ CloseHandle(hw);
+ archive_set_error(&a->archive, EINVAL, "Can't restore time");
+ return (ARCHIVE_WARN);
+}
+
+static int
+set_times_from_entry(struct archive_write_disk *a)
+{
+ time_t atime, birthtime, mtime, ctime;
+ long atime_nsec, birthtime_nsec, mtime_nsec, ctime_nsec;
+
+ /* Suitable defaults. */
+ atime = birthtime = mtime = ctime = a->start_time;
+ atime_nsec = birthtime_nsec = mtime_nsec = ctime_nsec = 0;
+
+ /* If no time was provided, we're done. */
+ if (!archive_entry_atime_is_set(a->entry)
+ && !archive_entry_birthtime_is_set(a->entry)
+ && !archive_entry_mtime_is_set(a->entry))
+ return (ARCHIVE_OK);
+
+ if (archive_entry_atime_is_set(a->entry)) {
+ atime = archive_entry_atime(a->entry);
+ atime_nsec = archive_entry_atime_nsec(a->entry);
+ }
+ if (archive_entry_birthtime_is_set(a->entry)) {
+ birthtime = archive_entry_birthtime(a->entry);
+ birthtime_nsec = archive_entry_birthtime_nsec(a->entry);
+ }
+ if (archive_entry_mtime_is_set(a->entry)) {
+ mtime = archive_entry_mtime(a->entry);
+ mtime_nsec = archive_entry_mtime_nsec(a->entry);
+ }
+ if (archive_entry_ctime_is_set(a->entry)) {
+ ctime = archive_entry_ctime(a->entry);
+ ctime_nsec = archive_entry_ctime_nsec(a->entry);
+ }
+
+ return set_times(a, a->fh, a->mode, a->name,
+ atime, atime_nsec,
+ birthtime, birthtime_nsec,
+ mtime, mtime_nsec,
+ ctime, ctime_nsec);
+}
+
+static int
+set_mode(struct archive_write_disk *a, int mode)
+{
+ int r = ARCHIVE_OK;
+ mode &= 07777; /* Strip off file type bits. */
+
+ if (a->todo & TODO_SGID_CHECK) {
+ /*
+ * If we don't know the GID is right, we must stat()
+ * to verify it. We can't just check the GID of this
+ * process, since systems sometimes set GID from
+ * the enclosing dir or based on ACLs.
+ */
+ if ((r = lazy_stat(a)) != ARCHIVE_OK)
+ return (r);
+ if (0 != a->gid) {
+ mode &= ~ S_ISGID;
+ }
+ /* While we're here, double-check the UID. */
+ if (0 != a->uid
+ && (a->todo & TODO_SUID)) {
+ mode &= ~ S_ISUID;
+ }
+ a->todo &= ~TODO_SGID_CHECK;
+ a->todo &= ~TODO_SUID_CHECK;
+ } else if (a->todo & TODO_SUID_CHECK) {
+ /*
+ * If we don't know the UID is right, we can just check
+ * the user, since all systems set the file UID from
+ * the process UID.
+ */
+ if (a->user_uid != a->uid) {
+ mode &= ~ S_ISUID;
+ }
+ a->todo &= ~TODO_SUID_CHECK;
+ }
+
+ if (S_ISLNK(a->mode)) {
+#ifdef HAVE_LCHMOD
+ /*
+ * If this is a symlink, use lchmod(). If the
+ * platform doesn't support lchmod(), just skip it. A
+ * platform that doesn't provide a way to set
+ * permissions on symlinks probably ignores
+ * permissions on symlinks, so a failure here has no
+ * impact.
+ */
+ if (lchmod(a->name, mode) != 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't set permissions to 0%o", (int)mode);
+ r = ARCHIVE_WARN;
+ }
+#endif
+ } else if (!S_ISDIR(a->mode)) {
+ /*
+ * If it's not a symlink and not a dir, then use
+ * fchmod() or chmod(), depending on whether we have
+ * an fd. Dirs get their perms set during the
+ * post-extract fixup, which is handled elsewhere.
+ */
+#ifdef HAVE_FCHMOD
+ if (a->fd >= 0) {
+ if (fchmod(a->fd, mode) != 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't set permissions to 0%o", (int)mode);
+ r = ARCHIVE_WARN;
+ }
+ } else
+#endif
+ /* If this platform lacks fchmod(), then
+ * we'll just use chmod(). */
+ if (la_chmod(a->name, mode) != 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't set permissions to 0%o", (int)mode);
+ r = ARCHIVE_WARN;
+ }
+ }
+ return (r);
+}
+
+static int
+set_fflags(struct archive_write_disk *a)
+{
+ (void)a; /* UNUSED */
+ return (ARCHIVE_OK);
+}
+
+/* Default empty function body to satisfy mainline code. */
+static int
+set_acls(struct archive_write_disk *a, HANDLE h, const wchar_t *name,
+ struct archive_acl *acl)
+{
+ (void)a; /* UNUSED */
+ (void)h; /* UNUSED */
+ (void)name; /* UNUSED */
+ (void)acl; /* UNUSED */
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Restore extended attributes - stub implementation for unsupported systems
+ */
+static int
+set_xattrs(struct archive_write_disk *a)
+{
+ static int warning_done = 0;
+
+ /* If there aren't any extended attributes, then it's okay not
+ * to extract them, otherwise, issue a single warning. */
+ if (archive_entry_xattr_count(a->entry) != 0 && !warning_done) {
+ warning_done = 1;
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Cannot restore extended attributes on this system");
+ return (ARCHIVE_WARN);
+ }
+ /* Warning was already emitted; suppress further warnings. */
+ return (ARCHIVE_OK);
+}
+
+static void
+fileTimeToUtc(const FILETIME *filetime, time_t *time, long *ns)
+{
+ ULARGE_INTEGER utc;
+
+ utc.HighPart = filetime->dwHighDateTime;
+ utc.LowPart = filetime->dwLowDateTime;
+ if (utc.QuadPart >= EPOC_TIME) {
+ utc.QuadPart -= EPOC_TIME;
+ /* milli seconds base */
+ *time = (time_t)(utc.QuadPart / 10000000);
+ /* nano seconds base */
+ *ns = (long)(utc.QuadPart % 10000000) * 100;
+ } else {
+ *time = 0;
+ *ns = 0;
+ }
+}
+/*
+ * Test if file on disk is older than entry.
+ */
+static int
+older(BY_HANDLE_FILE_INFORMATION *st, struct archive_entry *entry)
+{
+ time_t sec;
+ long nsec;
+
+ fileTimeToUtc(&st->ftLastWriteTime, &sec, &nsec);
+ /* First, test the seconds and return if we have a definite answer. */
+ /* Definitely older. */
+ if (sec < archive_entry_mtime(entry))
+ return (1);
+ /* Definitely younger. */
+ if (sec > archive_entry_mtime(entry))
+ return (0);
+ if (nsec < archive_entry_mtime_nsec(entry))
+ return (1);
+ /* Same age or newer, so not older. */
+ return (0);
+}
+
+#endif /* _WIN32 && !__CYGWIN__ */
+
diff --git a/libarchive/archive_write_filter.3 b/libarchive/archive_write_filter.3
new file mode 100644
index 000000000000..00438d405c11
--- /dev/null
+++ b/libarchive/archive_write_filter.3
@@ -0,0 +1,98 @@
+.\" Copyright (c) 2003-2011 Tim Kientzle
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd March 23, 2011
+.Dt ARCHIVE_WRITE_FILTER 3
+.Os
+.Sh NAME
+.Nm archive_write_add_filter_bzip2 ,
+.Nm archive_write_add_filter_compress ,
+.Nm archive_write_add_filter_gzip ,
+.Nm archive_write_add_filter_lzip ,
+.Nm archive_write_add_filter_lzma ,
+.Nm archive_write_add_filter_none ,
+.Nm archive_write_add_filter_program ,
+.Nm archive_write_add_filter_xz
+.Sh SYNOPSIS
+.In archive.h
+.Ft int
+.Fn archive_write_add_filter_bzip2 "struct archive *"
+.Ft int
+.Fn archive_write_add_filter_compress "struct archive *"
+.Ft int
+.Fn archive_write_add_filter_gzip "struct archive *"
+.Ft int
+.Fn archive_write_add_filter_lzip "struct archive *"
+.Ft int
+.Fn archive_write_add_filter_lzma "struct archive *"
+.Ft int
+.Fn archive_write_add_filter_none "struct archive *"
+.Ft int
+.Fn archive_write_add_filter_program "struct archive *" "const char * cmd"
+.Ft int
+.Fn archive_write_add_filter_xz "struct archive *"
+.Sh DESCRIPTION
+.Bl -tag -width indent
+.It Xo
+.Fn archive_write_add_filter_bzip2 ,
+.Fn archive_write_add_filter_compress ,
+.Fn archive_write_add_filter_gzip ,
+.Fn archive_write_add_filter_lzip ,
+.Fn archive_write_add_filter_lzma ,
+.Fn archive_write_add_filter_xz ,
+.Xc
+The resulting archive will be compressed as specified.
+Note that the compressed output is always properly blocked.
+.It Fn archive_write_add_filter_none
+This is never necessary.
+It is provided only for backwards compatibility.
+.It Fn archive_write_add_filter_program
+The archive will be fed into the specified compression program.
+The output of that program is blocked and written to the client
+write callbacks.
+.El
+.Sh RETURN VALUES
+These functions return
+.Cm ARCHIVE_OK
+on success, or
+.Cm ARCHIVE_FATAL .
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.\"
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_write 3 ,
+.Xr archive_write_format 3 ,
+.Xr archive_write_set_options 3 ,
+.Xr cpio 5 ,
+.Xr mtree 5 ,
+.Xr tar 5
diff --git a/libarchive/archive_write_finish_entry.3 b/libarchive/archive_write_finish_entry.3
new file mode 100644
index 000000000000..3add601295fb
--- /dev/null
+++ b/libarchive/archive_write_finish_entry.3
@@ -0,0 +1,74 @@
+.\" Copyright (c) 2003-2011 Tim Kientzle
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD: head/lib/libarchive/archive_write.3 201110 2009-12-28 03:31:29Z kientzle $
+.\"
+.Dd March 23, 2011
+.Dt ARCHIVE_WRITE_FINISH_ENTRY 3
+.Os
+.Sh NAME
+.Nm archive_write_finish_entry
+.Nd functions for creating archives
+.Sh SYNOPSIS
+.In archive.h
+.Ft int
+.Fn archive_write_finish_entry "struct archive *"
+.Sh DESCRIPTION
+Close out the entry just written.
+In particular, this writes out the final padding required by some formats.
+Ordinarily, clients never need to call this, as it
+is called automatically by
+.Fn archive_write_next_header
+and
+.Fn archive_write_close
+as needed.
+.\" .Sh EXAMPLE
+.Sh RETURN VALUES
+This function returns
+.Cm ARCHIVE_OK
+on success, or one of several non-zero
+error codes for errors.
+Specific error codes include:
+.Cm ARCHIVE_RETRY
+for operations that might succeed if retried,
+.Cm ARCHIVE_WARN
+for unusual conditions that do not prevent further operations, and
+.Cm ARCHIVE_FATAL
+for serious errors that make remaining operations impossible.
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.\"
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_write_data 3 ,
+.Xr archive_write_set_options 3 ,
+.Xr cpio 5 ,
+.Xr mtree 5 ,
+.Xr tar 5
diff --git a/libarchive/archive_write_format.3 b/libarchive/archive_write_format.3
new file mode 100644
index 000000000000..e12e7d8658ad
--- /dev/null
+++ b/libarchive/archive_write_format.3
@@ -0,0 +1,98 @@
+.\" Copyright (c) 2003-2011 Tim Kientzle
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd March 23, 2011
+.Dt ARCHIVE_WRITE_FORMAT 3
+.Os
+.Sh NAME
+.Nm archive_write_set_format_cpio ,
+.Nm archive_write_set_format_pax ,
+.Nm archive_write_set_format_pax_restricted ,
+.Nm archive_write_set_format_shar ,
+.Nm archive_write_set_format_shar_dump ,
+.Nm archive_write_set_format_ustar
+.Nd functions for creating archives
+.Sh SYNOPSIS
+.In archive.h
+.Ft int
+.Fn archive_write_set_format_cpio "struct archive *"
+.Ft int
+.Fn archive_write_set_format_pax "struct archive *"
+.Ft int
+.Fn archive_write_set_format_pax_restricted "struct archive *"
+.Ft int
+.Fn archive_write_set_format_shar "struct archive *"
+.Ft int
+.Fn archive_write_set_format_shar_dump "struct archive *"
+.Ft int
+.Fn archive_write_set_format_ustar "struct archive *"
+.Sh DESCRIPTION
+These functions set the format that will be used for the archive.
+.Pp
+The library can write
+POSIX octet-oriented cpio format archives,
+POSIX-standard
+.Dq pax interchange
+format archives,
+traditional
+.Dq shar
+archives,
+enhanced
+.Dq dump
+shar archives that store a variety of file attributes and handle binary files,
+and
+POSIX-standard
+.Dq ustar
+archives.
+The pax interchange format is a backwards-compatible tar format that
+adds key/value attributes to each entry and supports arbitrary
+filenames, linknames, uids, sizes, etc.
+.Dq Restricted pax interchange format
+is the library default; this is the same as pax format, but suppresses
+the pax extended header for most normal files.
+In most cases, this will result in ordinary ustar archives.
+.\"
+.Sh RETURN VALUES
+These functions return
+.Cm ARCHIVE_OK
+on success, or
+.Cm ARCHIVE_FATAL .
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.\"
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_write 3 ,
+.Xr archive_write_set_options 3 ,
+.Xr cpio 5 ,
+.Xr mtree 5 ,
+.Xr tar 5
diff --git a/libarchive/archive_write_free.3 b/libarchive/archive_write_free.3
new file mode 100644
index 000000000000..27efe18b04a8
--- /dev/null
+++ b/libarchive/archive_write_free.3
@@ -0,0 +1,81 @@
+.\" Copyright (c) 2003-2011 Tim Kientzle
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd March 23, 2011
+.Dt ARCHIVE_WRITE_FREE 3
+.Os
+.Sh NAME
+.Nm archive_write_close ,
+.Nm archive_write_finish ,
+.Nm archive_write_free
+.Nd functions for creating archives
+.Sh SYNOPSIS
+.In archive.h
+.Ft int
+.Fn archive_write_close "struct archive *"
+.Ft int
+.Fn archive_write_finish "struct archive *"
+.Ft int
+.Fn archive_write_free "struct archive *"
+.Sh DESCRIPTION
+.Bl -tag -width indent
+.It Fn archive_write_close
+Complete the archive and invoke the close callback.
+.It Fn archive_write_finish
+This is a deprecated synonym for
+.Fn archive_write_free .
+.It Fn archive_write_free
+Invokes
+.Fn archive_write_close
+if necessary, then releases all resources.
+If you need detailed information about
+.Fn archive_write_close
+failures, you should be careful to call it separately, as
+you cannot obtain error information after
+.Fn archive_write_free
+returns.
+.El
+.\" .Sh EXAMPLE
+.Sh RETURN VALUES
+These functions return
+.Cm ARCHIVE_OK
+on success, or
+.Cm ARCHIVE_FATAL .
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.\"
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_write_set_options 3 ,
+.Xr cpio 5 ,
+.Xr mtree 5 ,
+.Xr tar 5
diff --git a/libarchive/archive_write_header.3 b/libarchive/archive_write_header.3
new file mode 100644
index 000000000000..423b38e46318
--- /dev/null
+++ b/libarchive/archive_write_header.3
@@ -0,0 +1,71 @@
+.\" Copyright (c) 2003-2011 Tim Kientzle
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd March 23, 2011
+.Dt ARCHIVE_WRITE_HEADER 3
+.Os
+.Sh NAME
+.Nm archive_write_header
+.Nd functions for creating archives
+.Sh SYNOPSIS
+.In archive.h
+.Ft int
+.Fn archive_write_header "struct archive *" "struct archive_entry *"
+.Sh DESCRIPTION
+Build and write a header using the data in the provided
+.Tn struct archive_entry
+structure.
+See
+.Xr archive_entry 3
+for information on creating and populating
+.Tn struct archive_entry
+objects.
+.\" .Sh EXAMPLE
+.Sh RETURN VALUES
+This function returns
+.Cm ARCHIVE_OK
+on success, or one of the following on error:
+.Cm ARCHIVE_RETRY
+for operations that might succeed if retried,
+.Cm ARCHIVE_WARN
+for unusual conditions that do not prevent further operations, and
+.Cm ARCHIVE_FATAL
+for serious errors that make remaining operations impossible.
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.\"
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_write_set_options 3 ,
+.Xr cpio 5 ,
+.Xr mtree 5 ,
+.Xr tar 5
diff --git a/libarchive/archive_write_new.3 b/libarchive/archive_write_new.3
new file mode 100644
index 000000000000..d626ccb73250
--- /dev/null
+++ b/libarchive/archive_write_new.3
@@ -0,0 +1,56 @@
+.\" Copyright (c) 2003-2011 Tim Kientzle
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd March 23, 2011
+.Dt ARCHIVE_WRITE_NEW 3
+.Os
+.Sh NAME
+.Nm archive_write_new
+.Nd functions for creating archives
+.Sh SYNOPSIS
+.In archive.h
+.Ft struct archive *
+.Fn archive_write_new "void"
+.Sh DESCRIPTION
+Allocates and initializes a
+.Tn struct archive
+object suitable for writing a tar archive.
+.Dv NULL
+is returned on error.
+.Pp
+A complete description of the
+.Tn struct archive
+object can be found in the overview manual page for
+.Xr libarchive 3 .
+.\" .Sh ERRORS
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_write 3 ,
+.Xr archive_write_set_options 3 ,
+.Xr cpio 5 ,
+.Xr mtree 5 ,
+.Xr tar 5
diff --git a/libarchive/archive_write_open.3 b/libarchive/archive_write_open.3
new file mode 100644
index 000000000000..0d12cb3b39fe
--- /dev/null
+++ b/libarchive/archive_write_open.3
@@ -0,0 +1,233 @@
+.\" Copyright (c) 2003-2011 Tim Kientzle
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD: head/lib/libarchive/archive_write.3 201110 2009-12-28 03:31:29Z kientzle $
+.\"
+.Dd March 23, 2011
+.Dt ARCHIVE_WRITE 3
+.Os
+.Sh NAME
+.Nm archive_write_open ,
+.Nm archive_write_open_fd ,
+.Nm archive_write_open_FILE ,
+.Nm archive_write_open_filename ,
+.Nm archive_write_open_memory
+.Nd functions for creating archives
+.Sh SYNOPSIS
+.In archive.h
+.Ft int
+.Fo archive_write_open
+.Fa "struct archive *"
+.Fa "void *client_data"
+.Fa "archive_open_callback *"
+.Fa "archive_write_callback *"
+.Fa "archive_close_callback *"
+.Fc
+.Ft int
+.Fn archive_write_open_fd "struct archive *" "int fd"
+.Ft int
+.Fn archive_write_open_FILE "struct archive *" "FILE *file"
+.Ft int
+.Fn archive_write_open_filename "struct archive *" "const char *filename"
+.Ft int
+.Fo archive_write_open_memory
+.Fa "struct archive *"
+.Fa "void *buffer"
+.Fa "size_t bufferSize"
+.Fa "size_t *outUsed"
+.Fc
+.Sh DESCRIPTION
+.Bl -tag -width indent
+.It Fn archive_write_open
+Freeze the settings, open the archive, and prepare for writing entries.
+This is the most generic form of this function, which accepts
+pointers to three callback functions which will be invoked by
+the compression layer to write the constructed archive.
+.It Fn archive_write_open_fd
+A convenience form of
+.Fn archive_write_open
+that accepts a file descriptor.
+The
+.Fn archive_write_open_fd
+function is safe for use with tape drives or other
+block-oriented devices.
+.It Fn archive_write_open_FILE
+A convenience form of
+.Fn archive_write_open
+that accepts a
+.Ft "FILE *"
+pointer.
+Note that
+.Fn archive_write_open_FILE
+is not safe for writing to tape drives or other devices
+that require correct blocking.
+.It Fn archive_write_open_file
+A deprecated synonym for
+.Fn archive_write_open_filename .
+.It Fn archive_write_open_filename
+A convenience form of
+.Fn archive_write_open
+that accepts a filename.
+A NULL argument indicates that the output should be written to standard output;
+an argument of
+.Dq -
+will open a file with that name.
+If you have not invoked
+.Fn archive_write_set_bytes_in_last_block ,
+then
+.Fn archive_write_open_filename
+will adjust the last-block padding depending on the file:
+it will enable padding when writing to standard output or
+to a character or block device node, it will disable padding otherwise.
+You can override this by manually invoking
+.Fn archive_write_set_bytes_in_last_block
+before calling
+.Fn archive_write_open .
+The
+.Fn archive_write_open_filename
+function is safe for use with tape drives or other
+block-oriented devices.
+.It Fn archive_write_open_memory
+A convenience form of
+.Fn archive_write_open
+that accepts a pointer to a block of memory that will receive
+the archive.
+The final
+.Ft "size_t *"
+argument points to a variable that will be updated
+after each write to reflect how much of the buffer
+is currently in use.
+You should be careful to ensure that this variable
+remains allocated until after the archive is
+closed.
+.El
+More information about the
+.Va struct archive
+object and the overall design of the library can be found in the
+.Xr libarchive 3
+overview.
+.\"
+.Sh CLIENT CALLBACKS
+To use this library, you will need to define and register
+callback functions that will be invoked to write data to the
+resulting archive.
+These functions are registered by calling
+.Fn archive_write_open :
+.Bl -item -offset indent
+.It
+.Ft typedef int
+.Fn archive_open_callback "struct archive *" "void *client_data"
+.El
+.Pp
+The open callback is invoked by
+.Fn archive_write_open .
+It should return
+.Cm ARCHIVE_OK
+if the underlying file or data source is successfully
+opened.
+If the open fails, it should call
+.Fn archive_set_error
+to register an error code and message and return
+.Cm ARCHIVE_FATAL .
+.Bl -item -offset indent
+.It
+.Ft typedef ssize_t
+.Fo archive_write_callback
+.Fa "struct archive *"
+.Fa "void *client_data"
+.Fa "const void *buffer"
+.Fa "size_t length"
+.Fc
+.El
+.Pp
+The write callback is invoked whenever the library
+needs to write raw bytes to the archive.
+For correct blocking, each call to the write callback function
+should translate into a single
+.Xr write 2
+system call.
+This is especially critical when writing archives to tape drives.
+On success, the write callback should return the
+number of bytes actually written.
+On error, the callback should invoke
+.Fn archive_set_error
+to register an error code and message and return -1.
+.Bl -item -offset indent
+.It
+.Ft typedef int
+.Fn archive_close_callback "struct archive *" "void *client_data"
+.El
+.Pp
+The close callback is invoked by archive_close when
+the archive processing is complete.
+The callback should return
+.Cm ARCHIVE_OK
+on success.
+On failure, the callback should invoke
+.Fn archive_set_error
+to register an error code and message and
+return
+.Cm ARCHIVE_FATAL.
+.Pp
+Note that if the client-provided write callback function
+returns a non-zero value, that error will be propagated back to the caller
+through whatever API function resulted in that call, which
+may include
+.Fn archive_write_header ,
+.Fn archive_write_data ,
+.Fn archive_write_close ,
+.Fn archive_write_finish ,
+or
+.Fn archive_write_free .
+The client callback can call
+.Fn archive_set_error
+to provide values that can then be retrieved by
+.Fn archive_errno
+and
+.Fn archive_error_string .
+.\" .Sh EXAMPLE
+.Sh RETURN VALUES
+These functions return
+.Cm ARCHIVE_OK
+on success, or
+.Cm ARCHIVE_FATAL .
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.\"
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_write 3 ,
+.Xr archive_write_filter 3 ,
+.Xr archive_write_format 3 ,
+.Xr archive_write_new 3 ,
+.Xr archive_write_set_options 3 ,
+.Xr cpio 5 ,
+.Xr mtree 5 ,
+.Xr tar 5
diff --git a/libarchive/archive_write_open_filename.c b/libarchive/archive_write_open_filename.c
index 8a4cd3522196..8689866311c6 100644
--- a/libarchive/archive_write_open_filename.c
+++ b/libarchive/archive_write_open_filename.c
@@ -46,6 +46,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_open_filename.c 191165 200
#endif
#include "archive.h"
+#include "archive_string.h"
#ifndef O_BINARY
#define O_BINARY 0
@@ -53,7 +54,11 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_open_filename.c 191165 200
struct write_file_data {
int fd;
- char filename[1];
+ char mbs_filename;
+ union {
+ char m[1];
+ wchar_t w[1];
+ } filename; /* Must be last! */
};
static int file_close(struct archive *, void *);
@@ -79,12 +84,60 @@ archive_write_open_filename(struct archive *a, const char *filename)
archive_set_error(a, ENOMEM, "No memory");
return (ARCHIVE_FATAL);
}
- strcpy(mine->filename, filename);
+ strcpy(mine->filename.m, filename);
+ mine->mbs_filename = 1;
mine->fd = -1;
return (archive_write_open(a, mine,
file_open, file_write, file_close));
}
+int
+archive_write_open_filename_w(struct archive *a, const wchar_t *filename)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ struct write_file_data *mine;
+
+ if (filename == NULL || filename[0] == L'\0')
+ return (archive_write_open_fd(a, 1));
+
+ mine = malloc(sizeof(*mine) + wcslen(filename) * sizeof(wchar_t));
+ if (mine == NULL) {
+ archive_set_error(a, ENOMEM, "No memory");
+ return (ARCHIVE_FATAL);
+ }
+ wcscpy(mine->filename.w, filename);
+ mine->mbs_filename = 0;
+ mine->fd = -1;
+ return (archive_write_open(a, mine,
+ file_open, file_write, file_close));
+#else
+ /*
+ * POSIX system does not support a wchar_t interface for
+ * open() system call, so we have to translate a wchar_t
+ * filename to multi-byte one and use it.
+ */
+ struct archive_string fn;
+ int r;
+
+ if (filename == NULL || filename[0] == L'\0')
+ return (archive_write_open_fd(a, 1));
+
+ archive_string_init(&fn);
+ if (archive_string_append_from_wcs(&fn, filename,
+ wcslen(filename)) != 0) {
+ archive_set_error(a, EINVAL,
+ "Failed to convert a wide-character filename to"
+ " a multi-byte filename");
+ archive_string_free(&fn);
+ return (ARCHIVE_FATAL);
+ }
+ r = archive_write_open_filename(a, fn.s);
+ archive_string_free(&fn);
+ return (r);
+#endif
+}
+
+
static int
file_open(struct archive *a, void *client_data)
{
@@ -98,17 +151,46 @@ file_open(struct archive *a, void *client_data)
/*
* Open the file.
*/
- mine->fd = open(mine->filename, flags, 0666);
- if (mine->fd < 0) {
- archive_set_error(a, errno, "Failed to open '%s'",
- mine->filename);
- return (ARCHIVE_FATAL);
- }
+ if (mine->mbs_filename) {
+ mine->fd = open(mine->filename.m, flags, 0666);
+ if (mine->fd < 0) {
+ archive_set_error(a, errno, "Failed to open '%s'",
+ mine->filename.m);
+ return (ARCHIVE_FATAL);
+ }
+
+ if (fstat(mine->fd, &st) != 0) {
+ archive_set_error(a, errno, "Couldn't stat '%s'",
+ mine->filename.m);
+ return (ARCHIVE_FATAL);
+ }
+ } else {
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ mine->fd = _wopen(mine->filename.w, flags, 0666);
+ if (mine->fd < 0 && errno == ENOENT) {
+ wchar_t *fullpath;
+ fullpath = __la_win_permissive_name_w(mine->filename.w);
+ if (fullpath != NULL) {
+ mine->fd = _wopen(fullpath, flags, 0666);
+ free(fullpath);
+ }
+ }
+ if (mine->fd < 0) {
+ archive_set_error(a, errno, "Failed to open '%S'",
+ mine->filename.w);
+ return (ARCHIVE_FATAL);
+ }
- if (fstat(mine->fd, &st) != 0) {
- archive_set_error(a, errno, "Couldn't stat '%s'",
- mine->filename);
- return (ARCHIVE_FATAL);
+ if (fstat(mine->fd, &st) != 0) {
+ archive_set_error(a, errno, "Couldn't stat '%S'",
+ mine->filename.w);
+ return (ARCHIVE_FATAL);
+ }
+#else
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Unexpedted operation in archive_write_open_filename");
+ return (ARCHIVE_FATAL);
+#endif
}
/*
diff --git a/libarchive/archive_write_open_memory.c b/libarchive/archive_write_open_memory.c
index d235ca01dc8c..4f8d679e582f 100644
--- a/libarchive/archive_write_open_memory.c
+++ b/libarchive/archive_write_open_memory.c
@@ -32,18 +32,6 @@ __FBSDID("$FreeBSD: src/lib/libarchive/archive_write_open_memory.c,v 1.3 2007/01
#include "archive.h"
-/*
- * This is a little tricky. I used to allow the
- * compression handling layer to fork the compressor,
- * which means this write function gets invoked in
- * a separate process. That would, of course, make it impossible
- * to actually use the data stored into memory here.
- * Fortunately, none of the compressors fork today and
- * I'm reluctant to use that route in the future but, if
- * forking compressors ever do reappear, this will have
- * to get a lot more complicated.
- */
-
struct write_memory_data {
size_t used;
size_t size;
diff --git a/libarchive/archive_write_private.h b/libarchive/archive_write_private.h
index f9b656555b3c..91284cf1b4c8 100644
--- a/libarchive/archive_write_private.h
+++ b/libarchive/archive_write_private.h
@@ -36,10 +36,42 @@
#include "archive_string.h"
#include "archive_private.h"
+struct archive_write;
+
+struct archive_write_filter {
+ int64_t bytes_written;
+ struct archive *archive; /* Associated archive. */
+ struct archive_write_filter *next_filter; /* Who I write to. */
+ int (*options)(struct archive_write_filter *,
+ const char *key, const char *value);
+ int (*open)(struct archive_write_filter *);
+ int (*write)(struct archive_write_filter *, const void *, size_t);
+ int (*close)(struct archive_write_filter *);
+ int (*free)(struct archive_write_filter *);
+ void *data;
+ const char *name;
+ int code;
+ int bytes_per_block;
+ int bytes_in_last_block;
+};
+
+#if ARCHIVE_VERSION < 4000000
+void __archive_write_filters_free(struct archive *);
+#endif
+
+struct archive_write_filter *__archive_write_allocate_filter(struct archive *);
+
+int __archive_write_output(struct archive_write *, const void *, size_t);
+int __archive_write_nulls(struct archive_write *, size_t);
+int __archive_write_filter(struct archive_write_filter *, const void *, size_t);
+int __archive_write_open_filter(struct archive_write_filter *);
+int __archive_write_close_filter(struct archive_write_filter *);
+
struct archive_write {
struct archive archive;
/* Dev/ino of the archive being written. */
+ int skip_file_set;
dev_t skip_file_dev;
int64_t skip_file_ino;
@@ -63,29 +95,10 @@ struct archive_write {
int bytes_in_last_block;
/*
- * These control whether data within a gzip/bzip2 compressed
- * stream gets padded or not. If pad_uncompressed is set,
- * the data will be padded to a full block before being
- * compressed. The pad_uncompressed_byte determines the value
- * that will be used for padding. Note that these have no
- * effect on compression "none."
- */
- int pad_uncompressed;
- int pad_uncompressed_byte; /* TODO: Support this. */
-
- /*
- * On write, the client just invokes an archive_write_set function
- * which sets up the data here directly.
+ * First and last write filters in the pipeline.
*/
- struct {
- void *data;
- void *config;
- int (*init)(struct archive_write *);
- int (*options)(struct archive_write *,
- const char *key, const char *value);
- int (*finish)(struct archive_write *);
- int (*write)(struct archive_write *, const void *, size_t);
- } compressor;
+ struct archive_write_filter *filter_first;
+ struct archive_write_filter *filter_last;
/*
* Pointers to format-specific functions for writing. They're
@@ -96,13 +109,13 @@ struct archive_write {
int (*format_init)(struct archive_write *);
int (*format_options)(struct archive_write *,
const char *key, const char *value);
- int (*format_finish)(struct archive_write *);
- int (*format_destroy)(struct archive_write *);
int (*format_finish_entry)(struct archive_write *);
int (*format_write_header)(struct archive_write *,
struct archive_entry *);
ssize_t (*format_write_data)(struct archive_write *,
const void *buff, size_t);
+ int (*format_close)(struct archive_write *);
+ int (*format_free)(struct archive_write *);
};
/*
@@ -117,6 +130,7 @@ struct archive_write {
*/
int
__archive_write_format_header_ustar(struct archive_write *, char buff[512],
- struct archive_entry *, int tartype, int strict);
+ struct archive_entry *, int tartype, int strict,
+ struct archive_string_conv *);
#endif
diff --git a/libarchive/archive_write_set_compression_bzip2.c b/libarchive/archive_write_set_compression_bzip2.c
deleted file mode 100644
index 626bbbc16ecf..000000000000
--- a/libarchive/archive_write_set_compression_bzip2.c
+++ /dev/null
@@ -1,408 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "archive_platform.h"
-
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_bzip2.c 201091 2009-12-28 02:22:41Z kientzle $");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_BZLIB_H
-#include <bzlib.h>
-#endif
-
-#include "archive.h"
-#include "archive_private.h"
-#include "archive_write_private.h"
-
-#if !defined(HAVE_BZLIB_H) || !defined(BZ_CONFIG_ERROR)
-int
-archive_write_set_compression_bzip2(struct archive *a)
-{
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "bzip2 compression not supported on this platform");
- return (ARCHIVE_FATAL);
-}
-#else
-/* Don't compile this if we don't have bzlib. */
-
-struct private_data {
- bz_stream stream;
- int64_t total_in;
- char *compressed;
- size_t compressed_buffer_size;
-};
-
-struct private_config {
- int compression_level;
-};
-
-/*
- * Yuck. bzlib.h is not const-correct, so I need this one bit
- * of ugly hackery to convert a const * pointer to a non-const pointer.
- */
-#define SET_NEXT_IN(st,src) \
- (st)->stream.next_in = (char *)(uintptr_t)(const void *)(src)
-
-static int archive_compressor_bzip2_finish(struct archive_write *);
-static int archive_compressor_bzip2_init(struct archive_write *);
-static int archive_compressor_bzip2_options(struct archive_write *,
- const char *, const char *);
-static int archive_compressor_bzip2_write(struct archive_write *,
- const void *, size_t);
-static int drive_compressor(struct archive_write *, struct private_data *,
- int finishing);
-
-/*
- * Allocate, initialize and return an archive object.
- */
-int
-archive_write_set_compression_bzip2(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- struct private_config *config;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_set_compression_bzip2");
- config = malloc(sizeof(*config));
- if (config == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Out of memory");
- return (ARCHIVE_FATAL);
- }
- a->compressor.config = config;
- a->compressor.finish = archive_compressor_bzip2_finish;
- config->compression_level = 9; /* default */
- a->compressor.init = &archive_compressor_bzip2_init;
- a->compressor.options = &archive_compressor_bzip2_options;
- a->archive.compression_code = ARCHIVE_COMPRESSION_BZIP2;
- a->archive.compression_name = "bzip2";
- return (ARCHIVE_OK);
-}
-
-/*
- * Setup callback.
- */
-static int
-archive_compressor_bzip2_init(struct archive_write *a)
-{
- int ret;
- struct private_data *state;
- struct private_config *config;
-
- config = (struct private_config *)a->compressor.config;
- if (a->client_opener != NULL) {
- ret = (a->client_opener)(&a->archive, a->client_data);
- if (ret != 0)
- return (ret);
- }
-
- state = (struct private_data *)malloc(sizeof(*state));
- if (state == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate data for compression");
- return (ARCHIVE_FATAL);
- }
- memset(state, 0, sizeof(*state));
-
- state->compressed_buffer_size = a->bytes_per_block;
- state->compressed = (char *)malloc(state->compressed_buffer_size);
-
- if (state->compressed == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate data for compression buffer");
- free(state);
- return (ARCHIVE_FATAL);
- }
-
- state->stream.next_out = state->compressed;
- state->stream.avail_out = state->compressed_buffer_size;
- a->compressor.write = archive_compressor_bzip2_write;
-
- /* Initialize compression library */
- ret = BZ2_bzCompressInit(&(state->stream),
- config->compression_level, 0, 30);
- if (ret == BZ_OK) {
- a->compressor.data = state;
- return (ARCHIVE_OK);
- }
-
- /* Library setup failed: clean up. */
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Internal error initializing compression library");
- free(state->compressed);
- free(state);
-
- /* Override the error message if we know what really went wrong. */
- switch (ret) {
- case BZ_PARAM_ERROR:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Internal error initializing compression library: "
- "invalid setup parameter");
- break;
- case BZ_MEM_ERROR:
- archive_set_error(&a->archive, ENOMEM,
- "Internal error initializing compression library: "
- "out of memory");
- break;
- case BZ_CONFIG_ERROR:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Internal error initializing compression library: "
- "mis-compiled library");
- break;
- }
-
- return (ARCHIVE_FATAL);
-
-}
-
-/*
- * Set write options.
- */
-static int
-archive_compressor_bzip2_options(struct archive_write *a, const char *key,
- const char *value)
-{
- struct private_config *config;
-
- config = (struct private_config *)a->compressor.config;
- if (strcmp(key, "compression-level") == 0) {
- if (value == NULL || !(value[0] >= '0' && value[0] <= '9') ||
- value[1] != '\0')
- return (ARCHIVE_WARN);
- config->compression_level = value[0] - '0';
- /* Make '0' be a synonym for '1'. */
- /* This way, bzip2 compressor supports the same 0..9
- * range of levels as gzip. */
- if (config->compression_level < 1)
- config->compression_level = 1;
- return (ARCHIVE_OK);
- }
-
- return (ARCHIVE_WARN);
-}
-
-/*
- * Write data to the compressed stream.
- *
- * Returns ARCHIVE_OK if all data written, error otherwise.
- */
-static int
-archive_compressor_bzip2_write(struct archive_write *a, const void *buff,
- size_t length)
-{
- struct private_data *state;
-
- state = (struct private_data *)a->compressor.data;
- if (a->client_writer == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "No write callback is registered? "
- "This is probably an internal programming error.");
- return (ARCHIVE_FATAL);
- }
-
- /* Update statistics */
- state->total_in += length;
-
- /* Compress input data to output buffer */
- SET_NEXT_IN(state, buff);
- state->stream.avail_in = length;
- if (drive_compressor(a, state, 0))
- return (ARCHIVE_FATAL);
- a->archive.file_position += length;
- return (ARCHIVE_OK);
-}
-
-
-/*
- * Finish the compression.
- */
-static int
-archive_compressor_bzip2_finish(struct archive_write *a)
-{
- ssize_t block_length;
- int ret;
- struct private_data *state;
- ssize_t target_block_length;
- ssize_t bytes_written;
- unsigned tocopy;
-
- ret = ARCHIVE_OK;
- state = (struct private_data *)a->compressor.data;
- if (state != NULL) {
- if (a->client_writer == NULL) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_PROGRAMMER,
- "No write callback is registered?\n"
- "This is probably an internal programming error.");
- ret = ARCHIVE_FATAL;
- goto cleanup;
- }
-
- /* By default, always pad the uncompressed data. */
- if (a->pad_uncompressed) {
- tocopy = a->bytes_per_block -
- (state->total_in % a->bytes_per_block);
- while (tocopy > 0 && tocopy < (unsigned)a->bytes_per_block) {
- SET_NEXT_IN(state, a->nulls);
- state->stream.avail_in = tocopy < a->null_length ?
- tocopy : a->null_length;
- state->total_in += state->stream.avail_in;
- tocopy -= state->stream.avail_in;
- ret = drive_compressor(a, state, 0);
- if (ret != ARCHIVE_OK)
- goto cleanup;
- }
- }
-
- /* Finish compression cycle. */
- if ((ret = drive_compressor(a, state, 1)))
- goto cleanup;
-
- /* Optionally, pad the final compressed block. */
- block_length = state->stream.next_out - state->compressed;
-
- /* Tricky calculation to determine size of last block. */
- if (a->bytes_in_last_block <= 0)
- /* Default or Zero: pad to full block */
- target_block_length = a->bytes_per_block;
- else
- /* Round length to next multiple of bytes_in_last_block. */
- target_block_length = a->bytes_in_last_block *
- ( (block_length + a->bytes_in_last_block - 1) /
- a->bytes_in_last_block);
- if (target_block_length > a->bytes_per_block)
- target_block_length = a->bytes_per_block;
- if (block_length < target_block_length) {
- memset(state->stream.next_out, 0,
- target_block_length - block_length);
- block_length = target_block_length;
- }
-
- /* Write the last block */
- bytes_written = (a->client_writer)(&a->archive, a->client_data,
- state->compressed, block_length);
-
- /* TODO: Handle short write of final block. */
- if (bytes_written <= 0)
- ret = ARCHIVE_FATAL;
- else {
- a->archive.raw_position += ret;
- ret = ARCHIVE_OK;
- }
-
- /* Cleanup: shut down compressor, release memory, etc. */
-cleanup:
- switch (BZ2_bzCompressEnd(&(state->stream))) {
- case BZ_OK:
- break;
- default:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "Failed to clean up compressor");
- ret = ARCHIVE_FATAL;
- }
-
- free(state->compressed);
- free(state);
- }
- /* Free configuration data even if we were never fully initialized. */
- free(a->compressor.config);
- a->compressor.config = NULL;
- return (ret);
-}
-
-/*
- * Utility function to push input data through compressor, writing
- * full output blocks as necessary.
- *
- * Note that this handles both the regular write case (finishing ==
- * false) and the end-of-archive case (finishing == true).
- */
-static int
-drive_compressor(struct archive_write *a, struct private_data *state, int finishing)
-{
- ssize_t bytes_written;
- int ret;
-
- for (;;) {
- if (state->stream.avail_out == 0) {
- bytes_written = (a->client_writer)(&a->archive,
- a->client_data, state->compressed,
- state->compressed_buffer_size);
- if (bytes_written <= 0) {
- /* TODO: Handle this write failure */
- return (ARCHIVE_FATAL);
- } else if ((size_t)bytes_written < state->compressed_buffer_size) {
- /* Short write: Move remainder to
- * front and keep filling */
- memmove(state->compressed,
- state->compressed + bytes_written,
- state->compressed_buffer_size - bytes_written);
- }
-
- a->archive.raw_position += bytes_written;
- state->stream.next_out = state->compressed +
- state->compressed_buffer_size - bytes_written;
- state->stream.avail_out = bytes_written;
- }
-
- /* If there's nothing to do, we're done. */
- if (!finishing && state->stream.avail_in == 0)
- return (ARCHIVE_OK);
-
- ret = BZ2_bzCompress(&(state->stream),
- finishing ? BZ_FINISH : BZ_RUN);
-
- switch (ret) {
- case BZ_RUN_OK:
- /* In non-finishing case, did compressor
- * consume everything? */
- if (!finishing && state->stream.avail_in == 0)
- return (ARCHIVE_OK);
- break;
- case BZ_FINISH_OK: /* Finishing: There's more work to do */
- break;
- case BZ_STREAM_END: /* Finishing: all done */
- /* Only occurs in finishing case */
- return (ARCHIVE_OK);
- default:
- /* Any other return value indicates an error */
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_PROGRAMMER,
- "Bzip2 compression failed;"
- " BZ2_bzCompress() returned %d",
- ret);
- return (ARCHIVE_FATAL);
- }
- }
-}
-
-#endif /* HAVE_BZLIB_H && BZ_CONFIG_ERROR */
diff --git a/libarchive/archive_write_set_compression_gzip.c b/libarchive/archive_write_set_compression_gzip.c
deleted file mode 100644
index f0176e25f744..000000000000
--- a/libarchive/archive_write_set_compression_gzip.c
+++ /dev/null
@@ -1,477 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "archive_platform.h"
-
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_gzip.c 201081 2009-12-28 02:04:42Z kientzle $");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#include <time.h>
-#ifdef HAVE_ZLIB_H
-#include <zlib.h>
-#endif
-
-#include "archive.h"
-#include "archive_private.h"
-#include "archive_write_private.h"
-
-#ifndef HAVE_ZLIB_H
-int
-archive_write_set_compression_gzip(struct archive *a)
-{
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "gzip compression not supported on this platform");
- return (ARCHIVE_FATAL);
-}
-#else
-/* Don't compile this if we don't have zlib. */
-
-struct private_data {
- z_stream stream;
- int64_t total_in;
- unsigned char *compressed;
- size_t compressed_buffer_size;
- unsigned long crc;
-};
-
-struct private_config {
- int compression_level;
-};
-
-
-/*
- * Yuck. zlib.h is not const-correct, so I need this one bit
- * of ugly hackery to convert a const * pointer to a non-const pointer.
- */
-#define SET_NEXT_IN(st,src) \
- (st)->stream.next_in = (Bytef *)(uintptr_t)(const void *)(src)
-
-static int archive_compressor_gzip_finish(struct archive_write *);
-static int archive_compressor_gzip_init(struct archive_write *);
-static int archive_compressor_gzip_options(struct archive_write *,
- const char *, const char *);
-static int archive_compressor_gzip_write(struct archive_write *,
- const void *, size_t);
-static int drive_compressor(struct archive_write *, struct private_data *,
- int finishing);
-
-
-/*
- * Allocate, initialize and return a archive object.
- */
-int
-archive_write_set_compression_gzip(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- struct private_config *config;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_set_compression_gzip");
- config = malloc(sizeof(*config));
- if (config == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Out of memory");
- return (ARCHIVE_FATAL);
- }
- a->compressor.config = config;
- a->compressor.finish = &archive_compressor_gzip_finish;
- config->compression_level = Z_DEFAULT_COMPRESSION;
- a->compressor.init = &archive_compressor_gzip_init;
- a->compressor.options = &archive_compressor_gzip_options;
- a->archive.compression_code = ARCHIVE_COMPRESSION_GZIP;
- a->archive.compression_name = "gzip";
- return (ARCHIVE_OK);
-}
-
-/*
- * Setup callback.
- */
-static int
-archive_compressor_gzip_init(struct archive_write *a)
-{
- int ret;
- struct private_data *state;
- struct private_config *config;
- time_t t;
-
- config = (struct private_config *)a->compressor.config;
-
- if (a->client_opener != NULL) {
- ret = (a->client_opener)(&a->archive, a->client_data);
- if (ret != ARCHIVE_OK)
- return (ret);
- }
-
- /*
- * The next check is a temporary workaround until the gzip
- * code can be overhauled some. The code should not require
- * that compressed_buffer_size == bytes_per_block. Removing
- * this assumption will allow us to compress larger chunks at
- * a time, which should improve overall performance
- * marginally. As a minor side-effect, such a cleanup would
- * allow us to support truly arbitrary block sizes.
- */
- if (a->bytes_per_block < 10) {
- archive_set_error(&a->archive, EINVAL,
- "GZip compressor requires a minimum 10 byte block size");
- return (ARCHIVE_FATAL);
- }
-
- state = (struct private_data *)malloc(sizeof(*state));
- if (state == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate data for compression");
- return (ARCHIVE_FATAL);
- }
- memset(state, 0, sizeof(*state));
-
- /*
- * See comment above. We should set compressed_buffer_size to
- * max(bytes_per_block, 65536), but the code can't handle that yet.
- */
- state->compressed_buffer_size = a->bytes_per_block;
- state->compressed = (unsigned char *)malloc(state->compressed_buffer_size);
- state->crc = crc32(0L, NULL, 0);
-
- if (state->compressed == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate data for compression buffer");
- free(state);
- return (ARCHIVE_FATAL);
- }
-
- state->stream.next_out = state->compressed;
- state->stream.avail_out = state->compressed_buffer_size;
-
- /* Prime output buffer with a gzip header. */
- t = time(NULL);
- state->compressed[0] = 0x1f; /* GZip signature bytes */
- state->compressed[1] = 0x8b;
- state->compressed[2] = 0x08; /* "Deflate" compression */
- state->compressed[3] = 0; /* No options */
- state->compressed[4] = (t)&0xff; /* Timestamp */
- state->compressed[5] = (t>>8)&0xff;
- state->compressed[6] = (t>>16)&0xff;
- state->compressed[7] = (t>>24)&0xff;
- state->compressed[8] = 0; /* No deflate options */
- state->compressed[9] = 3; /* OS=Unix */
- state->stream.next_out += 10;
- state->stream.avail_out -= 10;
-
- a->compressor.write = archive_compressor_gzip_write;
-
- /* Initialize compression library. */
- ret = deflateInit2(&(state->stream),
- config->compression_level,
- Z_DEFLATED,
- -15 /* < 0 to suppress zlib header */,
- 8,
- Z_DEFAULT_STRATEGY);
-
- if (ret == Z_OK) {
- a->compressor.data = state;
- return (0);
- }
-
- /* Library setup failed: clean up. */
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Internal error "
- "initializing compression library");
- free(state->compressed);
- free(state);
-
- /* Override the error message if we know what really went wrong. */
- switch (ret) {
- case Z_STREAM_ERROR:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Internal error initializing "
- "compression library: invalid setup parameter");
- break;
- case Z_MEM_ERROR:
- archive_set_error(&a->archive, ENOMEM, "Internal error initializing "
- "compression library");
- break;
- case Z_VERSION_ERROR:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Internal error initializing "
- "compression library: invalid library version");
- break;
- }
-
- return (ARCHIVE_FATAL);
-}
-
-/*
- * Set write options.
- */
-static int
-archive_compressor_gzip_options(struct archive_write *a, const char *key,
- const char *value)
-{
- struct private_config *config;
-
- config = (struct private_config *)a->compressor.config;
- if (strcmp(key, "compression-level") == 0) {
- if (value == NULL || !(value[0] >= '0' && value[0] <= '9') ||
- value[1] != '\0')
- return (ARCHIVE_WARN);
- config->compression_level = value[0] - '0';
- return (ARCHIVE_OK);
- }
-
- return (ARCHIVE_WARN);
-}
-
-/*
- * Write data to the compressed stream.
- */
-static int
-archive_compressor_gzip_write(struct archive_write *a, const void *buff,
- size_t length)
-{
- struct private_data *state;
- int ret;
-
- state = (struct private_data *)a->compressor.data;
- if (a->client_writer == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "No write callback is registered? "
- "This is probably an internal programming error.");
- return (ARCHIVE_FATAL);
- }
-
- /* Update statistics */
- state->crc = crc32(state->crc, (const Bytef *)buff, length);
- state->total_in += length;
-
- /* Compress input data to output buffer */
- SET_NEXT_IN(state, buff);
- state->stream.avail_in = length;
- if ((ret = drive_compressor(a, state, 0)) != ARCHIVE_OK)
- return (ret);
-
- a->archive.file_position += length;
- return (ARCHIVE_OK);
-}
-
-/*
- * Finish the compression...
- */
-static int
-archive_compressor_gzip_finish(struct archive_write *a)
-{
- ssize_t block_length, target_block_length, bytes_written;
- int ret;
- struct private_data *state;
- unsigned tocopy;
- unsigned char trailer[8];
-
- state = (struct private_data *)a->compressor.data;
- ret = 0;
- if (state != NULL) {
- if (a->client_writer == NULL) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_PROGRAMMER,
- "No write callback is registered? "
- "This is probably an internal programming error.");
- ret = ARCHIVE_FATAL;
- goto cleanup;
- }
-
- /* By default, always pad the uncompressed data. */
- if (a->pad_uncompressed) {
- tocopy = a->bytes_per_block -
- (state->total_in % a->bytes_per_block);
- while (tocopy > 0 && tocopy < (unsigned)a->bytes_per_block) {
- SET_NEXT_IN(state, a->nulls);
- state->stream.avail_in = tocopy < a->null_length ?
- tocopy : a->null_length;
- state->crc = crc32(state->crc, a->nulls,
- state->stream.avail_in);
- state->total_in += state->stream.avail_in;
- tocopy -= state->stream.avail_in;
- ret = drive_compressor(a, state, 0);
- if (ret != ARCHIVE_OK)
- goto cleanup;
- }
- }
-
- /* Finish compression cycle */
- if (((ret = drive_compressor(a, state, 1))) != ARCHIVE_OK)
- goto cleanup;
-
- /* Build trailer: 4-byte CRC and 4-byte length. */
- trailer[0] = (state->crc)&0xff;
- trailer[1] = (state->crc >> 8)&0xff;
- trailer[2] = (state->crc >> 16)&0xff;
- trailer[3] = (state->crc >> 24)&0xff;
- trailer[4] = (state->total_in)&0xff;
- trailer[5] = (state->total_in >> 8)&0xff;
- trailer[6] = (state->total_in >> 16)&0xff;
- trailer[7] = (state->total_in >> 24)&0xff;
-
- /* Add trailer to current block. */
- tocopy = 8;
- if (tocopy > state->stream.avail_out)
- tocopy = state->stream.avail_out;
- memcpy(state->stream.next_out, trailer, tocopy);
- state->stream.next_out += tocopy;
- state->stream.avail_out -= tocopy;
-
- /* If it overflowed, flush and start a new block. */
- if (tocopy < 8) {
- bytes_written = (a->client_writer)(&a->archive, a->client_data,
- state->compressed, state->compressed_buffer_size);
- if (bytes_written <= 0) {
- ret = ARCHIVE_FATAL;
- goto cleanup;
- }
- a->archive.raw_position += bytes_written;
- state->stream.next_out = state->compressed;
- state->stream.avail_out = state->compressed_buffer_size;
- memcpy(state->stream.next_out, trailer + tocopy, 8-tocopy);
- state->stream.next_out += 8-tocopy;
- state->stream.avail_out -= 8-tocopy;
- }
-
- /* Optionally, pad the final compressed block. */
- block_length = state->stream.next_out - state->compressed;
-
- /* Tricky calculation to determine size of last block. */
- if (a->bytes_in_last_block <= 0)
- /* Default or Zero: pad to full block */
- target_block_length = a->bytes_per_block;
- else
- /* Round length to next multiple of bytes_in_last_block. */
- target_block_length = a->bytes_in_last_block *
- ( (block_length + a->bytes_in_last_block - 1) /
- a->bytes_in_last_block);
- if (target_block_length > a->bytes_per_block)
- target_block_length = a->bytes_per_block;
- if (block_length < target_block_length) {
- memset(state->stream.next_out, 0,
- target_block_length - block_length);
- block_length = target_block_length;
- }
-
- /* Write the last block */
- bytes_written = (a->client_writer)(&a->archive, a->client_data,
- state->compressed, block_length);
- if (bytes_written <= 0) {
- ret = ARCHIVE_FATAL;
- goto cleanup;
- }
- a->archive.raw_position += bytes_written;
-
- /* Cleanup: shut down compressor, release memory, etc. */
- cleanup:
- switch (deflateEnd(&(state->stream))) {
- case Z_OK:
- break;
- default:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Failed to clean up compressor");
- ret = ARCHIVE_FATAL;
- }
- free(state->compressed);
- free(state);
- }
- /* Clean up config area even if we never initialized. */
- free(a->compressor.config);
- a->compressor.config = NULL;
- return (ret);
-}
-
-/*
- * Utility function to push input data through compressor,
- * writing full output blocks as necessary.
- *
- * Note that this handles both the regular write case (finishing ==
- * false) and the end-of-archive case (finishing == true).
- */
-static int
-drive_compressor(struct archive_write *a, struct private_data *state, int finishing)
-{
- ssize_t bytes_written;
- int ret;
-
- for (;;) {
- if (state->stream.avail_out == 0) {
- bytes_written = (a->client_writer)(&a->archive,
- a->client_data, state->compressed,
- state->compressed_buffer_size);
- if (bytes_written <= 0) {
- /* TODO: Handle this write failure */
- return (ARCHIVE_FATAL);
- } else if ((size_t)bytes_written < state->compressed_buffer_size) {
- /* Short write: Move remaining to
- * front of block and keep filling */
- memmove(state->compressed,
- state->compressed + bytes_written,
- state->compressed_buffer_size - bytes_written);
- }
- a->archive.raw_position += bytes_written;
- state->stream.next_out
- = state->compressed +
- state->compressed_buffer_size - bytes_written;
- state->stream.avail_out = bytes_written;
- }
-
- /* If there's nothing to do, we're done. */
- if (!finishing && state->stream.avail_in == 0)
- return (ARCHIVE_OK);
-
- ret = deflate(&(state->stream),
- finishing ? Z_FINISH : Z_NO_FLUSH );
-
- switch (ret) {
- case Z_OK:
- /* In non-finishing case, check if compressor
- * consumed everything */
- if (!finishing && state->stream.avail_in == 0)
- return (ARCHIVE_OK);
- /* In finishing case, this return always means
- * there's more work */
- break;
- case Z_STREAM_END:
- /* This return can only occur in finishing case. */
- return (ARCHIVE_OK);
- default:
- /* Any other return value indicates an error. */
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "GZip compression failed:"
- " deflate() call returned status %d",
- ret);
- return (ARCHIVE_FATAL);
- }
- }
-}
-
-#endif /* HAVE_ZLIB_H */
diff --git a/libarchive/archive_write_set_compression_none.c b/libarchive/archive_write_set_compression_none.c
deleted file mode 100644
index e0216d9e1226..000000000000
--- a/libarchive/archive_write_set_compression_none.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_none.c 201080 2009-12-28 02:03:54Z kientzle $");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include "archive.h"
-#include "archive_private.h"
-#include "archive_write_private.h"
-
-static int archive_compressor_none_finish(struct archive_write *a);
-static int archive_compressor_none_init(struct archive_write *);
-static int archive_compressor_none_write(struct archive_write *,
- const void *, size_t);
-
-struct archive_none {
- char *buffer;
- ssize_t buffer_size;
- char *next; /* Current insert location */
- ssize_t avail; /* Free space left in buffer */
-};
-
-int
-archive_write_set_compression_none(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_set_compression_none");
- a->compressor.init = &archive_compressor_none_init;
- return (0);
-}
-
-/*
- * Setup callback.
- */
-static int
-archive_compressor_none_init(struct archive_write *a)
-{
- int ret;
- struct archive_none *state;
-
- a->archive.compression_code = ARCHIVE_COMPRESSION_NONE;
- a->archive.compression_name = "none";
-
- if (a->client_opener != NULL) {
- ret = (a->client_opener)(&a->archive, a->client_data);
- if (ret != 0)
- return (ret);
- }
-
- state = (struct archive_none *)malloc(sizeof(*state));
- if (state == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate data for output buffering");
- return (ARCHIVE_FATAL);
- }
- memset(state, 0, sizeof(*state));
-
- state->buffer_size = a->bytes_per_block;
- if (state->buffer_size != 0) {
- state->buffer = (char *)malloc(state->buffer_size);
- if (state->buffer == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate output buffer");
- free(state);
- return (ARCHIVE_FATAL);
- }
- }
-
- state->next = state->buffer;
- state->avail = state->buffer_size;
-
- a->compressor.data = state;
- a->compressor.write = archive_compressor_none_write;
- a->compressor.finish = archive_compressor_none_finish;
- return (ARCHIVE_OK);
-}
-
-/*
- * Write data to the stream.
- */
-static int
-archive_compressor_none_write(struct archive_write *a, const void *vbuff,
- size_t length)
-{
- const char *buff;
- ssize_t remaining, to_copy;
- ssize_t bytes_written;
- struct archive_none *state;
-
- state = (struct archive_none *)a->compressor.data;
- buff = (const char *)vbuff;
- if (a->client_writer == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "No write callback is registered? "
- "This is probably an internal programming error.");
- return (ARCHIVE_FATAL);
- }
-
- remaining = length;
-
- /*
- * If there is no buffer for blocking, just pass the data
- * straight through to the client write callback. In
- * particular, this supports "no write delay" operation for
- * special applications. Just set the block size to zero.
- */
- if (state->buffer_size == 0) {
- while (remaining > 0) {
- bytes_written = (a->client_writer)(&a->archive,
- a->client_data, buff, remaining);
- if (bytes_written <= 0)
- return (ARCHIVE_FATAL);
- a->archive.raw_position += bytes_written;
- remaining -= bytes_written;
- buff += bytes_written;
- }
- a->archive.file_position += length;
- return (ARCHIVE_OK);
- }
-
- /* If the copy buffer isn't empty, try to fill it. */
- if (state->avail < state->buffer_size) {
- /* If buffer is not empty... */
- /* ... copy data into buffer ... */
- to_copy = (remaining > state->avail) ?
- state->avail : remaining;
- memcpy(state->next, buff, to_copy);
- state->next += to_copy;
- state->avail -= to_copy;
- buff += to_copy;
- remaining -= to_copy;
- /* ... if it's full, write it out. */
- if (state->avail == 0) {
- bytes_written = (a->client_writer)(&a->archive,
- a->client_data, state->buffer, state->buffer_size);
- if (bytes_written <= 0)
- return (ARCHIVE_FATAL);
- /* XXX TODO: if bytes_written < state->buffer_size */
- a->archive.raw_position += bytes_written;
- state->next = state->buffer;
- state->avail = state->buffer_size;
- }
- }
-
- while (remaining > state->buffer_size) {
- /* Write out full blocks directly to client. */
- bytes_written = (a->client_writer)(&a->archive,
- a->client_data, buff, state->buffer_size);
- if (bytes_written <= 0)
- return (ARCHIVE_FATAL);
- a->archive.raw_position += bytes_written;
- buff += bytes_written;
- remaining -= bytes_written;
- }
-
- if (remaining > 0) {
- /* Copy last bit into copy buffer. */
- memcpy(state->next, buff, remaining);
- state->next += remaining;
- state->avail -= remaining;
- }
-
- a->archive.file_position += length;
- return (ARCHIVE_OK);
-}
-
-
-/*
- * Finish the compression.
- */
-static int
-archive_compressor_none_finish(struct archive_write *a)
-{
- ssize_t block_length;
- ssize_t target_block_length;
- ssize_t bytes_written;
- int ret;
- struct archive_none *state;
-
- state = (struct archive_none *)a->compressor.data;
- ret = ARCHIVE_OK;
- if (a->client_writer == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "No write callback is registered? "
- "This is probably an internal programming error.");
- return (ARCHIVE_FATAL);
- }
-
- /* If there's pending data, pad and write the last block */
- if (state->next != state->buffer) {
- block_length = state->buffer_size - state->avail;
-
- /* Tricky calculation to determine size of last block */
- if (a->bytes_in_last_block <= 0)
- /* Default or Zero: pad to full block */
- target_block_length = a->bytes_per_block;
- else
- /* Round to next multiple of bytes_in_last_block. */
- target_block_length = a->bytes_in_last_block *
- ( (block_length + a->bytes_in_last_block - 1) /
- a->bytes_in_last_block);
- if (target_block_length > a->bytes_per_block)
- target_block_length = a->bytes_per_block;
- if (block_length < target_block_length) {
- memset(state->next, 0,
- target_block_length - block_length);
- block_length = target_block_length;
- }
- bytes_written = (a->client_writer)(&a->archive,
- a->client_data, state->buffer, block_length);
- if (bytes_written <= 0)
- ret = ARCHIVE_FATAL;
- else {
- a->archive.raw_position += bytes_written;
- ret = ARCHIVE_OK;
- }
- }
- if (state->buffer)
- free(state->buffer);
- free(state);
- a->compressor.data = NULL;
-
- return (ret);
-}
diff --git a/libarchive/archive_write_set_compression_program.c b/libarchive/archive_write_set_compression_program.c
deleted file mode 100644
index 475ba3540321..000000000000
--- a/libarchive/archive_write_set_compression_program.c
+++ /dev/null
@@ -1,347 +0,0 @@
-/*-
- * Copyright (c) 2007 Joerg Sonnenberger
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "archive_platform.h"
-
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_program.c 201104 2009-12-28 03:14:30Z kientzle $");
-
-/* This capability is only available on POSIX systems. */
-#if (!defined(HAVE_PIPE) || !defined(HAVE_FCNTL) || \
- !(defined(HAVE_FORK) || defined(HAVE_VFORK))) && (!defined(_WIN32) || defined(__CYGWIN__))
-#include "archive.h"
-
-/*
- * On non-Posix systems, allow the program to build, but choke if
- * this function is actually invoked.
- */
-int
-archive_write_set_compression_program(struct archive *_a, const char *cmd)
-{
- archive_set_error(_a, -1,
- "External compression programs not supported on this platform");
- return (ARCHIVE_FATAL);
-}
-
-#else
-
-#ifdef HAVE_SYS_WAIT_H
-# include <sys/wait.h>
-#endif
-#ifdef HAVE_ERRNO_H
-# include <errno.h>
-#endif
-#ifdef HAVE_FCNTL_H
-# include <fcntl.h>
-#endif
-#ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-# include <string.h>
-#endif
-
-#include "archive.h"
-#include "archive_private.h"
-#include "archive_write_private.h"
-
-#include "filter_fork.h"
-
-struct private_data {
- char *description;
- pid_t child;
- int child_stdin, child_stdout;
-
- char *child_buf;
- size_t child_buf_len, child_buf_avail;
-};
-
-static int archive_compressor_program_finish(struct archive_write *);
-static int archive_compressor_program_init(struct archive_write *);
-static int archive_compressor_program_write(struct archive_write *,
- const void *, size_t);
-
-/*
- * Allocate, initialize and return a archive object.
- */
-int
-archive_write_set_compression_program(struct archive *_a, const char *cmd)
-{
- struct archive_write *a = (struct archive_write *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_set_compression_program");
- a->compressor.init = &archive_compressor_program_init;
- a->compressor.config = strdup(cmd);
- return (ARCHIVE_OK);
-}
-
-/*
- * Setup callback.
- */
-static int
-archive_compressor_program_init(struct archive_write *a)
-{
- int ret;
- struct private_data *state;
- static const char *prefix = "Program: ";
- char *cmd = a->compressor.config;
-
- if (a->client_opener != NULL) {
- ret = (a->client_opener)(&a->archive, a->client_data);
- if (ret != ARCHIVE_OK)
- return (ret);
- }
-
- state = (struct private_data *)malloc(sizeof(*state));
- if (state == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate data for compression");
- return (ARCHIVE_FATAL);
- }
- memset(state, 0, sizeof(*state));
-
- a->archive.compression_code = ARCHIVE_COMPRESSION_PROGRAM;
- state->description = (char *)malloc(strlen(prefix) + strlen(cmd) + 1);
- strcpy(state->description, prefix);
- strcat(state->description, cmd);
- a->archive.compression_name = state->description;
-
- state->child_buf_len = a->bytes_per_block;
- state->child_buf_avail = 0;
- state->child_buf = malloc(state->child_buf_len);
-
- if (state->child_buf == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate data for compression buffer");
- free(state);
- return (ARCHIVE_FATAL);
- }
-
- if ((state->child = __archive_create_child(cmd,
- &state->child_stdin, &state->child_stdout)) == -1) {
- archive_set_error(&a->archive, EINVAL,
- "Can't initialise filter");
- free(state->child_buf);
- free(state);
- return (ARCHIVE_FATAL);
- }
-
- a->compressor.write = archive_compressor_program_write;
- a->compressor.finish = archive_compressor_program_finish;
-
- a->compressor.data = state;
- return (0);
-}
-
-static ssize_t
-child_write(struct archive_write *a, const char *buf, size_t buf_len)
-{
- struct private_data *state = a->compressor.data;
- ssize_t ret;
-
- if (state->child_stdin == -1)
- return (-1);
-
- if (buf_len == 0)
- return (-1);
-
-restart_write:
- do {
- ret = write(state->child_stdin, buf, buf_len);
- } while (ret == -1 && errno == EINTR);
-
- if (ret > 0)
- return (ret);
- if (ret == 0) {
- close(state->child_stdin);
- state->child_stdin = -1;
- fcntl(state->child_stdout, F_SETFL, 0);
- return (0);
- }
- if (ret == -1 && errno != EAGAIN)
- return (-1);
-
- if (state->child_stdout == -1) {
- fcntl(state->child_stdin, F_SETFL, 0);
- __archive_check_child(state->child_stdin, state->child_stdout);
- goto restart_write;
- }
-
- do {
- ret = read(state->child_stdout,
- state->child_buf + state->child_buf_avail,
- state->child_buf_len - state->child_buf_avail);
- } while (ret == -1 && errno == EINTR);
-
- if (ret == 0 || (ret == -1 && errno == EPIPE)) {
- close(state->child_stdout);
- state->child_stdout = -1;
- fcntl(state->child_stdin, F_SETFL, 0);
- goto restart_write;
- }
- if (ret == -1 && errno == EAGAIN) {
- __archive_check_child(state->child_stdin, state->child_stdout);
- goto restart_write;
- }
- if (ret == -1)
- return (-1);
-
- state->child_buf_avail += ret;
-
- ret = (a->client_writer)(&a->archive, a->client_data,
- state->child_buf, state->child_buf_avail);
- if (ret <= 0)
- return (-1);
-
- if ((size_t)ret < state->child_buf_avail) {
- memmove(state->child_buf, state->child_buf + ret,
- state->child_buf_avail - ret);
- }
- state->child_buf_avail -= ret;
- a->archive.raw_position += ret;
- goto restart_write;
-}
-
-/*
- * Write data to the compressed stream.
- */
-static int
-archive_compressor_program_write(struct archive_write *a, const void *buff,
- size_t length)
-{
- ssize_t ret;
- const char *buf;
-
- if (a->client_writer == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "No write callback is registered? "
- "This is probably an internal programming error.");
- return (ARCHIVE_FATAL);
- }
-
- buf = buff;
- while (length > 0) {
- ret = child_write(a, buf, length);
- if (ret == -1 || ret == 0) {
- archive_set_error(&a->archive, EIO,
- "Can't write to filter");
- return (ARCHIVE_FATAL);
- }
- length -= ret;
- buf += ret;
- }
-
- a->archive.file_position += length;
- return (ARCHIVE_OK);
-}
-
-
-/*
- * Finish the compression...
- */
-static int
-archive_compressor_program_finish(struct archive_write *a)
-{
- int ret, status;
- ssize_t bytes_read, bytes_written;
- struct private_data *state;
-
- state = (struct private_data *)a->compressor.data;
- ret = 0;
- if (a->client_writer == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "No write callback is registered? "
- "This is probably an internal programming error.");
- ret = ARCHIVE_FATAL;
- goto cleanup;
- }
-
- /* XXX pad compressed data. */
-
- close(state->child_stdin);
- state->child_stdin = -1;
- fcntl(state->child_stdout, F_SETFL, 0);
-
- for (;;) {
- do {
- bytes_read = read(state->child_stdout,
- state->child_buf + state->child_buf_avail,
- state->child_buf_len - state->child_buf_avail);
- } while (bytes_read == -1 && errno == EINTR);
-
- if (bytes_read == 0 || (bytes_read == -1 && errno == EPIPE))
- break;
-
- if (bytes_read == -1) {
- archive_set_error(&a->archive, errno,
- "Read from filter failed unexpectedly.");
- ret = ARCHIVE_FATAL;
- goto cleanup;
- }
- state->child_buf_avail += bytes_read;
-
- bytes_written = (a->client_writer)(&a->archive, a->client_data,
- state->child_buf, state->child_buf_avail);
- if (bytes_written <= 0) {
- ret = ARCHIVE_FATAL;
- goto cleanup;
- }
- if ((size_t)bytes_written < state->child_buf_avail) {
- memmove(state->child_buf,
- state->child_buf + bytes_written,
- state->child_buf_avail - bytes_written);
- }
- state->child_buf_avail -= bytes_written;
- a->archive.raw_position += bytes_written;
- }
-
- /* XXX pad final compressed block. */
-
-cleanup:
- /* Shut down the child. */
- if (state->child_stdin != -1)
- close(state->child_stdin);
- if (state->child_stdout != -1)
- close(state->child_stdout);
- while (waitpid(state->child, &status, 0) == -1 && errno == EINTR)
- continue;
-
- if (status != 0) {
- archive_set_error(&a->archive, EIO,
- "Filter exited with failure.");
- ret = ARCHIVE_FATAL;
- }
-
- /* Release our configuration data. */
- free(a->compressor.config);
- a->compressor.config = NULL;
-
- /* Release our private state data. */
- free(state->child_buf);
- free(state->description);
- free(state);
- return (ret);
-}
-
-#endif /* !defined(HAVE_PIPE) || !defined(HAVE_VFORK) || !defined(HAVE_FCNTL) */
diff --git a/libarchive/archive_write_set_compression_xz.c b/libarchive/archive_write_set_compression_xz.c
deleted file mode 100644
index 3193eb484568..000000000000
--- a/libarchive/archive_write_set_compression_xz.c
+++ /dev/null
@@ -1,439 +0,0 @@
-/*-
- * Copyright (c) 2009 Michihiro NAKAJIMA
- * Copyright (c) 2003-2007 Tim Kientzle
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "archive_platform.h"
-
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_xz.c 201108 2009-12-28 03:28:21Z kientzle $");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#include <time.h>
-#ifdef HAVE_LZMA_H
-#include <lzma.h>
-#endif
-
-#include "archive.h"
-#include "archive_private.h"
-#include "archive_write_private.h"
-
-#ifndef HAVE_LZMA_H
-int
-archive_write_set_compression_xz(struct archive *a)
-{
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "xz compression not supported on this platform");
- return (ARCHIVE_FATAL);
-}
-
-int
-archive_write_set_compression_lzma(struct archive *a)
-{
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "lzma compression not supported on this platform");
- return (ARCHIVE_FATAL);
-}
-#else
-/* Don't compile this if we don't have liblzma. */
-
-struct private_data {
- lzma_stream stream;
- lzma_filter lzmafilters[2];
- lzma_options_lzma lzma_opt;
- int64_t total_in;
- unsigned char *compressed;
- size_t compressed_buffer_size;
-};
-
-struct private_config {
- int compression_level;
-};
-
-static int archive_compressor_xz_init(struct archive_write *);
-static int archive_compressor_xz_options(struct archive_write *,
- const char *, const char *);
-static int archive_compressor_xz_finish(struct archive_write *);
-static int archive_compressor_xz_write(struct archive_write *,
- const void *, size_t);
-static int drive_compressor(struct archive_write *, struct private_data *,
- int finishing);
-
-
-/*
- * Allocate, initialize and return a archive object.
- */
-int
-archive_write_set_compression_xz(struct archive *_a)
-{
- struct private_config *config;
- struct archive_write *a = (struct archive_write *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_set_compression_xz");
- config = calloc(1, sizeof(*config));
- if (config == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Out of memory");
- return (ARCHIVE_FATAL);
- }
- a->compressor.config = config;
- a->compressor.finish = archive_compressor_xz_finish;
- config->compression_level = LZMA_PRESET_DEFAULT;
- a->compressor.init = &archive_compressor_xz_init;
- a->compressor.options = &archive_compressor_xz_options;
- a->archive.compression_code = ARCHIVE_COMPRESSION_XZ;
- a->archive.compression_name = "xz";
- return (ARCHIVE_OK);
-}
-
-/* LZMA is handled identically, we just need a different compression
- * code set. (The liblzma setup looks at the code to determine
- * the one place that XZ and LZMA require different handling.) */
-int
-archive_write_set_compression_lzma(struct archive *_a)
-{
- struct archive_write *a = (struct archive_write *)_a;
- int r = archive_write_set_compression_xz(_a);
- if (r != ARCHIVE_OK)
- return (r);
- a->archive.compression_code = ARCHIVE_COMPRESSION_LZMA;
- a->archive.compression_name = "lzma";
- return (ARCHIVE_OK);
-}
-
-static int
-archive_compressor_xz_init_stream(struct archive_write *a,
- struct private_data *state)
-{
- static const lzma_stream lzma_stream_init_data = LZMA_STREAM_INIT;
- int ret;
-
- state->stream = lzma_stream_init_data;
- state->stream.next_out = state->compressed;
- state->stream.avail_out = state->compressed_buffer_size;
- if (a->archive.compression_code == ARCHIVE_COMPRESSION_XZ)
- ret = lzma_stream_encoder(&(state->stream),
- state->lzmafilters, LZMA_CHECK_CRC64);
- else
- ret = lzma_alone_encoder(&(state->stream), &state->lzma_opt);
- if (ret == LZMA_OK)
- return (ARCHIVE_OK);
-
- switch (ret) {
- case LZMA_MEM_ERROR:
- archive_set_error(&a->archive, ENOMEM,
- "Internal error initializing compression library: "
- "Cannot allocate memory");
- break;
- default:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Internal error initializing compression library: "
- "It's a bug in liblzma");
- break;
- }
- return (ARCHIVE_FATAL);
-}
-
-/*
- * Setup callback.
- */
-static int
-archive_compressor_xz_init(struct archive_write *a)
-{
- int ret;
- struct private_data *state;
- struct private_config *config;
-
- if (a->client_opener != NULL) {
- ret = (a->client_opener)(&a->archive, a->client_data);
- if (ret != ARCHIVE_OK)
- return (ret);
- }
-
- state = (struct private_data *)malloc(sizeof(*state));
- if (state == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate data for compression");
- return (ARCHIVE_FATAL);
- }
- memset(state, 0, sizeof(*state));
- config = a->compressor.config;
-
- /*
- * See comment above. We should set compressed_buffer_size to
- * max(bytes_per_block, 65536), but the code can't handle that yet.
- */
- state->compressed_buffer_size = a->bytes_per_block;
- state->compressed = (unsigned char *)malloc(state->compressed_buffer_size);
- if (state->compressed == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate data for compression buffer");
- free(state);
- return (ARCHIVE_FATAL);
- }
- a->compressor.write = archive_compressor_xz_write;
-
- /* Initialize compression library. */
- if (lzma_lzma_preset(&state->lzma_opt, config->compression_level)) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Internal error initializing compression library");
- free(state->compressed);
- free(state);
- }
- state->lzmafilters[0].id = LZMA_FILTER_LZMA2;
- state->lzmafilters[0].options = &state->lzma_opt;
- state->lzmafilters[1].id = LZMA_VLI_UNKNOWN;/* Terminate */
- ret = archive_compressor_xz_init_stream(a, state);
- if (ret == LZMA_OK) {
- a->compressor.data = state;
- return (0);
- }
- /* Library setup failed: clean up. */
- free(state->compressed);
- free(state);
-
- return (ARCHIVE_FATAL);
-}
-
-/*
- * Set write options.
- */
-static int
-archive_compressor_xz_options(struct archive_write *a, const char *key,
- const char *value)
-{
- struct private_config *config;
-
- config = (struct private_config *)a->compressor.config;
- if (strcmp(key, "compression-level") == 0) {
- if (value == NULL || !(value[0] >= '0' && value[0] <= '9') ||
- value[1] != '\0')
- return (ARCHIVE_WARN);
- config->compression_level = value[0] - '0';
- if (config->compression_level > 6)
- config->compression_level = 6;
- return (ARCHIVE_OK);
- }
-
- return (ARCHIVE_WARN);
-}
-
-/*
- * Write data to the compressed stream.
- */
-static int
-archive_compressor_xz_write(struct archive_write *a, const void *buff,
- size_t length)
-{
- struct private_data *state;
- int ret;
-
- state = (struct private_data *)a->compressor.data;
- if (a->client_writer == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "No write callback is registered? "
- "This is probably an internal programming error.");
- return (ARCHIVE_FATAL);
- }
-
- /* Update statistics */
- state->total_in += length;
-
- /* Compress input data to output buffer */
- state->stream.next_in = buff;
- state->stream.avail_in = length;
- if ((ret = drive_compressor(a, state, 0)) != ARCHIVE_OK)
- return (ret);
-
- a->archive.file_position += length;
- return (ARCHIVE_OK);
-}
-
-
-/*
- * Finish the compression...
- */
-static int
-archive_compressor_xz_finish(struct archive_write *a)
-{
- ssize_t block_length, target_block_length, bytes_written;
- int ret;
- struct private_data *state;
- unsigned tocopy;
-
- ret = ARCHIVE_OK;
- state = (struct private_data *)a->compressor.data;
- if (state != NULL) {
- if (a->client_writer == NULL) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_PROGRAMMER,
- "No write callback is registered? "
- "This is probably an internal programming error.");
- ret = ARCHIVE_FATAL;
- goto cleanup;
- }
-
- /* By default, always pad the uncompressed data. */
- if (a->pad_uncompressed) {
- tocopy = a->bytes_per_block -
- (state->total_in % a->bytes_per_block);
- while (tocopy > 0 && tocopy < (unsigned)a->bytes_per_block) {
- state->stream.next_in = a->nulls;
- state->stream.avail_in = tocopy < a->null_length ?
- tocopy : a->null_length;
- state->total_in += state->stream.avail_in;
- tocopy -= state->stream.avail_in;
- ret = drive_compressor(a, state, 0);
- if (ret != ARCHIVE_OK)
- goto cleanup;
- }
- }
-
- /* Finish compression cycle */
- if (((ret = drive_compressor(a, state, 1))) != ARCHIVE_OK)
- goto cleanup;
-
- /* Optionally, pad the final compressed block. */
- block_length = state->stream.next_out - state->compressed;
-
- /* Tricky calculation to determine size of last block. */
- if (a->bytes_in_last_block <= 0)
- /* Default or Zero: pad to full block */
- target_block_length = a->bytes_per_block;
- else
- /* Round length to next multiple of bytes_in_last_block. */
- target_block_length = a->bytes_in_last_block *
- ( (block_length + a->bytes_in_last_block - 1) /
- a->bytes_in_last_block);
- if (target_block_length > a->bytes_per_block)
- target_block_length = a->bytes_per_block;
- if (block_length < target_block_length) {
- memset(state->stream.next_out, 0,
- target_block_length - block_length);
- block_length = target_block_length;
- }
-
- /* Write the last block */
- bytes_written = (a->client_writer)(&a->archive, a->client_data,
- state->compressed, block_length);
- if (bytes_written <= 0) {
- ret = ARCHIVE_FATAL;
- goto cleanup;
- }
- a->archive.raw_position += bytes_written;
-
- /* Cleanup: shut down compressor, release memory, etc. */
- cleanup:
- lzma_end(&(state->stream));
- free(state->compressed);
- free(state);
- }
- free(a->compressor.config);
- a->compressor.config = NULL;
- return (ret);
-}
-
-/*
- * Utility function to push input data through compressor,
- * writing full output blocks as necessary.
- *
- * Note that this handles both the regular write case (finishing ==
- * false) and the end-of-archive case (finishing == true).
- */
-static int
-drive_compressor(struct archive_write *a, struct private_data *state, int finishing)
-{
- ssize_t bytes_written;
- int ret;
-
- for (;;) {
- if (state->stream.avail_out == 0) {
- bytes_written = (a->client_writer)(&a->archive,
- a->client_data, state->compressed,
- state->compressed_buffer_size);
- if (bytes_written <= 0) {
- /* TODO: Handle this write failure */
- return (ARCHIVE_FATAL);
- } else if ((size_t)bytes_written < state->compressed_buffer_size) {
- /* Short write: Move remaining to
- * front of block and keep filling */
- memmove(state->compressed,
- state->compressed + bytes_written,
- state->compressed_buffer_size - bytes_written);
- }
- a->archive.raw_position += bytes_written;
- state->stream.next_out
- = state->compressed +
- state->compressed_buffer_size - bytes_written;
- state->stream.avail_out = bytes_written;
- }
-
- /* If there's nothing to do, we're done. */
- if (!finishing && state->stream.avail_in == 0)
- return (ARCHIVE_OK);
-
- ret = lzma_code(&(state->stream),
- finishing ? LZMA_FINISH : LZMA_RUN );
-
- switch (ret) {
- case LZMA_OK:
- /* In non-finishing case, check if compressor
- * consumed everything */
- if (!finishing && state->stream.avail_in == 0)
- return (ARCHIVE_OK);
- /* In finishing case, this return always means
- * there's more work */
- break;
- case LZMA_STREAM_END:
- /* This return can only occur in finishing case. */
- if (finishing)
- return (ARCHIVE_OK);
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "lzma compression data error");
- return (ARCHIVE_FATAL);
- case LZMA_MEMLIMIT_ERROR:
- archive_set_error(&a->archive, ENOMEM,
- "lzma compression error: "
- "%ju MiB would have been needed",
- (uintmax_t)((lzma_memusage(&(state->stream)) + 1024 * 1024 -1)
- / (1024 * 1024)));
- return (ARCHIVE_FATAL);
- default:
- /* Any other return value indicates an error. */
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "lzma compression failed:"
- " lzma_code() call returned status %d",
- ret);
- return (ARCHIVE_FATAL);
- }
- }
-}
-
-#endif /* HAVE_LZMA_H */
diff --git a/libarchive/archive_write_set_format.c b/libarchive/archive_write_set_format.c
index b1593fbe6d86..641d56f6c27e 100644
--- a/libarchive/archive_write_set_format.c
+++ b/libarchive/archive_write_set_format.c
@@ -41,18 +41,22 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format.c 201168 2009-1
static
struct { int code; int (*setter)(struct archive *); } codes[] =
{
+ { ARCHIVE_FORMAT_7ZIP, archive_write_set_format_7zip },
{ ARCHIVE_FORMAT_CPIO, archive_write_set_format_cpio },
- { ARCHIVE_FORMAT_CPIO_SVR4_NOCRC, archive_write_set_format_cpio_newc },
{ ARCHIVE_FORMAT_CPIO_POSIX, archive_write_set_format_cpio },
+ { ARCHIVE_FORMAT_CPIO_SVR4_NOCRC, archive_write_set_format_cpio_newc },
+ { ARCHIVE_FORMAT_ISO9660, archive_write_set_format_iso9660 },
{ ARCHIVE_FORMAT_MTREE, archive_write_set_format_mtree },
{ ARCHIVE_FORMAT_SHAR, archive_write_set_format_shar },
{ ARCHIVE_FORMAT_SHAR_BASE, archive_write_set_format_shar },
{ ARCHIVE_FORMAT_SHAR_DUMP, archive_write_set_format_shar_dump },
{ ARCHIVE_FORMAT_TAR, archive_write_set_format_pax_restricted },
+ { ARCHIVE_FORMAT_TAR_GNUTAR, archive_write_set_format_gnutar },
{ ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE, archive_write_set_format_pax },
{ ARCHIVE_FORMAT_TAR_PAX_RESTRICTED,
archive_write_set_format_pax_restricted },
{ ARCHIVE_FORMAT_TAR_USTAR, archive_write_set_format_ustar },
+ { ARCHIVE_FORMAT_XAR, archive_write_set_format_xar },
{ ARCHIVE_FORMAT_ZIP, archive_write_set_format_zip },
{ 0, NULL }
};
diff --git a/libarchive/archive_write_set_format_7zip.c b/libarchive/archive_write_set_format_7zip.c
new file mode 100644
index 000000000000..3f7a45be665f
--- /dev/null
+++ b/libarchive/archive_write_set_format_7zip.c
@@ -0,0 +1,2305 @@
+/*-
+ * Copyright (c) 2011-2012 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+__FBSDID("$FreeBSD$");
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include <stdlib.h>
+#ifdef HAVE_BZLIB_H
+#include <bzlib.h>
+#endif
+#if HAVE_LZMA_H
+#include <lzma.h>
+#endif
+#ifdef HAVE_ZLIB_H
+#include <zlib.h>
+#endif
+
+#include "archive.h"
+#ifndef HAVE_ZLIB_H
+#include "archive_crc32.h"
+#endif
+#include "archive_endian.h"
+#include "archive_entry.h"
+#include "archive_entry_locale.h"
+#include "archive_ppmd7_private.h"
+#include "archive_private.h"
+#include "archive_rb.h"
+#include "archive_string.h"
+#include "archive_write_private.h"
+
+/*
+ * Codec ID
+ */
+#define _7Z_COPY 0
+#define _7Z_LZMA1 0x030101
+#define _7Z_LZMA2 0x21
+#define _7Z_DEFLATE 0x040108
+#define _7Z_BZIP2 0x040202
+#define _7Z_PPMD 0x030401
+
+/*
+ * 7-Zip header property IDs.
+ */
+#define kEnd 0x00
+#define kHeader 0x01
+#define kArchiveProperties 0x02
+#define kAdditionalStreamsInfo 0x03
+#define kMainStreamsInfo 0x04
+#define kFilesInfo 0x05
+#define kPackInfo 0x06
+#define kUnPackInfo 0x07
+#define kSubStreamsInfo 0x08
+#define kSize 0x09
+#define kCRC 0x0A
+#define kFolder 0x0B
+#define kCodersUnPackSize 0x0C
+#define kNumUnPackStream 0x0D
+#define kEmptyStream 0x0E
+#define kEmptyFile 0x0F
+#define kAnti 0x10
+#define kName 0x11
+#define kCTime 0x12
+#define kATime 0x13
+#define kMTime 0x14
+#define kAttributes 0x15
+#define kEncodedHeader 0x17
+
+enum la_zaction {
+ ARCHIVE_Z_FINISH,
+ ARCHIVE_Z_RUN
+};
+
+/*
+ * A stream object of universal compressor.
+ */
+struct la_zstream {
+ const uint8_t *next_in;
+ size_t avail_in;
+ uint64_t total_in;
+
+ uint8_t *next_out;
+ size_t avail_out;
+ uint64_t total_out;
+
+ uint32_t prop_size;
+ uint8_t *props;
+
+ int valid;
+ void *real_stream;
+ int (*code) (struct archive *a,
+ struct la_zstream *lastrm,
+ enum la_zaction action);
+ int (*end)(struct archive *a,
+ struct la_zstream *lastrm);
+};
+
+#define PPMD7_DEFAULT_ORDER 6
+#define PPMD7_DEFAULT_MEM_SIZE (1 << 24)
+
+struct ppmd_stream {
+ int stat;
+ CPpmd7 ppmd7_context;
+ CPpmd7z_RangeEnc range_enc;
+ IByteOut byteout;
+ uint8_t *buff;
+ uint8_t *buff_ptr;
+ uint8_t *buff_end;
+ size_t buff_bytes;
+};
+
+struct coder {
+ unsigned codec;
+ size_t prop_size;
+ uint8_t *props;
+};
+
+struct file {
+ struct archive_rb_node rbnode;
+
+ struct file *next;
+ unsigned name_len;
+ uint8_t *utf16name;/* UTF16-LE name. */
+ uint64_t size;
+ unsigned flg;
+#define MTIME_IS_SET (1<<0)
+#define ATIME_IS_SET (1<<1)
+#define CTIME_IS_SET (1<<2)
+#define CRC32_IS_SET (1<<3)
+#define HAS_STREAM (1<<4)
+
+ struct {
+ time_t time;
+ long time_ns;
+ } times[3];
+#define MTIME 0
+#define ATIME 1
+#define CTIME 2
+
+ mode_t mode;
+ uint32_t crc32;
+
+ int dir:1;
+};
+
+struct _7zip {
+ int temp_fd;
+ uint64_t temp_offset;
+
+ struct file *cur_file;
+ size_t total_number_entry;
+ size_t total_number_nonempty_entry;
+ size_t total_number_empty_entry;
+ size_t total_number_dir_entry;
+ size_t total_bytes_entry_name;
+ size_t total_number_time_defined[3];
+ uint64_t total_bytes_compressed;
+ uint64_t total_bytes_uncompressed;
+ uint64_t entry_bytes_remaining;
+ uint32_t entry_crc32;
+ uint32_t precode_crc32;
+ uint32_t encoded_crc32;
+ int crc32flg;
+#define PRECODE_CRC32 1
+#define ENCODED_CRC32 2
+
+ unsigned opt_compression;
+ int opt_compression_level;
+
+ struct la_zstream stream;
+ struct coder coder;
+
+ struct archive_string_conv *sconv;
+
+ /*
+ * Compressed data buffer.
+ */
+ unsigned char wbuff[1024 * 64];
+ size_t wbuff_remaining;
+
+ /*
+ * The list of the file entries which has its contents is used to
+ * manage struct file objects.
+ * We use 'next' a menber of struct file to chain.
+ */
+ struct {
+ struct file *first;
+ struct file **last;
+ } file_list, empty_list;
+ struct archive_rb_tree rbtree;/* for empty files */
+};
+
+static int _7z_options(struct archive_write *,
+ const char *, const char *);
+static int _7z_write_header(struct archive_write *,
+ struct archive_entry *);
+static ssize_t _7z_write_data(struct archive_write *,
+ const void *, size_t);
+static int _7z_finish_entry(struct archive_write *);
+static int _7z_close(struct archive_write *);
+static int _7z_free(struct archive_write *);
+static int file_cmp_node(const struct archive_rb_node *,
+ const struct archive_rb_node *);
+static int file_cmp_key(const struct archive_rb_node *, const void *);
+static int file_new(struct archive_write *a, struct archive_entry *,
+ struct file **);
+static void file_free(struct file *);
+static void file_register(struct _7zip *, struct file *);
+static void file_register_empty(struct _7zip *, struct file *);
+static void file_init_register(struct _7zip *);
+static void file_init_register_empty(struct _7zip *);
+static void file_free_register(struct _7zip *);
+static ssize_t compress_out(struct archive_write *, const void *, size_t ,
+ enum la_zaction);
+static int compression_init_encoder_copy(struct archive *,
+ struct la_zstream *);
+static int compression_code_copy(struct archive *,
+ struct la_zstream *, enum la_zaction);
+static int compression_end_copy(struct archive *, struct la_zstream *);
+static int compression_init_encoder_deflate(struct archive *,
+ struct la_zstream *, int, int);
+#ifdef HAVE_ZLIB_H
+static int compression_code_deflate(struct archive *,
+ struct la_zstream *, enum la_zaction);
+static int compression_end_deflate(struct archive *, struct la_zstream *);
+#endif
+static int compression_init_encoder_bzip2(struct archive *,
+ struct la_zstream *, int);
+#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
+static int compression_code_bzip2(struct archive *,
+ struct la_zstream *, enum la_zaction);
+static int compression_end_bzip2(struct archive *, struct la_zstream *);
+#endif
+static int compression_init_encoder_lzma1(struct archive *,
+ struct la_zstream *, int);
+static int compression_init_encoder_lzma2(struct archive *,
+ struct la_zstream *, int);
+#if defined(HAVE_LZMA_H)
+static int compression_code_lzma(struct archive *,
+ struct la_zstream *, enum la_zaction);
+static int compression_end_lzma(struct archive *, struct la_zstream *);
+#endif
+static int compression_init_encoder_ppmd(struct archive *,
+ struct la_zstream *, unsigned, uint32_t);
+static int compression_code_ppmd(struct archive *,
+ struct la_zstream *, enum la_zaction);
+static int compression_end_ppmd(struct archive *, struct la_zstream *);
+static int _7z_compression_init_encoder(struct archive_write *, unsigned,
+ int);
+static int compression_code(struct archive *,
+ struct la_zstream *, enum la_zaction);
+static int compression_end(struct archive *,
+ struct la_zstream *);
+static int enc_uint64(struct archive_write *, uint64_t);
+static int make_header(struct archive_write *, uint64_t, uint64_t,
+ uint64_t, int, struct coder *);
+static int make_streamsInfo(struct archive_write *, uint64_t, uint64_t,
+ uint64_t, int, struct coder *, int, uint32_t);
+
+int
+archive_write_set_format_7zip(struct archive *_a)
+{
+ static const struct archive_rb_tree_ops rb_ops = {
+ file_cmp_node, file_cmp_key
+ };
+ struct archive_write *a = (struct archive_write *)_a;
+ struct _7zip *zip;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_7zip");
+
+ /* If another format was already registered, unregister it. */
+ if (a->format_free != NULL)
+ (a->format_free)(a);
+
+ zip = calloc(1, sizeof(*zip));
+ if (zip == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate 7-Zip data");
+ return (ARCHIVE_FATAL);
+ }
+ zip->temp_fd = -1;
+ __archive_rb_tree_init(&(zip->rbtree), &rb_ops);
+ file_init_register(zip);
+ file_init_register_empty(zip);
+
+ /* Set default compression type and its level. */
+#if HAVE_LZMA_H
+ zip->opt_compression = _7Z_LZMA1;
+#elif defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
+ zip->opt_compression = _7Z_BZIP2;
+#elif defined(HAVE_ZLIB_H)
+ zip->opt_compression = _7Z_DEFLATE;
+#else
+ zip->opt_compression = _7Z_COPY;
+#endif
+ zip->opt_compression_level = 6;
+
+ a->format_data = zip;
+
+ a->format_name = "7zip";
+ a->format_options = _7z_options;
+ a->format_write_header = _7z_write_header;
+ a->format_write_data = _7z_write_data;
+ a->format_finish_entry = _7z_finish_entry;
+ a->format_close = _7z_close;
+ a->format_free = _7z_free;
+ a->archive.archive_format = ARCHIVE_FORMAT_7ZIP;
+ a->archive.archive_format_name = "7zip";
+
+ return (ARCHIVE_OK);
+}
+
+static int
+_7z_options(struct archive_write *a, const char *key, const char *value)
+{
+ struct _7zip *zip;
+
+ zip = (struct _7zip *)a->format_data;
+
+ if (strcmp(key, "compression") == 0) {
+ const char *name = NULL;
+
+ if (value == NULL || strcmp(value, "copy") == 0 ||
+ strcmp(value, "COPY") == 0 ||
+ strcmp(value, "store") == 0 ||
+ strcmp(value, "STORE") == 0)
+ zip->opt_compression = _7Z_COPY;
+ else if (strcmp(value, "deflate") == 0 ||
+ strcmp(value, "DEFLATE") == 0)
+#if HAVE_ZLIB_H
+ zip->opt_compression = _7Z_DEFLATE;
+#else
+ name = "deflate";
+#endif
+ else if (strcmp(value, "bzip2") == 0 ||
+ strcmp(value, "BZIP2") == 0)
+#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
+ zip->opt_compression = _7Z_BZIP2;
+#else
+ name = "bzip2";
+#endif
+ else if (strcmp(value, "lzma1") == 0 ||
+ strcmp(value, "LZMA1") == 0)
+#if HAVE_LZMA_H
+ zip->opt_compression = _7Z_LZMA1;
+#else
+ name = "lzma1";
+#endif
+ else if (strcmp(value, "lzma2") == 0 ||
+ strcmp(value, "LZMA2") == 0)
+#if HAVE_LZMA_H
+ zip->opt_compression = _7Z_LZMA2;
+#else
+ name = "lzma2";
+#endif
+ else if (strcmp(value, "ppmd") == 0 ||
+ strcmp(value, "PPMD") == 0 ||
+ strcmp(value, "PPMd") == 0)
+ zip->opt_compression = _7Z_PPMD;
+ else {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "Unkonwn compression name: `%s'",
+ value);
+ return (ARCHIVE_FAILED);
+ }
+ if (name != NULL) {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "`%s' compression not supported "
+ "on this platform",
+ name);
+ return (ARCHIVE_FAILED);
+ }
+ return (ARCHIVE_OK);
+ }
+ if (strcmp(key, "compression-level") == 0) {
+ if (value == NULL ||
+ !(value[0] >= '0' && value[0] <= '9') ||
+ value[1] != '\0') {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "Illeagal value `%s'",
+ value);
+ return (ARCHIVE_FAILED);
+ }
+ zip->opt_compression_level = value[0] - '0';
+ return (ARCHIVE_OK);
+ }
+
+ return (ARCHIVE_FAILED);
+}
+
+static int
+_7z_write_header(struct archive_write *a, struct archive_entry *entry)
+{
+ struct _7zip *zip;
+ struct file *file;
+ int r;
+
+ zip = (struct _7zip *)a->format_data;
+ zip->cur_file = NULL;
+ zip->entry_bytes_remaining = 0;
+
+ if (zip->sconv == NULL) {
+ zip->sconv = archive_string_conversion_to_charset(
+ &a->archive, "UTF-16LE", 1);
+ if (zip->sconv == NULL)
+ return (ARCHIVE_FATAL);
+ }
+
+ r = file_new(a, entry, &file);
+ if (r < ARCHIVE_WARN) {
+ file_free(file);
+ return (r);
+ }
+
+ if (file->flg & MTIME_IS_SET)
+ zip->total_number_time_defined[MTIME]++;
+ if (file->flg & CTIME_IS_SET)
+ zip->total_number_time_defined[CTIME]++;
+ if (file->flg & ATIME_IS_SET)
+ zip->total_number_time_defined[ATIME]++;
+
+ if (file->size == 0 && file->dir) {
+ if (!__archive_rb_tree_insert_node(&(zip->rbtree),
+ (struct archive_rb_node *)file))
+ file_free(file);
+ }
+ zip->total_number_entry++;
+ zip->total_bytes_entry_name += file->name_len + 2;
+ if (file->size == 0) {
+ /* Count up the number of empty files. */
+ zip->total_number_empty_entry++;
+ if (file->dir)
+ zip->total_number_dir_entry++;
+ else
+ file_register_empty(zip, file);
+ return (r);
+ }
+
+ /*
+ * Init compression.
+ */
+ if ((zip->total_number_entry - zip->total_number_empty_entry) == 1) {
+ r = _7z_compression_init_encoder(a, zip->opt_compression,
+ zip->opt_compression_level);
+ if (r < 0) {
+ file_free(file);
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ /* Register a non-empty file. */
+ file_register(zip, file);
+
+ /*
+ * Set the current file to cur_file to read its contents.
+ */
+ zip->cur_file = file;
+
+
+ /* Save a offset of current file in temporary file. */
+ zip->entry_bytes_remaining = file->size;
+ zip->entry_crc32 = 0;
+
+ /*
+ * Store a symbolic link name as file contents.
+ */
+ if (archive_entry_filetype(entry) == AE_IFLNK) {
+ ssize_t bytes;
+ const void *p = (const void *)archive_entry_symlink(entry);
+ bytes = compress_out(a, p, file->size, ARCHIVE_Z_RUN);
+ if (bytes < 0)
+ return ((int)bytes);
+ zip->entry_crc32 = crc32(zip->entry_crc32, p, bytes);
+ zip->entry_bytes_remaining -= bytes;
+ }
+
+ return (r);
+}
+
+/*
+ * Write data to a temporary file.
+ */
+static int
+write_to_temp(struct archive_write *a, const void *buff, size_t s)
+{
+ struct _7zip *zip;
+ unsigned char *p;
+ ssize_t ws;
+
+ zip = (struct _7zip *)a->format_data;
+
+ /*
+ * Open a temporary file.
+ */
+ if (zip->temp_fd == -1) {
+ zip->temp_offset = 0;
+ zip->temp_fd = __archive_mktemp(NULL);
+ if (zip->temp_fd < 0) {
+ archive_set_error(&a->archive, errno,
+ "Couldn't create temporary file");
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ p = (unsigned char *)buff;
+ while (s) {
+ ws = write(zip->temp_fd, p, s);
+ if (ws < 0) {
+ archive_set_error(&(a->archive), errno,
+ "fwrite function failed");
+ return (ARCHIVE_FATAL);
+ }
+ s -= ws;
+ p += ws;
+ zip->temp_offset += ws;
+ }
+ return (ARCHIVE_OK);
+}
+
+static ssize_t
+compress_out(struct archive_write *a, const void *buff, size_t s,
+ enum la_zaction run)
+{
+ struct _7zip *zip = (struct _7zip *)a->format_data;
+ int r;
+
+ if (run == ARCHIVE_Z_FINISH && zip->stream.total_in == 0 && s == 0)
+ return (0);
+
+ if ((zip->crc32flg & PRECODE_CRC32) && s)
+ zip->precode_crc32 = crc32(zip->precode_crc32, buff, s);
+ zip->stream.next_in = (const unsigned char *)buff;
+ zip->stream.avail_in = s;
+ do {
+ /* Compress file data. */
+ r = compression_code(&(a->archive), &(zip->stream), run);
+ if (r != ARCHIVE_OK && r != ARCHIVE_EOF)
+ return (ARCHIVE_FATAL);
+ if (zip->stream.avail_out == 0) {
+ if (write_to_temp(a, zip->wbuff, sizeof(zip->wbuff))
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ zip->stream.next_out = zip->wbuff;
+ zip->stream.avail_out = sizeof(zip->wbuff);
+ if (zip->crc32flg & ENCODED_CRC32)
+ zip->encoded_crc32 = crc32(zip->encoded_crc32,
+ zip->wbuff, sizeof(zip->wbuff));
+ }
+ } while (zip->stream.avail_in);
+ if (run == ARCHIVE_Z_FINISH) {
+ uint64_t bytes = sizeof(zip->wbuff) - zip->stream.avail_out;
+ if (write_to_temp(a, zip->wbuff, bytes) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ if ((zip->crc32flg & ENCODED_CRC32) && bytes)
+ zip->encoded_crc32 = crc32(zip->encoded_crc32,
+ zip->wbuff, bytes);
+ }
+
+ return (s);
+}
+
+static ssize_t
+_7z_write_data(struct archive_write *a, const void *buff, size_t s)
+{
+ struct _7zip *zip;
+ ssize_t bytes;
+
+ zip = (struct _7zip *)a->format_data;
+
+ if (s > zip->entry_bytes_remaining)
+ s = zip->entry_bytes_remaining;
+ if (s == 0 || zip->cur_file == NULL)
+ return (0);
+ bytes = compress_out(a, buff, s, ARCHIVE_Z_RUN);
+ if (bytes < 0)
+ return (bytes);
+ zip->entry_crc32 = crc32(zip->entry_crc32, buff, bytes);
+ zip->entry_bytes_remaining -= bytes;
+ return (bytes);
+}
+
+static int
+_7z_finish_entry(struct archive_write *a)
+{
+ struct _7zip *zip;
+ size_t s;
+ ssize_t r;
+
+ zip = (struct _7zip *)a->format_data;
+ if (zip->cur_file == NULL)
+ return (ARCHIVE_OK);
+
+ while (zip->entry_bytes_remaining > 0) {
+ s = zip->entry_bytes_remaining;
+ if (s > a->null_length)
+ s = a->null_length;
+ r = _7z_write_data(a, a->nulls, s);
+ if (r < 0)
+ return (r);
+ }
+ zip->total_bytes_compressed += zip->stream.total_in;
+ zip->total_bytes_uncompressed += zip->stream.total_out;
+ zip->cur_file->crc32 = zip->entry_crc32;
+ zip->cur_file = NULL;
+
+ return (ARCHIVE_OK);
+}
+
+static int
+flush_wbuff(struct archive_write *a)
+{
+ struct _7zip *zip;
+ int r;
+ size_t s;
+
+ zip = (struct _7zip *)a->format_data;
+ s = sizeof(zip->wbuff) - zip->wbuff_remaining;
+ r = __archive_write_output(a, zip->wbuff, s);
+ if (r != ARCHIVE_OK)
+ return (r);
+ zip->wbuff_remaining = sizeof(zip->wbuff);
+ return (r);
+}
+
+static int
+copy_out(struct archive_write *a, uint64_t offset, uint64_t length)
+{
+ struct _7zip *zip;
+ int r;
+
+ zip = (struct _7zip *)a->format_data;
+ if (zip->temp_offset > 0 &&
+ lseek(zip->temp_fd, offset, SEEK_SET) < 0) {
+ archive_set_error(&(a->archive), errno, "lseek failed");
+ return (ARCHIVE_FATAL);
+ }
+ while (length) {
+ size_t rsize;
+ ssize_t rs;
+ unsigned char *wb;
+
+ if (length > zip->wbuff_remaining)
+ rsize = zip->wbuff_remaining;
+ else
+ rsize = (size_t)length;
+ wb = zip->wbuff + (sizeof(zip->wbuff) - zip->wbuff_remaining);
+ rs = read(zip->temp_fd, wb, rsize);
+ if (rs < 0) {
+ archive_set_error(&(a->archive), errno,
+ "Can't read temporary file(%jd)",
+ (intmax_t)rs);
+ return (ARCHIVE_FATAL);
+ }
+ if (rs == 0) {
+ archive_set_error(&(a->archive), 0,
+ "Truncated 7-Zip archive");
+ return (ARCHIVE_FATAL);
+ }
+ zip->wbuff_remaining -= rs;
+ length -= rs;
+ if (zip->wbuff_remaining == 0) {
+ r = flush_wbuff(a);
+ if (r != ARCHIVE_OK)
+ return (r);
+ }
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+_7z_close(struct archive_write *a)
+{
+ struct _7zip *zip;
+ unsigned char *wb;
+ uint64_t header_offset, header_size, header_unpacksize;
+ uint64_t length;
+ uint32_t header_crc32;
+ int r;
+
+ zip = (struct _7zip *)a->format_data;
+
+ if (zip->total_number_entry > 0) {
+ struct archive_rb_node *n;
+ uint64_t data_offset, data_size, data_unpacksize;
+ unsigned header_compression;
+
+ r = (int)compress_out(a, NULL, 0, ARCHIVE_Z_FINISH);
+ if (r < 0)
+ return (r);
+ data_offset = 0;
+ data_size = zip->stream.total_out;
+ data_unpacksize = zip->stream.total_in;
+ zip->coder.codec = zip->opt_compression;
+ zip->coder.prop_size = zip->stream.prop_size;
+ zip->coder.props = zip->stream.props;
+ zip->stream.prop_size = 0;
+ zip->stream.props = NULL;
+ zip->total_number_nonempty_entry =
+ zip->total_number_entry - zip->total_number_empty_entry;
+
+ /* Connect an empty file list. */
+ if (zip->empty_list.first != NULL) {
+ *zip->file_list.last = zip->empty_list.first;
+ zip->file_list.last = zip->empty_list.last;
+ }
+ /* Connect a directory file list. */
+ ARCHIVE_RB_TREE_FOREACH(n, &(zip->rbtree)) {
+ file_register(zip, (struct file *)n);
+ }
+
+ /*
+ * NOTE: 7z command supports just LZMA1, LZMA2 and COPY for
+ * the compression type for encoding the header.
+ */
+#if HAVE_LZMA_H
+ header_compression = _7Z_LZMA1;
+ /* If the stored file is only one, do not encode the header.
+ * This is the same way 7z command does. */
+ if (zip->total_number_entry == 1)
+ header_compression = _7Z_COPY;
+#else
+ header_compression = _7Z_COPY;
+#endif
+ r = _7z_compression_init_encoder(a, header_compression, 6);
+ if (r < 0)
+ return (r);
+ zip->crc32flg = PRECODE_CRC32;
+ zip->precode_crc32 = 0;
+ r = make_header(a, data_offset, data_size, data_unpacksize,
+ 1, &(zip->coder));
+ if (r < 0)
+ return (r);
+ r = (int)compress_out(a, NULL, 0, ARCHIVE_Z_FINISH);
+ if (r < 0)
+ return (r);
+ header_offset = data_offset + data_size;
+ header_size = zip->stream.total_out;
+ header_crc32 = zip->precode_crc32;
+ header_unpacksize = zip->stream.total_in;
+
+ if (header_compression != _7Z_COPY) {
+ /*
+ * Encode the header in order to reduce the size
+ * of the archive.
+ */
+ free(zip->coder.props);
+ zip->coder.codec = header_compression;
+ zip->coder.prop_size = zip->stream.prop_size;
+ zip->coder.props = zip->stream.props;
+ zip->stream.prop_size = 0;
+ zip->stream.props = NULL;
+
+ r = _7z_compression_init_encoder(a, _7Z_COPY, 0);
+ if (r < 0)
+ return (r);
+ zip->crc32flg = ENCODED_CRC32;
+ zip->encoded_crc32 = 0;
+
+ /*
+ * Make EncodedHeader.
+ */
+ r = enc_uint64(a, kEncodedHeader);
+ if (r < 0)
+ return (r);
+ r = make_streamsInfo(a, header_offset, header_size,
+ header_unpacksize, 1, &(zip->coder), 0,
+ header_crc32);
+ if (r < 0)
+ return (r);
+ r = (int)compress_out(a, NULL, 0, ARCHIVE_Z_FINISH);
+ if (r < 0)
+ return (r);
+ header_offset = header_offset + header_size;
+ header_size = zip->stream.total_out;
+ header_crc32 = zip->encoded_crc32;
+ }
+ zip->crc32flg = 0;
+ } else {
+ header_offset = header_size = 0;
+ header_crc32 = 0;
+ }
+
+ length = zip->temp_offset;
+
+ /*
+ * Make the zip header on wbuff(write buffer).
+ */
+ wb = zip->wbuff;
+ zip->wbuff_remaining = sizeof(zip->wbuff);
+ memcpy(&wb[0], "7z\xBC\xAF\x27\x1C", 6);
+ wb[6] = 0;/* Major version. */
+ wb[7] = 3;/* Minor version. */
+ archive_le64enc(&wb[12], header_offset);/* Next Header Offset */
+ archive_le64enc(&wb[20], header_size);/* Next Header Size */
+ archive_le32enc(&wb[28], header_crc32);/* Next Header CRC */
+ archive_le32enc(&wb[8], crc32(0, &wb[12], 20));/* Start Header CRC */
+ zip->wbuff_remaining -= 32;
+
+ /*
+ * Read all file contents and an encoded header from the temporary
+ * file and write out it.
+ */
+ r = copy_out(a, 0, length);
+ if (r != ARCHIVE_OK)
+ return (r);
+ r = flush_wbuff(a);
+ return (r);
+}
+
+/*
+ * Encode 64 bits value into 7-Zip's encoded UINT64 value.
+ */
+static int
+enc_uint64(struct archive_write *a, uint64_t val)
+{
+ unsigned mask = 0x80;
+ uint8_t numdata[9];
+ int i;
+
+ numdata[0] = 0;
+ for (i = 1; i < sizeof(numdata); i++) {
+ if (val < mask) {
+ numdata[0] |= (uint8_t)val;
+ break;
+ }
+ numdata[i] = (uint8_t)val;
+ val >>= 8;
+ numdata[0] |= mask;
+ mask >>= 1;
+ }
+ return (compress_out(a, numdata, i, ARCHIVE_Z_RUN));
+}
+
+static int
+make_substreamsInfo(struct archive_write *a, struct coder *coders)
+{
+ struct _7zip *zip = (struct _7zip *)a->format_data;
+ struct file *file;
+ int r;
+
+ /*
+ * Make SubStreamsInfo.
+ */
+ r = enc_uint64(a, kSubStreamsInfo);
+ if (r < 0)
+ return (r);
+
+ if (zip->total_number_nonempty_entry > 1 && coders->codec != _7Z_COPY) {
+ /*
+ * Make NumUnPackStream.
+ */
+ r = enc_uint64(a, kNumUnPackStream);
+ if (r < 0)
+ return (r);
+
+ /* Write numUnpackStreams */
+ r = enc_uint64(a, zip->total_number_nonempty_entry);
+ if (r < 0)
+ return (r);
+
+ /*
+ * Make kSize.
+ */
+ r = enc_uint64(a, kSize);
+ if (r < 0)
+ return (r);
+ file = zip->file_list.first;
+ for (;file != NULL; file = file->next) {
+ if (file->next == NULL ||
+ file->next->size == 0)
+ break;
+ r = enc_uint64(a, file->size);
+ if (r < 0)
+ return (r);
+ }
+ }
+
+ /*
+ * Make CRC.
+ */
+ r = enc_uint64(a, kCRC);
+ if (r < 0)
+ return (r);
+
+
+ /* All are defined */
+ r = enc_uint64(a, 1);
+ if (r < 0)
+ return (r);
+ file = zip->file_list.first;
+ for (;file != NULL; file = file->next) {
+ uint8_t crc[4];
+ if (file->size == 0)
+ break;
+ archive_le32enc(crc, file->crc32);
+ r = compress_out(a, crc, 4, ARCHIVE_Z_RUN);
+ if (r < 0)
+ return (r);
+ }
+
+ /* Write End. */
+ r = enc_uint64(a, kEnd);
+ if (r < 0)
+ return (r);
+ return (ARCHIVE_OK);
+}
+
+static int
+make_streamsInfo(struct archive_write *a, uint64_t offset, uint64_t pack_size,
+ uint64_t unpack_size, int num_coder, struct coder *coders, int substrm,
+ uint32_t header_crc)
+{
+ struct _7zip *zip = (struct _7zip *)a->format_data;
+ uint8_t codec_buff[8];
+ int numFolders, fi;
+ int codec_size;
+ int i, r;
+
+ if (coders->codec == _7Z_COPY)
+ numFolders = zip->total_number_nonempty_entry;
+ else
+ numFolders = 1;
+
+ /*
+ * Make PackInfo.
+ */
+ r = enc_uint64(a, kPackInfo);
+ if (r < 0)
+ return (r);
+
+ /* Write PackPos. */
+ r = enc_uint64(a, offset);
+ if (r < 0)
+ return (r);
+
+ /* Write NumPackStreams. */
+ r = enc_uint64(a, numFolders);
+ if (r < 0)
+ return (r);
+
+ /* Make Size. */
+ r = enc_uint64(a, kSize);
+ if (r < 0)
+ return (r);
+
+ if (numFolders > 1) {
+ struct file *file = zip->file_list.first;
+ for (;file != NULL; file = file->next) {
+ if (file->size == 0)
+ break;
+ r = enc_uint64(a, file->size);
+ if (r < 0)
+ return (r);
+ }
+ } else {
+ /* Write size. */
+ r = enc_uint64(a, pack_size);
+ if (r < 0)
+ return (r);
+ }
+
+ r = enc_uint64(a, kEnd);
+ if (r < 0)
+ return (r);
+
+ /*
+ * Make UnPackInfo.
+ */
+ r = enc_uint64(a, kUnPackInfo);
+ if (r < 0)
+ return (r);
+
+ /*
+ * Make Folder.
+ */
+ r = enc_uint64(a, kFolder);
+ if (r < 0)
+ return (r);
+
+ /* Write NumFolders. */
+ r = enc_uint64(a, numFolders);
+ if (r < 0)
+ return (r);
+
+ /* Write External. */
+ r = enc_uint64(a, 0);
+ if (r < 0)
+ return (r);
+
+ for (fi = 0; fi < numFolders; fi++) {
+ /* Write NumCoders. */
+ r = enc_uint64(a, num_coder);
+ if (r < 0)
+ return (r);
+
+ for (i = 0; i < num_coder; i++) {
+ unsigned codec_id = coders[i].codec;
+
+ /* Write Codec flag. */
+ archive_be64enc(codec_buff, codec_id);
+ for (codec_size = 8; codec_size > 0; codec_size--) {
+ if (codec_buff[8 - codec_size])
+ break;
+ }
+ if (codec_size == 0)
+ codec_size = 1;
+ if (coders[i].prop_size)
+ r = enc_uint64(a, codec_size | 0x20);
+ else
+ r = enc_uint64(a, codec_size);
+ if (r < 0)
+ return (r);
+
+ /* Write Codec ID. */
+ codec_size &= 0x0f;
+ r = compress_out(a, &codec_buff[8-codec_size],
+ codec_size, ARCHIVE_Z_RUN);
+ if (r < 0)
+ return (r);
+
+ if (coders[i].prop_size) {
+ /* Write Codec property size. */
+ r = enc_uint64(a, coders[i].prop_size);
+ if (r < 0)
+ return (r);
+
+ /* Write Codec properties. */
+ r = compress_out(a, coders[i].props,
+ coders[i].prop_size, ARCHIVE_Z_RUN);
+ if (r < 0)
+ return (r);
+ }
+ }
+ }
+
+ /*
+ * Make CodersUnPackSize.
+ */
+ r = enc_uint64(a, kCodersUnPackSize);
+ if (r < 0)
+ return (r);
+
+ if (numFolders > 1) {
+ struct file *file = zip->file_list.first;
+ for (;file != NULL; file = file->next) {
+ if (file->size == 0)
+ break;
+ r = enc_uint64(a, file->size);
+ if (r < 0)
+ return (r);
+ }
+
+ } else {
+ /* Write UnPackSize. */
+ r = enc_uint64(a, unpack_size);
+ if (r < 0)
+ return (r);
+ }
+
+ if (!substrm) {
+ uint8_t crc[4];
+ /*
+ * Make CRC.
+ */
+ r = enc_uint64(a, kCRC);
+ if (r < 0)
+ return (r);
+
+ /* All are defined */
+ r = enc_uint64(a, 1);
+ if (r < 0)
+ return (r);
+ archive_le32enc(crc, header_crc);
+ r = compress_out(a, crc, 4, ARCHIVE_Z_RUN);
+ if (r < 0)
+ return (r);
+ }
+
+ /* Write End. */
+ r = enc_uint64(a, kEnd);
+ if (r < 0)
+ return (r);
+
+ if (substrm) {
+ /*
+ * Make SubStreamsInfo.
+ */
+ r = make_substreamsInfo(a, coders);
+ if (r < 0)
+ return (r);
+ }
+
+
+ /* Write End. */
+ r = enc_uint64(a, kEnd);
+ if (r < 0)
+ return (r);
+
+ return (ARCHIVE_OK);
+}
+
+
+#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
+static uint64_t
+utcToFiletime(time_t time, long ns)
+{
+ uint64_t fileTime;
+
+ fileTime = time;
+ fileTime *= 10000000;
+ fileTime += ns / 100;
+ fileTime += EPOC_TIME;
+ return (fileTime);
+}
+
+static int
+make_time(struct archive_write *a, uint8_t type, unsigned flg, int ti)
+{
+ uint8_t filetime[8];
+ struct _7zip *zip = (struct _7zip *)a->format_data;
+ struct file *file;
+ int r;
+ uint8_t mask, byte;
+
+ /*
+ * Make Time Bools.
+ */
+ if (zip->total_number_time_defined[ti] == zip->total_number_entry) {
+ /* Write Time Type. */
+ r = enc_uint64(a, type);
+ if (r < 0)
+ return (r);
+ /* Write EmptyStream Size. */
+ r = enc_uint64(a, 2 + zip->total_number_entry * 8);
+ if (r < 0)
+ return (r);
+ /* All are defined. */
+ r = enc_uint64(a, 1);
+ if (r < 0)
+ return (r);
+ } else {
+ if (zip->total_number_time_defined[ti] == 0)
+ return (ARCHIVE_OK);
+
+ /* Write Time Type. */
+ r = enc_uint64(a, type);
+ if (r < 0)
+ return (r);
+ /* Write EmptyStream Size. */
+ r = enc_uint64(a, 2 + ((zip->total_number_entry + 7) >> 3)
+ + zip->total_number_time_defined[ti] * 8);
+ if (r < 0)
+ return (r);
+
+ /* All are not defined. */
+ r = enc_uint64(a, 0);
+ if (r < 0)
+ return (r);
+
+ byte = 0;
+ mask = 0x80;
+ file = zip->file_list.first;
+ for (;file != NULL; file = file->next) {
+ if (file->flg & flg)
+ byte |= mask;
+ mask >>= 1;
+ if (mask == 0) {
+ r = compress_out(a, &byte, 1, ARCHIVE_Z_RUN);
+ if (r < 0)
+ return (r);
+ mask = 0x80;
+ byte = 0;
+ }
+ }
+ if (mask != 0x80) {
+ r = compress_out(a, &byte, 1, ARCHIVE_Z_RUN);
+ if (r < 0)
+ return (r);
+ }
+ }
+
+ /* External. */
+ r = enc_uint64(a, 0);
+ if (r < 0)
+ return (r);
+
+
+ /*
+ * Make Times.
+ */
+ file = zip->file_list.first;
+ for (;file != NULL; file = file->next) {
+ if ((file->flg & flg) == 0)
+ continue;
+ archive_le64enc(filetime, utcToFiletime(file->times[ti].time,
+ file->times[ti].time_ns));
+ r = compress_out(a, filetime, 8, ARCHIVE_Z_RUN);
+ if (r < 0)
+ return (r);
+ }
+
+ return (ARCHIVE_OK);
+}
+
+static int
+make_header(struct archive_write *a, uint64_t offset, uint64_t pack_size,
+ uint64_t unpack_size, int codernum, struct coder *coders)
+{
+ struct _7zip *zip = (struct _7zip *)a->format_data;
+ struct file *file;
+ int r;
+ uint8_t mask, byte;
+
+ /*
+ * Make FilesInfo.
+ */
+ r = enc_uint64(a, kHeader);
+ if (r < 0)
+ return (r);
+
+ /*
+ * If there are empty files only, do not write MainStreamInfo.
+ */
+ if (zip->total_number_nonempty_entry) {
+ /*
+ * Make MainStreamInfo.
+ */
+ r = enc_uint64(a, kMainStreamsInfo);
+ if (r < 0)
+ return (r);
+ r = make_streamsInfo(a, offset, pack_size, unpack_size,
+ codernum, coders, 1, 0);
+ if (r < 0)
+ return (r);
+ }
+
+ /*
+ * Make FilesInfo.
+ */
+ r = enc_uint64(a, kFilesInfo);
+ if (r < 0)
+ return (r);
+
+ /* Write numFiles. */
+ r = enc_uint64(a, zip->total_number_entry);
+ if (r < 0)
+ return (r);
+
+ if (zip->total_number_empty_entry > 0) {
+ /* Make EmptyStream. */
+ r = enc_uint64(a, kEmptyStream);
+ if (r < 0)
+ return (r);
+
+ /* Write EmptyStream Size. */
+ r = enc_uint64(a, (zip->total_number_entry+7)>>3);
+ if (r < 0)
+ return (r);
+
+ byte = 0;
+ mask = 0x80;
+ file = zip->file_list.first;
+ for (;file != NULL; file = file->next) {
+ if (file->size == 0)
+ byte |= mask;
+ mask >>= 1;
+ if (mask == 0) {
+ r = compress_out(a, &byte, 1, ARCHIVE_Z_RUN);
+ if (r < 0)
+ return (r);
+ mask = 0x80;
+ byte = 0;
+ }
+ }
+ if (mask != 0x80) {
+ r = compress_out(a, &byte, 1, ARCHIVE_Z_RUN);
+ if (r < 0)
+ return (r);
+ }
+ }
+
+ if (zip->total_number_empty_entry > zip->total_number_dir_entry) {
+ /* Make EmptyFile. */
+ r = enc_uint64(a, kEmptyFile);
+ if (r < 0)
+ return (r);
+
+ /* Write EmptyFile Size. */
+ r = enc_uint64(a, (zip->total_number_empty_entry + 7) >> 3);
+ if (r < 0)
+ return (r);
+
+ byte = 0;
+ mask = 0x80;
+ file = zip->file_list.first;
+ for (;file != NULL; file = file->next) {
+ if (file->size)
+ continue;
+ if (!file->dir)
+ byte |= mask;
+ mask >>= 1;
+ if (mask == 0) {
+ r = compress_out(a, &byte, 1, ARCHIVE_Z_RUN);
+ if (r < 0)
+ return (r);
+ mask = 0x80;
+ byte = 0;
+ }
+ }
+ if (mask != 0x80) {
+ r = compress_out(a, &byte, 1, ARCHIVE_Z_RUN);
+ if (r < 0)
+ return (r);
+ }
+ }
+
+ /* Make Name. */
+ r = enc_uint64(a, kName);
+ if (r < 0)
+ return (r);
+
+ /* Write Nume size. */
+ r = enc_uint64(a, zip->total_bytes_entry_name+1);
+ if (r < 0)
+ return (r);
+
+ /* Write dmy byte. */
+ r = enc_uint64(a, 0);
+ if (r < 0)
+ return (r);
+
+ file = zip->file_list.first;
+ for (;file != NULL; file = file->next) {
+ r = compress_out(a, file->utf16name, file->name_len+2,
+ ARCHIVE_Z_RUN);
+ if (r < 0)
+ return (r);
+ }
+
+ /* Make MTime. */
+ r = make_time(a, kMTime, MTIME_IS_SET, MTIME);
+ if (r < 0)
+ return (r);
+
+ /* Make CTime. */
+ r = make_time(a, kCTime, CTIME_IS_SET, CTIME);
+ if (r < 0)
+ return (r);
+
+ /* Make ATime. */
+ r = make_time(a, kATime, ATIME_IS_SET, ATIME);
+ if (r < 0)
+ return (r);
+
+ /* Make Attributes. */
+ r = enc_uint64(a, kAttributes);
+ if (r < 0)
+ return (r);
+
+ /* Write Attributes size. */
+ r = enc_uint64(a, 2 + zip->total_number_entry * 4);
+ if (r < 0)
+ return (r);
+
+ /* Write "All Are Defined". */
+ r = enc_uint64(a, 1);
+ if (r < 0)
+ return (r);
+
+ /* Write dmy byte. */
+ r = enc_uint64(a, 0);
+ if (r < 0)
+ return (r);
+
+ file = zip->file_list.first;
+ for (;file != NULL; file = file->next) {
+ /*
+ * High 16bits is unix mode.
+ * Low 16bits is Windows attributes.
+ */
+ uint32_t encattr, attr;
+ if (file->dir)
+ attr = 0x8010;
+ else
+ attr = 0x8020;
+ if ((file->mode & 0222) == 0)
+ attr |= 1;/* Read Only. */
+ attr |= ((uint32_t)file->mode) << 16;
+ archive_le32enc(&encattr, attr);
+ r = compress_out(a, &encattr, 4, ARCHIVE_Z_RUN);
+ if (r < 0)
+ return (r);
+ }
+
+ /* Write End. */
+ r = enc_uint64(a, kEnd);
+ if (r < 0)
+ return (r);
+
+ /* Write End. */
+ r = enc_uint64(a, kEnd);
+ if (r < 0)
+ return (r);
+
+ return (ARCHIVE_OK);
+}
+
+
+static int
+_7z_free(struct archive_write *a)
+{
+ struct _7zip *zip = (struct _7zip *)a->format_data;
+
+ file_free_register(zip);
+ compression_end(&(a->archive), &(zip->stream));
+ free(zip->coder.props);
+ free(zip);
+
+ return (ARCHIVE_OK);
+}
+
+static int
+file_cmp_node(const struct archive_rb_node *n1,
+ const struct archive_rb_node *n2)
+{
+ struct file *f1 = (struct file *)n1;
+ struct file *f2 = (struct file *)n2;
+
+ if (f1->name_len == f2->name_len)
+ return (memcmp(f1->utf16name, f2->utf16name, f1->name_len));
+ return (f1->name_len > f2->name_len)?1:-1;
+}
+
+static int
+file_cmp_key(const struct archive_rb_node *n, const void *key)
+{
+ struct file *f = (struct file *)n;
+
+ return (f->name_len - *(const char *)key);
+}
+
+static int
+file_new(struct archive_write *a, struct archive_entry *entry,
+ struct file **newfile)
+{
+ struct _7zip *zip;
+ struct file *file;
+ const char *u16;
+ size_t u16len;
+ int ret = ARCHIVE_OK;
+
+ zip = (struct _7zip *)a->format_data;
+ *newfile = NULL;
+
+ file = calloc(1, sizeof(*file));
+ if (file == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+
+ if (0 > archive_entry_pathname_l(entry, &u16, &u16len, zip->sconv)) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for UTF-16LE");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "A filename cannot be converted to UTF-16LE;"
+ "You should disable making Joliet extension");
+ ret = ARCHIVE_WARN;
+ }
+ file->utf16name = malloc(u16len + 2);
+ if (file->utf16name == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Name");
+ return (ARCHIVE_FATAL);
+ }
+ memcpy(file->utf16name, u16, u16len);
+ file->utf16name[u16len+0] = 0;
+ file->utf16name[u16len+1] = 0;
+ file->name_len = u16len;
+ file->mode = archive_entry_mode(entry);
+ if (archive_entry_filetype(entry) == AE_IFREG)
+ file->size = archive_entry_size(entry);
+ else
+ archive_entry_set_size(entry, 0);
+ if (archive_entry_filetype(entry) == AE_IFDIR)
+ file->dir = 1;
+ else if (archive_entry_filetype(entry) == AE_IFLNK)
+ file->size = strlen(archive_entry_symlink(entry));
+ if (archive_entry_mtime_is_set(entry)) {
+ file->flg |= MTIME_IS_SET;
+ file->times[MTIME].time = archive_entry_mtime(entry);
+ file->times[MTIME].time_ns = archive_entry_mtime_nsec(entry);
+ }
+ if (archive_entry_atime_is_set(entry)) {
+ file->flg |= ATIME_IS_SET;
+ file->times[ATIME].time = archive_entry_atime(entry);
+ file->times[ATIME].time_ns = archive_entry_atime_nsec(entry);
+ }
+ if (archive_entry_ctime_is_set(entry)) {
+ file->flg |= CTIME_IS_SET;
+ file->times[CTIME].time = archive_entry_ctime(entry);
+ file->times[CTIME].time_ns = archive_entry_ctime_nsec(entry);
+ }
+
+ *newfile = file;
+ return (ret);
+}
+
+static void
+file_free(struct file *file)
+{
+ free(file->utf16name);
+ free(file);
+}
+
+static void
+file_register(struct _7zip *zip, struct file *file)
+{
+ file->next = NULL;
+ *zip->file_list.last = file;
+ zip->file_list.last = &(file->next);
+}
+
+static void
+file_init_register(struct _7zip *zip)
+{
+ zip->file_list.first = NULL;
+ zip->file_list.last = &(zip->file_list.first);
+}
+
+static void
+file_free_register(struct _7zip *zip)
+{
+ struct file *file, *file_next;
+
+ file = zip->file_list.first;
+ while (file != NULL) {
+ file_next = file->next;
+ file_free(file);
+ file = file_next;
+ }
+}
+
+static void
+file_register_empty(struct _7zip *zip, struct file *file)
+{
+ file->next = NULL;
+ *zip->empty_list.last = file;
+ zip->empty_list.last = &(file->next);
+}
+
+static void
+file_init_register_empty(struct _7zip *zip)
+{
+ zip->empty_list.first = NULL;
+ zip->empty_list.last = &(zip->empty_list.first);
+}
+
+#if !defined(HAVE_BZLIB_H) || !defined(BZ_CONFIG_ERROR) || !defined(HAVE_LZMA_H)
+static int
+compression_unsupported_encoder(struct archive *a,
+ struct la_zstream *lastrm, const char *name)
+{
+
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "%s compression not supported on this platform", name);
+ lastrm->valid = 0;
+ lastrm->real_stream = NULL;
+ return (ARCHIVE_FAILED);
+}
+#endif
+
+/*
+ * _7_COPY compressor.
+ */
+static int
+compression_init_encoder_copy(struct archive *a, struct la_zstream *lastrm)
+{
+
+ if (lastrm->valid)
+ compression_end(a, lastrm);
+ lastrm->valid = 1;
+ lastrm->code = compression_code_copy;
+ lastrm->end = compression_end_copy;
+ return (ARCHIVE_OK);
+}
+
+static int
+compression_code_copy(struct archive *a,
+ struct la_zstream *lastrm, enum la_zaction action)
+{
+ size_t bytes;
+
+ (void)a; /* UNUSED */
+ if (lastrm->avail_out > lastrm->avail_in)
+ bytes = lastrm->avail_in;
+ else
+ bytes = lastrm->avail_out;
+ if (bytes) {
+ memcpy(lastrm->next_out, lastrm->next_in, bytes);
+ lastrm->next_in += bytes;
+ lastrm->avail_in -= bytes;
+ lastrm->total_in += bytes;
+ lastrm->next_out += bytes;
+ lastrm->avail_out -= bytes;
+ lastrm->total_out += bytes;
+ }
+ if (action == ARCHIVE_Z_FINISH && lastrm->avail_in == 0)
+ return (ARCHIVE_EOF);
+ return (ARCHIVE_OK);
+}
+
+static int
+compression_end_copy(struct archive *a, struct la_zstream *lastrm)
+{
+ (void)a; /* UNUSED */
+ lastrm->valid = 0;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * _7_DEFLATE compressor.
+ */
+#ifdef HAVE_ZLIB_H
+static int
+compression_init_encoder_deflate(struct archive *a,
+ struct la_zstream *lastrm, int level, int withheader)
+{
+ z_stream *strm;
+
+ if (lastrm->valid)
+ compression_end(a, lastrm);
+ strm = calloc(1, sizeof(*strm));
+ if (strm == NULL) {
+ archive_set_error(a, ENOMEM,
+ "Can't allocate memory for gzip stream");
+ return (ARCHIVE_FATAL);
+ }
+ /* zlib.h is not const-correct, so we need this one bit
+ * of ugly hackery to convert a const * pointer to
+ * a non-const pointer. */
+ strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
+ strm->avail_in = lastrm->avail_in;
+ strm->total_in = lastrm->total_in;
+ strm->next_out = lastrm->next_out;
+ strm->avail_out = lastrm->avail_out;
+ strm->total_out = lastrm->total_out;
+ if (deflateInit2(strm, level, Z_DEFLATED,
+ (withheader)?15:-15,
+ 8, Z_DEFAULT_STRATEGY) != Z_OK) {
+ free(strm);
+ lastrm->real_stream = NULL;
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Internal error initializing compression library");
+ return (ARCHIVE_FATAL);
+ }
+ lastrm->real_stream = strm;
+ lastrm->valid = 1;
+ lastrm->code = compression_code_deflate;
+ lastrm->end = compression_end_deflate;
+ return (ARCHIVE_OK);
+}
+
+static int
+compression_code_deflate(struct archive *a,
+ struct la_zstream *lastrm, enum la_zaction action)
+{
+ z_stream *strm;
+ int r;
+
+ strm = (z_stream *)lastrm->real_stream;
+ /* zlib.h is not const-correct, so we need this one bit
+ * of ugly hackery to convert a const * pointer to
+ * a non-const pointer. */
+ strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
+ strm->avail_in = lastrm->avail_in;
+ strm->total_in = lastrm->total_in;
+ strm->next_out = lastrm->next_out;
+ strm->avail_out = lastrm->avail_out;
+ strm->total_out = lastrm->total_out;
+ r = deflate(strm,
+ (action == ARCHIVE_Z_FINISH)? Z_FINISH: Z_NO_FLUSH);
+ lastrm->next_in = strm->next_in;
+ lastrm->avail_in = strm->avail_in;
+ lastrm->total_in = strm->total_in;
+ lastrm->next_out = strm->next_out;
+ lastrm->avail_out = strm->avail_out;
+ lastrm->total_out = strm->total_out;
+ switch (r) {
+ case Z_OK:
+ return (ARCHIVE_OK);
+ case Z_STREAM_END:
+ return (ARCHIVE_EOF);
+ default:
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "GZip compression failed:"
+ " deflate() call returned status %d", r);
+ return (ARCHIVE_FATAL);
+ }
+}
+
+static int
+compression_end_deflate(struct archive *a, struct la_zstream *lastrm)
+{
+ z_stream *strm;
+ int r;
+
+ strm = (z_stream *)lastrm->real_stream;
+ r = deflateEnd(strm);
+ free(strm);
+ lastrm->real_stream = NULL;
+ lastrm->valid = 0;
+ if (r != Z_OK) {
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Failed to clean up compressor");
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_OK);
+}
+#else
+static int
+compression_init_encoder_deflate(struct archive *a,
+ struct la_zstream *lastrm, int level, int withheader)
+{
+
+ (void) level; /* UNUSED */
+ (void) withheader; /* UNUSED */
+ if (lastrm->valid)
+ compression_end(a, lastrm);
+ return (compression_unsupported_encoder(a, lastrm, "deflate"));
+}
+#endif
+
+/*
+ * _7_BZIP2 compressor.
+ */
+#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
+static int
+compression_init_encoder_bzip2(struct archive *a,
+ struct la_zstream *lastrm, int level)
+{
+ bz_stream *strm;
+
+ if (lastrm->valid)
+ compression_end(a, lastrm);
+ strm = calloc(1, sizeof(*strm));
+ if (strm == NULL) {
+ archive_set_error(a, ENOMEM,
+ "Can't allocate memory for bzip2 stream");
+ return (ARCHIVE_FATAL);
+ }
+ /* bzlib.h is not const-correct, so we need this one bit
+ * of ugly hackery to convert a const * pointer to
+ * a non-const pointer. */
+ strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
+ strm->avail_in = lastrm->avail_in;
+ strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
+ strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
+ strm->next_out = (char *)lastrm->next_out;
+ strm->avail_out = lastrm->avail_out;
+ strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
+ strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
+ if (BZ2_bzCompressInit(strm, level, 0, 30) != BZ_OK) {
+ free(strm);
+ lastrm->real_stream = NULL;
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Internal error initializing compression library");
+ return (ARCHIVE_FATAL);
+ }
+ lastrm->real_stream = strm;
+ lastrm->valid = 1;
+ lastrm->code = compression_code_bzip2;
+ lastrm->end = compression_end_bzip2;
+ return (ARCHIVE_OK);
+}
+
+static int
+compression_code_bzip2(struct archive *a,
+ struct la_zstream *lastrm, enum la_zaction action)
+{
+ bz_stream *strm;
+ int r;
+
+ strm = (bz_stream *)lastrm->real_stream;
+ /* bzlib.h is not const-correct, so we need this one bit
+ * of ugly hackery to convert a const * pointer to
+ * a non-const pointer. */
+ strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
+ strm->avail_in = lastrm->avail_in;
+ strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
+ strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
+ strm->next_out = (char *)lastrm->next_out;
+ strm->avail_out = lastrm->avail_out;
+ strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
+ strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
+ r = BZ2_bzCompress(strm,
+ (action == ARCHIVE_Z_FINISH)? BZ_FINISH: BZ_RUN);
+ lastrm->next_in = (const unsigned char *)strm->next_in;
+ lastrm->avail_in = strm->avail_in;
+ lastrm->total_in =
+ (((uint64_t)(uint32_t)strm->total_in_hi32) << 32)
+ + (uint64_t)(uint32_t)strm->total_in_lo32;
+ lastrm->next_out = (unsigned char *)strm->next_out;
+ lastrm->avail_out = strm->avail_out;
+ lastrm->total_out =
+ (((uint64_t)(uint32_t)strm->total_out_hi32) << 32)
+ + (uint64_t)(uint32_t)strm->total_out_lo32;
+ switch (r) {
+ case BZ_RUN_OK: /* Non-finishing */
+ case BZ_FINISH_OK: /* Finishing: There's more work to do */
+ return (ARCHIVE_OK);
+ case BZ_STREAM_END: /* Finishing: all done */
+ /* Only occurs in finishing case */
+ return (ARCHIVE_EOF);
+ default:
+ /* Any other return value indicates an error */
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Bzip2 compression failed:"
+ " BZ2_bzCompress() call returned status %d", r);
+ return (ARCHIVE_FATAL);
+ }
+}
+
+static int
+compression_end_bzip2(struct archive *a, struct la_zstream *lastrm)
+{
+ bz_stream *strm;
+ int r;
+
+ strm = (bz_stream *)lastrm->real_stream;
+ r = BZ2_bzCompressEnd(strm);
+ free(strm);
+ lastrm->real_stream = NULL;
+ lastrm->valid = 0;
+ if (r != BZ_OK) {
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Failed to clean up compressor");
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_OK);
+}
+
+#else
+static int
+compression_init_encoder_bzip2(struct archive *a,
+ struct la_zstream *lastrm, int level)
+{
+
+ (void) level; /* UNUSED */
+ if (lastrm->valid)
+ compression_end(a, lastrm);
+ return (compression_unsupported_encoder(a, lastrm, "bzip2"));
+}
+#endif
+
+/*
+ * _7_LZMA1, _7_LZMA2 compressor.
+ */
+#if defined(HAVE_LZMA_H)
+static int
+compression_init_encoder_lzma(struct archive *a,
+ struct la_zstream *lastrm, int level, uint64_t filter_id)
+{
+ static const lzma_stream lzma_init_data = LZMA_STREAM_INIT;
+ lzma_stream *strm;
+ lzma_filter *lzmafilters;
+ lzma_options_lzma lzma_opt;
+ int r;
+
+ if (lastrm->valid)
+ compression_end(a, lastrm);
+ strm = calloc(1, sizeof(*strm) + sizeof(*lzmafilters) * 2);
+ if (strm == NULL) {
+ archive_set_error(a, ENOMEM,
+ "Can't allocate memory for lzma stream");
+ return (ARCHIVE_FATAL);
+ }
+ lzmafilters = (lzma_filter *)(strm+1);
+ if (level > 6)
+ level = 6;
+ if (lzma_lzma_preset(&lzma_opt, level)) {
+ lastrm->real_stream = NULL;
+ archive_set_error(a, ENOMEM,
+ "Internal error initializing compression library");
+ return (ARCHIVE_FATAL);
+ }
+ lzmafilters[0].id = filter_id;
+ lzmafilters[0].options = &lzma_opt;
+ lzmafilters[1].id = LZMA_VLI_UNKNOWN;/* Terminate */
+
+ r = lzma_properties_size(&(lastrm->prop_size), lzmafilters);
+ if (r != LZMA_OK) {
+ free(strm);
+ lastrm->real_stream = NULL;
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "lzma_properties_size failed");
+ return (ARCHIVE_FATAL);
+ }
+ if (lastrm->prop_size) {
+ lastrm->props = malloc(lastrm->prop_size);
+ if (lastrm->props == NULL) {
+ free(strm);
+ lastrm->real_stream = NULL;
+ archive_set_error(a, ENOMEM,
+ "Cannot allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ r = lzma_properties_encode(lzmafilters, lastrm->props);
+ if (r != LZMA_OK) {
+ free(strm);
+ lastrm->real_stream = NULL;
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "lzma_properties_encode failed");
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ *strm = lzma_init_data;
+ r = lzma_raw_encoder(strm, lzmafilters);
+ switch (r) {
+ case LZMA_OK:
+ lastrm->real_stream = strm;
+ lastrm->valid = 1;
+ lastrm->code = compression_code_lzma;
+ lastrm->end = compression_end_lzma;
+ r = ARCHIVE_OK;
+ break;
+ case LZMA_MEM_ERROR:
+ free(strm);
+ lastrm->real_stream = NULL;
+ archive_set_error(a, ENOMEM,
+ "Internal error initializing compression library: "
+ "Cannot allocate memory");
+ r = ARCHIVE_FATAL;
+ break;
+ default:
+ free(strm);
+ lastrm->real_stream = NULL;
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Internal error initializing compression library: "
+ "It's a bug in liblzma");
+ r = ARCHIVE_FATAL;
+ break;
+ }
+ return (r);
+}
+
+static int
+compression_init_encoder_lzma1(struct archive *a,
+ struct la_zstream *lastrm, int level)
+{
+ return compression_init_encoder_lzma(a, lastrm, level,
+ LZMA_FILTER_LZMA1);
+}
+
+static int
+compression_init_encoder_lzma2(struct archive *a,
+ struct la_zstream *lastrm, int level)
+{
+ return compression_init_encoder_lzma(a, lastrm, level,
+ LZMA_FILTER_LZMA2);
+}
+
+static int
+compression_code_lzma(struct archive *a,
+ struct la_zstream *lastrm, enum la_zaction action)
+{
+ lzma_stream *strm;
+ int r;
+
+ strm = (lzma_stream *)lastrm->real_stream;
+ strm->next_in = lastrm->next_in;
+ strm->avail_in = lastrm->avail_in;
+ strm->total_in = lastrm->total_in;
+ strm->next_out = lastrm->next_out;
+ strm->avail_out = lastrm->avail_out;
+ strm->total_out = lastrm->total_out;
+ r = lzma_code(strm,
+ (action == ARCHIVE_Z_FINISH)? LZMA_FINISH: LZMA_RUN);
+ lastrm->next_in = strm->next_in;
+ lastrm->avail_in = strm->avail_in;
+ lastrm->total_in = strm->total_in;
+ lastrm->next_out = strm->next_out;
+ lastrm->avail_out = strm->avail_out;
+ lastrm->total_out = strm->total_out;
+ switch (r) {
+ case LZMA_OK:
+ /* Non-finishing case */
+ return (ARCHIVE_OK);
+ case LZMA_STREAM_END:
+ /* This return can only occur in finishing case. */
+ return (ARCHIVE_EOF);
+ case LZMA_MEMLIMIT_ERROR:
+ archive_set_error(a, ENOMEM,
+ "lzma compression error:"
+ " %ju MiB would have been needed",
+ (uintmax_t)((lzma_memusage(strm) + 1024 * 1024 -1)
+ / (1024 * 1024)));
+ return (ARCHIVE_FATAL);
+ default:
+ /* Any other return value indicates an error */
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "lzma compression failed:"
+ " lzma_code() call returned status %d", r);
+ return (ARCHIVE_FATAL);
+ }
+}
+
+static int
+compression_end_lzma(struct archive *a, struct la_zstream *lastrm)
+{
+ lzma_stream *strm;
+
+ (void)a; /* UNUSED */
+ strm = (lzma_stream *)lastrm->real_stream;
+ lzma_end(strm);
+ free(strm);
+ lastrm->valid = 0;
+ lastrm->real_stream = NULL;
+ return (ARCHIVE_OK);
+}
+#else
+static int
+compression_init_encoder_lzma1(struct archive *a,
+ struct la_zstream *lastrm, int level)
+{
+
+ (void) level; /* UNUSED */
+ if (lastrm->valid)
+ compression_end(a, lastrm);
+ return (compression_unsupported_encoder(a, lastrm, "lzma"));
+}
+static int
+compression_init_encoder_lzma2(struct archive *a,
+ struct la_zstream *lastrm, int level)
+{
+
+ (void) level; /* UNUSED */
+ if (lastrm->valid)
+ compression_end(a, lastrm);
+ return (compression_unsupported_encoder(a, lastrm, "lzma"));
+}
+#endif
+
+/*
+ * _7_PPMD compressor.
+ */
+static void *
+ppmd_alloc(void *p, size_t size)
+{
+ (void)p;
+ return malloc(size);
+}
+static void
+ppmd_free(void *p, void *address)
+{
+ (void)p;
+ free(address);
+}
+static ISzAlloc g_szalloc = { ppmd_alloc, ppmd_free };
+static void
+ppmd_write(void *p, Byte b)
+{
+ struct archive_write *a = ((IByteOut *)p)->a;
+ struct _7zip *zip = (struct _7zip *)(a->format_data);
+ struct la_zstream *lastrm = &(zip->stream);
+ struct ppmd_stream *strm;
+
+ if (lastrm->avail_out) {
+ *lastrm->next_out++ = b;
+ lastrm->avail_out--;
+ lastrm->total_out++;
+ return;
+ }
+ strm = (struct ppmd_stream *)lastrm->real_stream;
+ if (strm->buff_ptr < strm->buff_end) {
+ *strm->buff_ptr++ = b;
+ strm->buff_bytes++;
+ }
+}
+
+static int
+compression_init_encoder_ppmd(struct archive *a,
+ struct la_zstream *lastrm, unsigned maxOrder, uint32_t msize)
+{
+ struct ppmd_stream *strm;
+ uint8_t *props;
+ int r;
+
+ if (lastrm->valid)
+ compression_end(a, lastrm);
+ strm = calloc(1, sizeof(*strm));
+ if (strm == NULL) {
+ archive_set_error(a, ENOMEM,
+ "Can't allocate memory for PPMd");
+ return (ARCHIVE_FATAL);
+ }
+ strm->buff = malloc(32);
+ if (strm->buff == NULL) {
+ free(strm);
+ archive_set_error(a, ENOMEM,
+ "Can't allocate memory for PPMd");
+ return (ARCHIVE_FATAL);
+ }
+ strm->buff_ptr = strm->buff;
+ strm->buff_end = strm->buff + 32;
+
+ props = malloc(1+4);
+ if (props == NULL) {
+ free(strm->buff);
+ free(strm);
+ archive_set_error(a, ENOMEM,
+ "Coludn't allocate memory for PPMd");
+ return (ARCHIVE_FATAL);
+ }
+ props[0] = maxOrder;
+ archive_le32enc(props+1, msize);
+ __archive_ppmd7_functions.Ppmd7_Construct(&strm->ppmd7_context);
+ r = __archive_ppmd7_functions.Ppmd7_Alloc(
+ &strm->ppmd7_context, msize, &g_szalloc);
+ if (r == 0) {
+ free(strm->buff);
+ free(strm);
+ free(props);
+ archive_set_error(a, ENOMEM,
+ "Coludn't allocate memory for PPMd");
+ return (ARCHIVE_FATAL);
+ }
+ __archive_ppmd7_functions.Ppmd7_Init(&(strm->ppmd7_context), maxOrder);
+ strm->byteout.a = (struct archive_write *)a;
+ strm->byteout.Write = ppmd_write;
+ strm->range_enc.Stream = &(strm->byteout);
+ __archive_ppmd7_functions.Ppmd7z_RangeEnc_Init(&(strm->range_enc));
+ strm->stat = 0;
+
+ lastrm->real_stream = strm;
+ lastrm->valid = 1;
+ lastrm->code = compression_code_ppmd;
+ lastrm->end = compression_end_ppmd;
+ lastrm->prop_size = 5;
+ lastrm->props = props;
+ return (ARCHIVE_OK);
+}
+
+static int
+compression_code_ppmd(struct archive *a,
+ struct la_zstream *lastrm, enum la_zaction action)
+{
+ struct ppmd_stream *strm;
+
+ strm = (struct ppmd_stream *)lastrm->real_stream;
+
+ /* Copy encoded data if there are remaining bytes from previous call. */
+ if (strm->buff_bytes) {
+ uint8_t *p = strm->buff_ptr - strm->buff_bytes;
+ while (lastrm->avail_out && strm->buff_bytes) {
+ *lastrm->next_out++ = *p++;
+ lastrm->avail_out--;
+ lastrm->total_out++;
+ strm->buff_bytes--;
+ }
+ if (strm->buff_bytes)
+ return (ARCHIVE_OK);
+ if (strm->stat == 1)
+ return (ARCHIVE_EOF);
+ strm->buff_ptr = strm->buff;
+ }
+ while (lastrm->avail_in && lastrm->avail_out) {
+ __archive_ppmd7_functions.Ppmd7_EncodeSymbol(
+ &(strm->ppmd7_context), &(strm->range_enc),
+ *lastrm->next_in++);
+ lastrm->avail_in--;
+ lastrm->total_in++;
+ }
+ if (lastrm->avail_in == 0 && action == ARCHIVE_Z_FINISH) {
+ __archive_ppmd7_functions.Ppmd7z_RangeEnc_FlushData(
+ &(strm->range_enc));
+ strm->stat = 1;
+ /* Return EOF if there are no remaining bytes. */
+ if (strm->buff_bytes == 0)
+ return (ARCHIVE_EOF);
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+compression_end_ppmd(struct archive *a, struct la_zstream *lastrm)
+{
+ struct ppmd_stream *strm;
+
+ strm = (struct ppmd_stream *)lastrm->real_stream;
+ __archive_ppmd7_functions.Ppmd7_Free(&strm->ppmd7_context, &g_szalloc);
+ free(strm->buff);
+ free(strm);
+ lastrm->real_stream = NULL;
+ lastrm->valid = 0;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Universal compressor initializer.
+ */
+static int
+_7z_compression_init_encoder(struct archive_write *a, unsigned compression,
+ int compression_level)
+{
+ struct _7zip *zip;
+ int r;
+
+ zip = (struct _7zip *)a->format_data;
+ switch (compression) {
+ case _7Z_DEFLATE:
+ r = compression_init_encoder_deflate(
+ &(a->archive), &(zip->stream),
+ compression_level, 0);
+ break;
+ case _7Z_BZIP2:
+ r = compression_init_encoder_bzip2(
+ &(a->archive), &(zip->stream),
+ compression_level);
+ break;
+ case _7Z_LZMA1:
+ r = compression_init_encoder_lzma1(
+ &(a->archive), &(zip->stream),
+ compression_level);
+ break;
+ case _7Z_LZMA2:
+ r = compression_init_encoder_lzma2(
+ &(a->archive), &(zip->stream),
+ compression_level);
+ break;
+ case _7Z_PPMD:
+ r = compression_init_encoder_ppmd(
+ &(a->archive), &(zip->stream),
+ PPMD7_DEFAULT_ORDER, PPMD7_DEFAULT_MEM_SIZE);
+ break;
+ case _7Z_COPY:
+ default:
+ r = compression_init_encoder_copy(
+ &(a->archive), &(zip->stream));
+ break;
+ }
+ if (r == ARCHIVE_OK) {
+ zip->stream.total_in = 0;
+ zip->stream.next_out = zip->wbuff;
+ zip->stream.avail_out = sizeof(zip->wbuff);
+ zip->stream.total_out = 0;
+ }
+
+ return (r);
+}
+
+static int
+compression_code(struct archive *a, struct la_zstream *lastrm,
+ enum la_zaction action)
+{
+ if (lastrm->valid)
+ return (lastrm->code(a, lastrm, action));
+ return (ARCHIVE_OK);
+}
+
+static int
+compression_end(struct archive *a, struct la_zstream *lastrm)
+{
+ if (lastrm->valid) {
+ lastrm->prop_size = 0;
+ free(lastrm->props);
+ lastrm->props = NULL;
+ return (lastrm->end(a, lastrm));
+ }
+ return (ARCHIVE_OK);
+}
+
+
diff --git a/libarchive/archive_write_set_format_ar.c b/libarchive/archive_write_set_format_ar.c
index 2180fc9b7b89..956b93228513 100644
--- a/libarchive/archive_write_set_format_ar.c
+++ b/libarchive/archive_write_set_format_ar.c
@@ -48,6 +48,7 @@ struct ar_w {
uint64_t entry_padding;
int is_strtab;
int has_strtab;
+ char wrote_global_header;
char *strtab;
};
@@ -74,8 +75,8 @@ static int archive_write_ar_header(struct archive_write *,
struct archive_entry *);
static ssize_t archive_write_ar_data(struct archive_write *,
const void *buff, size_t s);
-static int archive_write_ar_destroy(struct archive_write *);
-static int archive_write_ar_finish(struct archive_write *);
+static int archive_write_ar_free(struct archive_write *);
+static int archive_write_ar_close(struct archive_write *);
static int archive_write_ar_finish_entry(struct archive_write *);
static const char *ar_basename(const char *path);
static int format_octal(int64_t v, char *p, int s);
@@ -85,7 +86,11 @@ int
archive_write_set_format_ar_bsd(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
- int r = archive_write_set_format_ar(a);
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_ar_bsd");
+ r = archive_write_set_format_ar(a);
if (r == ARCHIVE_OK) {
a->archive.archive_format = ARCHIVE_FORMAT_AR_BSD;
a->archive.archive_format_name = "ar (BSD)";
@@ -97,7 +102,11 @@ int
archive_write_set_format_ar_svr4(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
- int r = archive_write_set_format_ar(a);
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_ar_svr4");
+ r = archive_write_set_format_ar(a);
if (r == ARCHIVE_OK) {
a->archive.archive_format = ARCHIVE_FORMAT_AR_GNU;
a->archive.archive_format_name = "ar (GNU/SVR4)";
@@ -114,8 +123,8 @@ archive_write_set_format_ar(struct archive_write *a)
struct ar_w *ar;
/* If someone else was already registered, unregister them. */
- if (a->format_destroy != NULL)
- (a->format_destroy)(a);
+ if (a->format_free != NULL)
+ (a->format_free)(a);
ar = (struct ar_w *)malloc(sizeof(*ar));
if (ar == NULL) {
@@ -128,8 +137,8 @@ archive_write_set_format_ar(struct archive_write *a)
a->format_name = "ar";
a->format_write_header = archive_write_ar_header;
a->format_write_data = archive_write_ar_data;
- a->format_finish = archive_write_ar_finish;
- a->format_destroy = archive_write_ar_destroy;
+ a->format_close = archive_write_ar_close;
+ a->format_free = archive_write_ar_free;
a->format_finish_entry = archive_write_ar_finish_entry;
return (ARCHIVE_OK);
}
@@ -166,8 +175,10 @@ archive_write_ar_header(struct archive_write *a, struct archive_entry *entry)
* If we are now at the beginning of the archive,
* we need first write the ar global header.
*/
- if (a->archive.file_position == 0)
- (a->compressor.write)(a, "!<arch>\n", 8);
+ if (!ar->wrote_global_header) {
+ __archive_write_output(a, "!<arch>\n", 8);
+ ar->wrote_global_header = 1;
+ }
memset(buff, ' ', 60);
strncpy(&buff[AR_fmag_offset], "`\n", 2);
@@ -190,7 +201,7 @@ archive_write_ar_header(struct archive_write *a, struct archive_entry *entry)
ar->is_strtab = 1;
buff[AR_name_offset] = buff[AR_name_offset + 1] = '/';
/*
- * For archive string table, only ar_size filed should
+ * For archive string table, only ar_size field should
* be set.
*/
goto size;
@@ -330,7 +341,7 @@ size:
return (ARCHIVE_WARN);
}
- ret = (a->compressor.write)(a, buff, 60);
+ ret = __archive_write_output(a, buff, 60);
if (ret != ARCHIVE_OK)
return (ret);
@@ -338,7 +349,7 @@ size:
ar->entry_padding = ar->entry_bytes_remaining % 2;
if (append_fn > 0) {
- ret = (a->compressor.write)(a, filename, strlen(filename));
+ ret = __archive_write_output(a, filename, strlen(filename));
if (ret != ARCHIVE_OK)
return (ret);
ar->entry_bytes_remaining -= strlen(filename);
@@ -374,7 +385,7 @@ archive_write_ar_data(struct archive_write *a, const void *buff, size_t s)
ar->has_strtab = 1;
}
- ret = (a->compressor.write)(a, buff, s);
+ ret = __archive_write_output(a, buff, s);
if (ret != ARCHIVE_OK)
return (ret);
@@ -383,7 +394,7 @@ archive_write_ar_data(struct archive_write *a, const void *buff, size_t s)
}
static int
-archive_write_ar_destroy(struct archive_write *a)
+archive_write_ar_free(struct archive_write *a)
{
struct ar_w *ar;
@@ -403,16 +414,19 @@ archive_write_ar_destroy(struct archive_write *a)
}
static int
-archive_write_ar_finish(struct archive_write *a)
+archive_write_ar_close(struct archive_write *a)
{
+ struct ar_w *ar;
int ret;
/*
* If we haven't written anything yet, we need to write
* the ar global header now to make it a valid ar archive.
*/
- if (a->archive.file_position == 0) {
- ret = (a->compressor.write)(a, "!<arch>\n", 8);
+ ar = (struct ar_w *)a->format_data;
+ if (!ar->wrote_global_header) {
+ ar->wrote_global_header = 1;
+ ret = __archive_write_output(a, "!<arch>\n", 8);
return (ret);
}
@@ -439,12 +453,12 @@ archive_write_ar_finish_entry(struct archive_write *a)
if (ar->entry_padding != 1) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Padding wrong size: %d should be 1 or 0",
- (int)ar->entry_padding);
+ "Padding wrong size: %ju should be 1 or 0",
+ (uintmax_t)ar->entry_padding);
return (ARCHIVE_WARN);
}
- ret = (a->compressor.write)(a, "\n", 1);
+ ret = __archive_write_output(a, "\n", 1);
return (ret);
}
@@ -501,7 +515,7 @@ format_decimal(int64_t v, char *p, int s)
len = s;
h = p;
- /* Negative values in ar header are meaningless , so use 0. */
+ /* Negative values in ar header are meaningless, so use 0. */
if (v < 0) {
while (len-- > 0)
*p++ = '0';
diff --git a/libarchive/archive_write_set_format_by_name.c b/libarchive/archive_write_set_format_by_name.c
index a0921199c223..9671f60f8cd1 100644
--- a/libarchive/archive_write_set_format_by_name.c
+++ b/libarchive/archive_write_set_format_by_name.c
@@ -44,19 +44,28 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_by_name.c 20116
static
struct { const char *name; int (*setter)(struct archive *); } names[] =
{
+ { "7zip", archive_write_set_format_7zip },
{ "ar", archive_write_set_format_ar_bsd },
{ "arbsd", archive_write_set_format_ar_bsd },
{ "argnu", archive_write_set_format_ar_svr4 },
{ "arsvr4", archive_write_set_format_ar_svr4 },
+ { "bsdtar", archive_write_set_format_pax_restricted },
+ { "cd9660", archive_write_set_format_iso9660 },
{ "cpio", archive_write_set_format_cpio },
+ { "gnutar", archive_write_set_format_gnutar },
+ { "iso", archive_write_set_format_iso9660 },
+ { "iso9660", archive_write_set_format_iso9660 },
{ "mtree", archive_write_set_format_mtree },
{ "newc", archive_write_set_format_cpio_newc },
{ "odc", archive_write_set_format_cpio },
{ "pax", archive_write_set_format_pax },
+ { "paxr", archive_write_set_format_pax_restricted },
{ "posix", archive_write_set_format_pax },
+ { "rpax", archive_write_set_format_pax_restricted },
{ "shar", archive_write_set_format_shar },
{ "shardump", archive_write_set_format_shar_dump },
{ "ustar", archive_write_set_format_ustar },
+ { "xar", archive_write_set_format_xar },
{ "zip", archive_write_set_format_zip },
{ NULL, NULL }
};
@@ -72,5 +81,6 @@ archive_write_set_format_by_name(struct archive *a, const char *name)
}
archive_set_error(a, EINVAL, "No such format '%s'", name);
+ a->state = ARCHIVE_STATE_FATAL;
return (ARCHIVE_FATAL);
}
diff --git a/libarchive/archive_write_set_format_cpio.c b/libarchive/archive_write_set_format_cpio.c
index b64b1cb06e27..92b9bfb0b9ff 100644
--- a/libarchive/archive_write_set_format_cpio.c
+++ b/libarchive/archive_write_set_format_cpio.c
@@ -39,18 +39,22 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_cpio.c 201170 2
#include "archive.h"
#include "archive_entry.h"
+#include "archive_entry_locale.h"
#include "archive_private.h"
#include "archive_write_private.h"
static ssize_t archive_write_cpio_data(struct archive_write *,
const void *buff, size_t s);
-static int archive_write_cpio_finish(struct archive_write *);
-static int archive_write_cpio_destroy(struct archive_write *);
+static int archive_write_cpio_close(struct archive_write *);
+static int archive_write_cpio_free(struct archive_write *);
static int archive_write_cpio_finish_entry(struct archive_write *);
static int archive_write_cpio_header(struct archive_write *,
struct archive_entry *);
+static int archive_write_cpio_options(struct archive_write *,
+ const char *, const char *);
static int format_octal(int64_t, void *, int);
static int64_t format_octal_recursive(int64_t, char *, int);
+static int write_header(struct archive_write *, struct archive_entry *);
struct cpio {
uint64_t entry_bytes_remaining;
@@ -60,31 +64,34 @@ struct cpio {
struct { int64_t old; int new;} *ino_list;
size_t ino_list_size;
size_t ino_list_next;
-};
-#ifdef _MSC_VER
-#define __packed
-#pragma pack(push, 1)
-#endif
+ struct archive_string_conv *opt_sconv;
+ struct archive_string_conv *sconv_default;
+ int init_default_conversion;
+};
-struct cpio_header {
- char c_magic[6];
- char c_dev[6];
- char c_ino[6];
- char c_mode[6];
- char c_uid[6];
- char c_gid[6];
- char c_nlink[6];
- char c_rdev[6];
- char c_mtime[11];
- char c_namesize[6];
- char c_filesize[11];
-} __packed;
-
-#ifdef _MSC_VER
-#undef __packed
-#pragma pack(pop)
-#endif
+#define c_magic_offset 0
+#define c_magic_size 6
+#define c_dev_offset 6
+#define c_dev_size 6
+#define c_ino_offset 12
+#define c_ino_size 6
+#define c_mode_offset 18
+#define c_mode_size 6
+#define c_uid_offset 24
+#define c_uid_size 6
+#define c_gid_offset 30
+#define c_gid_size 6
+#define c_nlink_offset 36
+#define c_nlink_size 6
+#define c_rdev_offset 42
+#define c_rdev_size 6
+#define c_mtime_offset 48
+#define c_mtime_size 11
+#define c_namesize_offset 59
+#define c_namesize_size 6
+#define c_filesize_offset 65
+#define c_filesize_size 11
/*
* Set output format to 'cpio' format.
@@ -95,30 +102,58 @@ archive_write_set_format_cpio(struct archive *_a)
struct archive_write *a = (struct archive_write *)_a;
struct cpio *cpio;
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_cpio");
+
/* If someone else was already registered, unregister them. */
- if (a->format_destroy != NULL)
- (a->format_destroy)(a);
+ if (a->format_free != NULL)
+ (a->format_free)(a);
- cpio = (struct cpio *)malloc(sizeof(*cpio));
+ cpio = (struct cpio *)calloc(1, sizeof(*cpio));
if (cpio == NULL) {
archive_set_error(&a->archive, ENOMEM, "Can't allocate cpio data");
return (ARCHIVE_FATAL);
}
- memset(cpio, 0, sizeof(*cpio));
a->format_data = cpio;
-
- a->pad_uncompressed = 1;
a->format_name = "cpio";
+ a->format_options = archive_write_cpio_options;
a->format_write_header = archive_write_cpio_header;
a->format_write_data = archive_write_cpio_data;
a->format_finish_entry = archive_write_cpio_finish_entry;
- a->format_finish = archive_write_cpio_finish;
- a->format_destroy = archive_write_cpio_destroy;
+ a->format_close = archive_write_cpio_close;
+ a->format_free = archive_write_cpio_free;
a->archive.archive_format = ARCHIVE_FORMAT_CPIO_POSIX;
a->archive.archive_format_name = "POSIX cpio";
return (ARCHIVE_OK);
}
+static int
+archive_write_cpio_options(struct archive_write *a, const char *key,
+ const char *val)
+{
+ struct cpio *cpio = (struct cpio *)a->format_data;
+ int ret = ARCHIVE_FAILED;
+
+ if (strcmp(key, "hdrcharset") == 0) {
+ if (val == NULL || val[0] == 0)
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "%s: hdrcharset option needs a character-set name",
+ a->format_name);
+ else {
+ cpio->opt_sconv = archive_string_conversion_to_charset(
+ &a->archive, val, 0);
+ if (cpio->opt_sconv != NULL)
+ ret = ARCHIVE_OK;
+ else
+ ret = ARCHIVE_FATAL;
+ }
+ } else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "%s: unknown keyword ``%s''", a->format_name, key);
+
+ return (ret);
+}
+
/*
* Ino values are as long as 64 bits on some systems; cpio format
* only allows 18 bits and relies on the ino values to identify hardlinked
@@ -184,24 +219,90 @@ synthesize_ino_value(struct cpio *cpio, struct archive_entry *entry)
return (ino_new);
}
+
+static struct archive_string_conv *
+get_sconv(struct archive_write *a)
+{
+ struct cpio *cpio;
+ struct archive_string_conv *sconv;
+
+ cpio = (struct cpio *)a->format_data;
+ sconv = cpio->opt_sconv;
+ if (sconv == NULL) {
+ if (!cpio->init_default_conversion) {
+ cpio->sconv_default =
+ archive_string_default_conversion_for_write(
+ &(a->archive));
+ cpio->init_default_conversion = 1;
+ }
+ sconv = cpio->sconv_default;
+ }
+ return (sconv);
+}
+
static int
archive_write_cpio_header(struct archive_write *a, struct archive_entry *entry)
{
+ const char *path;
+ size_t len;
+
+ if (archive_entry_filetype(entry) == 0) {
+ archive_set_error(&a->archive, -1, "Filetype required");
+ return (ARCHIVE_FAILED);
+ }
+
+ if (archive_entry_pathname_l(entry, &path, &len, get_sconv(a)) != 0
+ && errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathname");
+ return (ARCHIVE_FATAL);
+ }
+ if (len == 0 || path == NULL || path[0] == '\0') {
+ archive_set_error(&a->archive, -1, "Pathname required");
+ return (ARCHIVE_FAILED);
+ }
+
+ if (!archive_entry_size_is_set(entry) || archive_entry_size(entry) < 0) {
+ archive_set_error(&a->archive, -1, "Size required");
+ return (ARCHIVE_FAILED);
+ }
+ return write_header(a, entry);
+}
+
+static int
+write_header(struct archive_write *a, struct archive_entry *entry)
+{
struct cpio *cpio;
const char *p, *path;
- int pathlength, ret, ret2;
+ int pathlength, ret, ret_final;
int64_t ino;
- struct cpio_header h;
+ char h[76];
+ struct archive_string_conv *sconv;
+ size_t len;
cpio = (struct cpio *)a->format_data;
- ret2 = ARCHIVE_OK;
-
- path = archive_entry_pathname(entry);
- pathlength = (int)strlen(path) + 1; /* Include trailing null. */
+ ret_final = ARCHIVE_OK;
+ sconv = get_sconv(a);
+
+ ret = archive_entry_pathname_l(entry, &path, &len, sconv);
+ if (ret != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate pathname '%s' to %s",
+ archive_entry_pathname(entry),
+ archive_string_conversion_charset_name(sconv));
+ ret_final = ARCHIVE_WARN;
+ }
+ /* Include trailing null. */
+ pathlength = (int)len + 1;
- memset(&h, 0, sizeof(h));
- format_octal(070707, &h.c_magic, sizeof(h.c_magic));
- format_octal(archive_entry_dev(entry), &h.c_dev, sizeof(h.c_dev));
+ memset(h, 0, sizeof(h));
+ format_octal(070707, h + c_magic_offset, c_magic_size);
+ format_octal(archive_entry_dev(entry), h + c_dev_offset, c_dev_size);
ino = synthesize_ino_value(cpio, entry);
if (ino < 0) {
@@ -213,49 +314,68 @@ archive_write_cpio_header(struct archive_write *a, struct archive_entry *entry)
"Too many files for this cpio format");
return (ARCHIVE_FATAL);
}
- format_octal(ino & 0777777, &h.c_ino, sizeof(h.c_ino));
+ format_octal(ino & 0777777, h + c_ino_offset, c_ino_size);
- format_octal(archive_entry_mode(entry), &h.c_mode, sizeof(h.c_mode));
- format_octal(archive_entry_uid(entry), &h.c_uid, sizeof(h.c_uid));
- format_octal(archive_entry_gid(entry), &h.c_gid, sizeof(h.c_gid));
- format_octal(archive_entry_nlink(entry), &h.c_nlink, sizeof(h.c_nlink));
+ /* TODO: Set ret_final to ARCHIVE_WARN if any of these overflow. */
+ format_octal(archive_entry_mode(entry), h + c_mode_offset, c_mode_size);
+ format_octal(archive_entry_uid(entry), h + c_uid_offset, c_uid_size);
+ format_octal(archive_entry_gid(entry), h + c_gid_offset, c_gid_size);
+ format_octal(archive_entry_nlink(entry), h + c_nlink_offset, c_nlink_size);
if (archive_entry_filetype(entry) == AE_IFBLK
|| archive_entry_filetype(entry) == AE_IFCHR)
- format_octal(archive_entry_dev(entry), &h.c_rdev, sizeof(h.c_rdev));
+ format_octal(archive_entry_dev(entry), h + c_rdev_offset, c_rdev_size);
else
- format_octal(0, &h.c_rdev, sizeof(h.c_rdev));
- format_octal(archive_entry_mtime(entry), &h.c_mtime, sizeof(h.c_mtime));
- format_octal(pathlength, &h.c_namesize, sizeof(h.c_namesize));
+ format_octal(0, h + c_rdev_offset, c_rdev_size);
+ format_octal(archive_entry_mtime(entry), h + c_mtime_offset, c_mtime_size);
+ format_octal(pathlength, h + c_namesize_offset, c_namesize_size);
/* Non-regular files don't store bodies. */
if (archive_entry_filetype(entry) != AE_IFREG)
archive_entry_set_size(entry, 0);
/* Symlinks get the link written as the body of the entry. */
- p = archive_entry_symlink(entry);
- if (p != NULL && *p != '\0')
- format_octal(strlen(p), &h.c_filesize, sizeof(h.c_filesize));
+ ret = archive_entry_symlink_l(entry, &p, &len, sconv);
+ if (ret != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Linkname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate linkname '%s' to %s",
+ archive_entry_symlink(entry),
+ archive_string_conversion_charset_name(sconv));
+ ret_final = ARCHIVE_WARN;
+ }
+ if (len > 0 && p != NULL && *p != '\0')
+ ret = format_octal(strlen(p), h + c_filesize_offset,
+ c_filesize_size);
else
- format_octal(archive_entry_size(entry),
- &h.c_filesize, sizeof(h.c_filesize));
+ ret = format_octal(archive_entry_size(entry),
+ h + c_filesize_offset, c_filesize_size);
+ if (ret) {
+ archive_set_error(&a->archive, ERANGE,
+ "File is too large for cpio format.");
+ return (ARCHIVE_FAILED);
+ }
- ret = (a->compressor.write)(a, &h, sizeof(h));
+ ret = __archive_write_output(a, h, sizeof(h));
if (ret != ARCHIVE_OK)
return (ARCHIVE_FATAL);
- ret = (a->compressor.write)(a, path, pathlength);
+ ret = __archive_write_output(a, path, pathlength);
if (ret != ARCHIVE_OK)
return (ARCHIVE_FATAL);
cpio->entry_bytes_remaining = archive_entry_size(entry);
/* Write the symlink now. */
- if (p != NULL && *p != '\0')
- ret = (a->compressor.write)(a, p, strlen(p));
-
- if (ret == ARCHIVE_OK)
- ret = ret2;
- return (ret);
+ if (p != NULL && *p != '\0') {
+ ret = __archive_write_output(a, p, strlen(p));
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+ return (ret_final);
}
static ssize_t
@@ -268,7 +388,7 @@ archive_write_cpio_data(struct archive_write *a, const void *buff, size_t s)
if (s > cpio->entry_bytes_remaining)
s = cpio->entry_bytes_remaining;
- ret = (a->compressor.write)(a, buff, s);
+ ret = __archive_write_output(a, buff, s);
cpio->entry_bytes_remaining -= s;
if (ret >= 0)
return (s);
@@ -307,22 +427,23 @@ format_octal_recursive(int64_t v, char *p, int s)
}
static int
-archive_write_cpio_finish(struct archive_write *a)
+archive_write_cpio_close(struct archive_write *a)
{
int er;
struct archive_entry *trailer;
- trailer = archive_entry_new();
+ trailer = archive_entry_new2(NULL);
/* nlink = 1 here for GNU cpio compat. */
archive_entry_set_nlink(trailer, 1);
+ archive_entry_set_size(trailer, 0);
archive_entry_set_pathname(trailer, "TRAILER!!!");
- er = archive_write_cpio_header(a, trailer);
+ er = write_header(a, trailer);
archive_entry_free(trailer);
return (er);
}
static int
-archive_write_cpio_destroy(struct archive_write *a)
+archive_write_cpio_free(struct archive_write *a)
{
struct cpio *cpio;
@@ -337,18 +458,7 @@ static int
archive_write_cpio_finish_entry(struct archive_write *a)
{
struct cpio *cpio;
- size_t to_write;
- int ret;
cpio = (struct cpio *)a->format_data;
- ret = ARCHIVE_OK;
- while (cpio->entry_bytes_remaining > 0) {
- to_write = cpio->entry_bytes_remaining < a->null_length ?
- cpio->entry_bytes_remaining : a->null_length;
- ret = (a->compressor.write)(a, a->nulls, to_write);
- if (ret != ARCHIVE_OK)
- return (ret);
- cpio->entry_bytes_remaining -= to_write;
- }
- return (ret);
+ return (__archive_write_nulls(a, cpio->entry_bytes_remaining));
}
diff --git a/libarchive/archive_write_set_format_cpio_newc.c b/libarchive/archive_write_set_format_cpio_newc.c
index 0af0890952ef..d06c391a81fd 100644
--- a/libarchive/archive_write_set_format_cpio_newc.c
+++ b/libarchive/archive_write_set_format_cpio_newc.c
@@ -40,41 +40,62 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_cpio_newc.c 201
#include "archive.h"
#include "archive_entry.h"
+#include "archive_entry_locale.h"
#include "archive_private.h"
#include "archive_write_private.h"
static ssize_t archive_write_newc_data(struct archive_write *,
const void *buff, size_t s);
-static int archive_write_newc_finish(struct archive_write *);
-static int archive_write_newc_destroy(struct archive_write *);
+static int archive_write_newc_close(struct archive_write *);
+static int archive_write_newc_free(struct archive_write *);
static int archive_write_newc_finish_entry(struct archive_write *);
static int archive_write_newc_header(struct archive_write *,
struct archive_entry *);
+static int archive_write_newc_options(struct archive_write *,
+ const char *, const char *);
static int format_hex(int64_t, void *, int);
static int64_t format_hex_recursive(int64_t, char *, int);
+static int write_header(struct archive_write *, struct archive_entry *);
struct cpio {
uint64_t entry_bytes_remaining;
int padding;
-};
-struct cpio_header_newc {
- char c_magic[6];
- char c_ino[8];
- char c_mode[8];
- char c_uid[8];
- char c_gid[8];
- char c_nlink[8];
- char c_mtime[8];
- char c_filesize[8];
- char c_devmajor[8];
- char c_devminor[8];
- char c_rdevmajor[8];
- char c_rdevminor[8];
- char c_namesize[8];
- char c_checksum[8];
+ struct archive_string_conv *opt_sconv;
+ struct archive_string_conv *sconv_default;
+ int init_default_conversion;
};
+#define c_magic_offset 0
+#define c_magic_size 6
+#define c_ino_offset 6
+#define c_ino_size 8
+#define c_mode_offset 14
+#define c_mode_size 8
+#define c_uid_offset 22
+#define c_uid_size 8
+#define c_gid_offset 30
+#define c_gid_size 8
+#define c_nlink_offset 38
+#define c_nlink_size 8
+#define c_mtime_offset 46
+#define c_mtime_size 8
+#define c_filesize_offset 54
+#define c_filesize_size 8
+#define c_devmajor_offset 62
+#define c_devmajor_size 8
+#define c_devminor_offset 70
+#define c_devminor_size 8
+#define c_rdevmajor_offset 78
+#define c_rdevmajor_size 8
+#define c_rdevminor_offset 86
+#define c_rdevminor_size 8
+#define c_namesize_offset 94
+#define c_namesize_size 8
+#define c_checksum_offset 102
+#define c_checksum_size 8
+#define c_header_size 110
+
/* Logic trick: difference between 'n' and next multiple of 4 */
#define PAD4(n) (3 & (1 + ~(n)))
@@ -87,9 +108,12 @@ archive_write_set_format_cpio_newc(struct archive *_a)
struct archive_write *a = (struct archive_write *)_a;
struct cpio *cpio;
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_cpio_newc");
+
/* If someone else was already registered, unregister them. */
- if (a->format_destroy != NULL)
- (a->format_destroy)(a);
+ if (a->format_free != NULL)
+ (a->format_free)(a);
cpio = (struct cpio *)malloc(sizeof(*cpio));
if (cpio == NULL) {
@@ -98,107 +122,217 @@ archive_write_set_format_cpio_newc(struct archive *_a)
}
memset(cpio, 0, sizeof(*cpio));
a->format_data = cpio;
-
- a->pad_uncompressed = 1;
a->format_name = "cpio";
+ a->format_options = archive_write_newc_options;
a->format_write_header = archive_write_newc_header;
a->format_write_data = archive_write_newc_data;
a->format_finish_entry = archive_write_newc_finish_entry;
- a->format_finish = archive_write_newc_finish;
- a->format_destroy = archive_write_newc_destroy;
+ a->format_close = archive_write_newc_close;
+ a->format_free = archive_write_newc_free;
a->archive.archive_format = ARCHIVE_FORMAT_CPIO_SVR4_NOCRC;
a->archive.archive_format_name = "SVR4 cpio nocrc";
return (ARCHIVE_OK);
}
static int
+archive_write_newc_options(struct archive_write *a, const char *key,
+ const char *val)
+{
+ struct cpio *cpio = (struct cpio *)a->format_data;
+ int ret = ARCHIVE_FAILED;
+
+ if (strcmp(key, "hdrcharset") == 0) {
+ if (val == NULL || val[0] == 0)
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "%s: hdrcharset option needs a character-set name",
+ a->format_name);
+ else {
+ cpio->opt_sconv = archive_string_conversion_to_charset(
+ &a->archive, val, 0);
+ if (cpio->opt_sconv != NULL)
+ ret = ARCHIVE_OK;
+ else
+ ret = ARCHIVE_FATAL;
+ }
+ } else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "%s: unknown keyword ``%s''", a->format_name, key);
+
+ return (ret);
+}
+
+static struct archive_string_conv *
+get_sconv(struct archive_write *a)
+{
+ struct cpio *cpio;
+ struct archive_string_conv *sconv;
+
+ cpio = (struct cpio *)a->format_data;
+ sconv = cpio->opt_sconv;
+ if (sconv == NULL) {
+ if (!cpio->init_default_conversion) {
+ cpio->sconv_default =
+ archive_string_default_conversion_for_write(
+ &(a->archive));
+ cpio->init_default_conversion = 1;
+ }
+ sconv = cpio->sconv_default;
+ }
+ return (sconv);
+}
+
+static int
archive_write_newc_header(struct archive_write *a, struct archive_entry *entry)
{
+ const char *path;
+ size_t len;
+
+ if (archive_entry_filetype(entry) == 0) {
+ archive_set_error(&a->archive, -1, "Filetype required");
+ return (ARCHIVE_FAILED);
+ }
+
+ if (archive_entry_pathname_l(entry, &path, &len, get_sconv(a)) != 0
+ && errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathname");
+ return (ARCHIVE_FATAL);
+ }
+ if (len == 0 || path == NULL || path[0] == '\0') {
+ archive_set_error(&a->archive, -1, "Pathname required");
+ return (ARCHIVE_FAILED);
+ }
+
+ if (archive_entry_hardlink(entry) == NULL
+ && (!archive_entry_size_is_set(entry) || archive_entry_size(entry) < 0)) {
+ archive_set_error(&a->archive, -1, "Size required");
+ return (ARCHIVE_FAILED);
+ }
+ return write_header(a, entry);
+}
+
+static int
+write_header(struct archive_write *a, struct archive_entry *entry)
+{
int64_t ino;
struct cpio *cpio;
const char *p, *path;
- int pathlength, ret, ret2;
- struct cpio_header_newc h;
+ int pathlength, ret, ret_final;
+ char h[c_header_size];
+ struct archive_string_conv *sconv;
+ size_t len;
int pad;
cpio = (struct cpio *)a->format_data;
- ret2 = ARCHIVE_OK;
-
- path = archive_entry_pathname(entry);
- pathlength = (int)strlen(path) + 1; /* Include trailing null. */
+ ret_final = ARCHIVE_OK;
+ sconv = get_sconv(a);
+
+ ret = archive_entry_pathname_l(entry, &path, &len, sconv);
+ if (ret != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate pathname '%s' to %s",
+ archive_entry_pathname(entry),
+ archive_string_conversion_charset_name(sconv));
+ ret_final = ARCHIVE_WARN;
+ }
+ pathlength = (int)len + 1; /* Include trailing null. */
- memset(&h, 0, sizeof(h));
- format_hex(0x070701, &h.c_magic, sizeof(h.c_magic));
- format_hex(archive_entry_devmajor(entry), &h.c_devmajor,
- sizeof(h.c_devmajor));
- format_hex(archive_entry_devminor(entry), &h.c_devminor,
- sizeof(h.c_devminor));
+ memset(h, 0, c_header_size);
+ format_hex(0x070701, h + c_magic_offset, c_magic_size);
+ format_hex(archive_entry_devmajor(entry), h + c_devmajor_offset,
+ c_devmajor_size);
+ format_hex(archive_entry_devminor(entry), h + c_devminor_offset,
+ c_devminor_size);
ino = archive_entry_ino64(entry);
if (ino > 0xffffffff) {
archive_set_error(&a->archive, ERANGE,
"large inode number truncated");
- ret2 = ARCHIVE_WARN;
+ ret_final = ARCHIVE_WARN;
}
- format_hex(ino & 0xffffffff, &h.c_ino, sizeof(h.c_ino));
- format_hex(archive_entry_mode(entry), &h.c_mode, sizeof(h.c_mode));
- format_hex(archive_entry_uid(entry), &h.c_uid, sizeof(h.c_uid));
- format_hex(archive_entry_gid(entry), &h.c_gid, sizeof(h.c_gid));
- format_hex(archive_entry_nlink(entry), &h.c_nlink, sizeof(h.c_nlink));
+ /* TODO: Set ret_final to ARCHIVE_WARN if any of these overflow. */
+ format_hex(ino & 0xffffffff, h + c_ino_offset, c_ino_size);
+ format_hex(archive_entry_mode(entry), h + c_mode_offset, c_mode_size);
+ format_hex(archive_entry_uid(entry), h + c_uid_offset, c_uid_size);
+ format_hex(archive_entry_gid(entry), h + c_gid_offset, c_gid_size);
+ format_hex(archive_entry_nlink(entry), h + c_nlink_offset, c_nlink_size);
if (archive_entry_filetype(entry) == AE_IFBLK
|| archive_entry_filetype(entry) == AE_IFCHR) {
- format_hex(archive_entry_rdevmajor(entry), &h.c_rdevmajor, sizeof(h.c_rdevmajor));
- format_hex(archive_entry_rdevminor(entry), &h.c_rdevminor, sizeof(h.c_rdevminor));
+ format_hex(archive_entry_rdevmajor(entry), h + c_rdevmajor_offset, c_rdevmajor_size);
+ format_hex(archive_entry_rdevminor(entry), h + c_rdevminor_offset, c_rdevminor_size);
} else {
- format_hex(0, &h.c_rdevmajor, sizeof(h.c_rdevmajor));
- format_hex(0, &h.c_rdevminor, sizeof(h.c_rdevminor));
+ format_hex(0, h + c_rdevmajor_offset, c_rdevmajor_size);
+ format_hex(0, h + c_rdevminor_offset, c_rdevminor_size);
}
- format_hex(archive_entry_mtime(entry), &h.c_mtime, sizeof(h.c_mtime));
- format_hex(pathlength, &h.c_namesize, sizeof(h.c_namesize));
- format_hex(0, &h.c_checksum, sizeof(h.c_checksum));
+ format_hex(archive_entry_mtime(entry), h + c_mtime_offset, c_mtime_size);
+ format_hex(pathlength, h + c_namesize_offset, c_namesize_size);
+ format_hex(0, h + c_checksum_offset, c_checksum_size);
/* Non-regular files don't store bodies. */
if (archive_entry_filetype(entry) != AE_IFREG)
archive_entry_set_size(entry, 0);
/* Symlinks get the link written as the body of the entry. */
- p = archive_entry_symlink(entry);
- if (p != NULL && *p != '\0')
- format_hex(strlen(p), &h.c_filesize, sizeof(h.c_filesize));
+ ret = archive_entry_symlink_l(entry, &p, &len, sconv);
+ if (ret != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Likname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate linkname '%s' to %s",
+ archive_entry_symlink(entry),
+ archive_string_conversion_charset_name(sconv));
+ ret_final = ARCHIVE_WARN;
+ }
+ if (len > 0 && p != NULL && *p != '\0')
+ ret = format_hex(strlen(p), h + c_filesize_offset,
+ c_filesize_size);
else
- format_hex(archive_entry_size(entry),
- &h.c_filesize, sizeof(h.c_filesize));
+ ret = format_hex(archive_entry_size(entry),
+ h + c_filesize_offset, c_filesize_size);
+ if (ret) {
+ archive_set_error(&a->archive, ERANGE,
+ "File is too large for this format.");
+ return (ARCHIVE_FAILED);
+ }
- ret = (a->compressor.write)(a, &h, sizeof(h));
+ ret = __archive_write_output(a, h, c_header_size);
if (ret != ARCHIVE_OK)
return (ARCHIVE_FATAL);
/* Pad pathname to even length. */
- ret = (a->compressor.write)(a, path, pathlength);
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- pad = PAD4(pathlength + sizeof(struct cpio_header_newc));
- if (pad)
- ret = (a->compressor.write)(a, "\0\0\0", pad);
+ ret = __archive_write_output(a, path, pathlength);
if (ret != ARCHIVE_OK)
return (ARCHIVE_FATAL);
+ pad = PAD4(pathlength + c_header_size);
+ if (pad) {
+ ret = __archive_write_output(a, "\0\0\0", pad);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
cpio->entry_bytes_remaining = archive_entry_size(entry);
cpio->padding = PAD4(cpio->entry_bytes_remaining);
/* Write the symlink now. */
if (p != NULL && *p != '\0') {
- ret = (a->compressor.write)(a, p, strlen(p));
+ ret = __archive_write_output(a, p, strlen(p));
if (ret != ARCHIVE_OK)
return (ARCHIVE_FATAL);
pad = PAD4(strlen(p));
- ret = (a->compressor.write)(a, "\0\0\0", pad);
+ ret = __archive_write_output(a, "\0\0\0", pad);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
}
-
- if (ret == ARCHIVE_OK)
- ret = ret2;
- return (ret);
+ return (ret_final);
}
static ssize_t
@@ -211,7 +345,7 @@ archive_write_newc_data(struct archive_write *a, const void *buff, size_t s)
if (s > cpio->entry_bytes_remaining)
s = cpio->entry_bytes_remaining;
- ret = (a->compressor.write)(a, buff, s);
+ ret = __archive_write_output(a, buff, s);
cpio->entry_bytes_remaining -= s;
if (ret >= 0)
return (s);
@@ -250,21 +384,23 @@ format_hex_recursive(int64_t v, char *p, int s)
}
static int
-archive_write_newc_finish(struct archive_write *a)
+archive_write_newc_close(struct archive_write *a)
{
int er;
struct archive_entry *trailer;
trailer = archive_entry_new();
archive_entry_set_nlink(trailer, 1);
+ archive_entry_set_size(trailer, 0);
archive_entry_set_pathname(trailer, "TRAILER!!!");
- er = archive_write_newc_header(a, trailer);
+ /* Bypass the required data checks. */
+ er = write_header(a, trailer);
archive_entry_free(trailer);
return (er);
}
static int
-archive_write_newc_destroy(struct archive_write *a)
+archive_write_newc_free(struct archive_write *a)
{
struct cpio *cpio;
@@ -278,18 +414,7 @@ static int
archive_write_newc_finish_entry(struct archive_write *a)
{
struct cpio *cpio;
- size_t to_write;
- int ret;
cpio = (struct cpio *)a->format_data;
- while (cpio->entry_bytes_remaining > 0) {
- to_write = cpio->entry_bytes_remaining < a->null_length ?
- cpio->entry_bytes_remaining : a->null_length;
- ret = (a->compressor.write)(a, a->nulls, to_write);
- if (ret != ARCHIVE_OK)
- return (ret);
- cpio->entry_bytes_remaining -= to_write;
- }
- ret = (a->compressor.write)(a, a->nulls, cpio->padding);
- return (ret);
+ return (__archive_write_nulls(a, cpio->entry_bytes_remaining + cpio->padding));
}
diff --git a/libarchive/archive_write_set_format_gnutar.c b/libarchive/archive_write_set_format_gnutar.c
new file mode 100644
index 000000000000..dea46b05d4ac
--- /dev/null
+++ b/libarchive/archive_write_set_format_gnutar.c
@@ -0,0 +1,684 @@
+/*-
+ * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ * Author: Jonas Gastal <jgastal@profusion.mobi>
+ * Copyright (c) 2011 Michihiro NAKAJIMA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_gnu_tar.c 191579 2009-04-27 18:35:03Z gastal $");
+
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include "archive.h"
+#include "archive_entry.h"
+#include "archive_entry_locale.h"
+#include "archive_private.h"
+#include "archive_write_private.h"
+
+struct gnutar {
+ uint64_t entry_bytes_remaining;
+ uint64_t entry_padding;
+ const char * linkname;
+ size_t linkname_length;
+ const char * pathname;
+ size_t pathname_length;
+ const char * uname;
+ size_t uname_length;
+ const char * gname;
+ size_t gname_length;
+ struct archive_string_conv *opt_sconv;
+ struct archive_string_conv *sconv_default;
+ int init_default_conversion;
+};
+
+/*
+ * Define structure of GNU tar header.
+ */
+#define GNUTAR_name_offset 0
+#define GNUTAR_name_size 100
+#define GNUTAR_mode_offset 100
+#define GNUTAR_mode_size 7
+#define GNUTAR_mode_max_size 8
+#define GNUTAR_uid_offset 108
+#define GNUTAR_uid_size 7
+#define GNUTAR_uid_max_size 8
+#define GNUTAR_gid_offset 116
+#define GNUTAR_gid_size 7
+#define GNUTAR_gid_max_size 8
+#define GNUTAR_size_offset 124
+#define GNUTAR_size_size 11
+#define GNUTAR_size_max_size 12
+#define GNUTAR_mtime_offset 136
+#define GNUTAR_mtime_size 11
+#define GNUTAR_mtime_max_size 11
+#define GNUTAR_checksum_offset 148
+#define GNUTAR_checksum_size 8
+#define GNUTAR_typeflag_offset 156
+#define GNUTAR_typeflag_size 1
+#define GNUTAR_linkname_offset 157
+#define GNUTAR_linkname_size 100
+#define GNUTAR_magic_offset 257
+#define GNUTAR_magic_size 6
+#define GNUTAR_version_offset 263
+#define GNUTAR_version_size 2
+#define GNUTAR_uname_offset 265
+#define GNUTAR_uname_size 32
+#define GNUTAR_gname_offset 297
+#define GNUTAR_gname_size 32
+#define GNUTAR_rdevmajor_offset 329
+#define GNUTAR_rdevmajor_size 6
+#define GNUTAR_rdevmajor_max_size 8
+#define GNUTAR_rdevminor_offset 337
+#define GNUTAR_rdevminor_size 6
+#define GNUTAR_rdevminor_max_size 8
+
+/*
+ * A filled-in copy of the header for initialization.
+ */
+static const char template_header[] = {
+ /* name: 100 bytes */
+ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
+ 0,0,0,0,
+ /* Mode, null termination: 8 bytes */
+ '0','0','0','0','0','0', '0','\0',
+ /* uid, null termination: 8 bytes */
+ '0','0','0','0','0','0', '0','\0',
+ /* gid, null termination: 8 bytes */
+ '0','0','0','0','0','0', '0','\0',
+ /* size, space termation: 12 bytes */
+ '0','0','0','0','0','0','0','0','0','0','0', '\0',
+ /* mtime, space termation: 12 bytes */
+ '0','0','0','0','0','0','0','0','0','0','0', '\0',
+ /* Initial checksum value: 8 spaces */
+ ' ',' ',' ',' ',' ',' ',' ',' ',
+ /* Typeflag: 1 byte */
+ '0', /* '0' = regular file */
+ /* Linkname: 100 bytes */
+ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
+ 0,0,0,0,
+ /* Magic: 8 bytes */
+ 'u','s','t','a','r',' ', ' ','\0',
+ /* Uname: 32 bytes */
+ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
+ /* Gname: 32 bytes */
+ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
+ /* rdevmajor + null padding: 8 bytes */
+ '\0','\0','\0','\0','\0','\0', '\0','\0',
+ /* rdevminor + null padding: 8 bytes */
+ '\0','\0','\0','\0','\0','\0', '\0','\0',
+ /* Padding: 167 bytes */
+ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0
+};
+
+static int archive_write_gnutar_options(struct archive_write *,
+ const char *, const char *);
+static int archive_format_gnutar_header(struct archive_write *, char h[512],
+ struct archive_entry *, int tartype);
+static int archive_write_gnutar_header(struct archive_write *,
+ struct archive_entry *entry);
+static ssize_t archive_write_gnutar_data(struct archive_write *a, const void *buff,
+ size_t s);
+static int archive_write_gnutar_free(struct archive_write *);
+static int archive_write_gnutar_close(struct archive_write *);
+static int archive_write_gnutar_finish_entry(struct archive_write *);
+static int format_256(int64_t, char *, int);
+static int format_number(int64_t, char *, int size, int maxsize);
+static int format_octal(int64_t, char *, int);
+
+/*
+ * Set output format to 'GNU tar' format.
+ */
+int
+archive_write_set_format_gnutar(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ struct gnutar *gnutar;
+
+ gnutar = (struct gnutar *)calloc(1, sizeof(*gnutar));
+ if (gnutar == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Can't allocate gnutar data");
+ return (ARCHIVE_FATAL);
+ }
+ a->format_data = gnutar;
+ a->format_name = "gnutar";
+ a->format_options = archive_write_gnutar_options;
+ a->format_write_header = archive_write_gnutar_header;
+ a->format_write_data = archive_write_gnutar_data;
+ a->format_close = archive_write_gnutar_close;
+ a->format_free = archive_write_gnutar_free;
+ a->format_finish_entry = archive_write_gnutar_finish_entry;
+ a->archive.archive_format = ARCHIVE_FORMAT_TAR_GNUTAR;
+ a->archive.archive_format_name = "GNU tar";
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_write_gnutar_options(struct archive_write *a, const char *key,
+ const char *val)
+{
+ struct gnutar *gnutar = (struct gnutar *)a->format_data;
+ int ret = ARCHIVE_FAILED;
+
+ if (strcmp(key, "hdrcharset") == 0) {
+ if (val == NULL || val[0] == 0)
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "%s: hdrcharset option needs a character-set name",
+ a->format_name);
+ else {
+ gnutar->opt_sconv = archive_string_conversion_to_charset(
+ &a->archive, val, 0);
+ if (gnutar->opt_sconv != NULL)
+ ret = ARCHIVE_OK;
+ else
+ ret = ARCHIVE_FATAL;
+ }
+ } else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "%s: unknown keyword ``%s''", a->format_name, key);
+
+ return (ret);
+}
+
+static int
+archive_write_gnutar_close(struct archive_write *a)
+{
+ return (__archive_write_nulls(a, 512*2));
+}
+
+static int
+archive_write_gnutar_free(struct archive_write *a)
+{
+ struct gnutar *gnutar;
+
+ gnutar = (struct gnutar *)a->format_data;
+ free(gnutar);
+ a->format_data = NULL;
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_write_gnutar_finish_entry(struct archive_write *a)
+{
+ struct gnutar *gnutar;
+ int ret;
+
+ gnutar = (struct gnutar *)a->format_data;
+ ret = __archive_write_nulls(a,
+ gnutar->entry_bytes_remaining + gnutar->entry_padding);
+ gnutar->entry_bytes_remaining = gnutar->entry_padding = 0;
+ return (ret);
+}
+
+static ssize_t
+archive_write_gnutar_data(struct archive_write *a, const void *buff, size_t s)
+{
+ struct gnutar *gnutar;
+ int ret;
+
+ gnutar = (struct gnutar *)a->format_data;
+ if (s > gnutar->entry_bytes_remaining)
+ s = gnutar->entry_bytes_remaining;
+ ret = __archive_write_output(a, buff, s);
+ gnutar->entry_bytes_remaining -= s;
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ return (s);
+}
+
+static int
+archive_write_gnutar_header(struct archive_write *a,
+ struct archive_entry *entry)
+{
+ char buff[512];
+ int r, ret, ret2 = ARCHIVE_OK;
+ int tartype;
+ struct gnutar *gnutar;
+ struct archive_string_conv *sconv;
+
+ gnutar = (struct gnutar *)a->format_data;
+
+ /* Setup default string conversion. */
+ if (gnutar->opt_sconv == NULL) {
+ if (!gnutar->init_default_conversion) {
+ gnutar->sconv_default =
+ archive_string_default_conversion_for_write(
+ &(a->archive));
+ gnutar->init_default_conversion = 1;
+ }
+ sconv = gnutar->sconv_default;
+ } else
+ sconv = gnutar->opt_sconv;
+
+ /* Only regular files (not hardlinks) have data. */
+ if (archive_entry_hardlink(entry) != NULL ||
+ archive_entry_symlink(entry) != NULL ||
+ !(archive_entry_filetype(entry) == AE_IFREG))
+ archive_entry_set_size(entry, 0);
+
+ if (AE_IFDIR == archive_entry_filetype(entry)) {
+ const char *p;
+ char *t;
+ /*
+ * Ensure a trailing '/'. Modify the entry so
+ * the client sees the change.
+ */
+ p = archive_entry_pathname(entry);
+ if (p[strlen(p) - 1] != '/') {
+ t = (char *)malloc(strlen(p) + 2);
+ if (t == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate gnutar data");
+ return(ARCHIVE_FATAL);
+ }
+ strcpy(t, p);
+ strcat(t, "/");
+ archive_entry_copy_pathname(entry, t);
+ free(t);
+ }
+ }
+
+ r = archive_entry_pathname_l(entry, &(gnutar->pathname),
+ &(gnutar->pathname_length), sconv);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathame");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate pathname '%s' to %s",
+ archive_entry_pathname(entry),
+ archive_string_conversion_charset_name(sconv));
+ ret2 = ARCHIVE_WARN;
+ }
+ r = archive_entry_uname_l(entry, &(gnutar->uname),
+ &(gnutar->uname_length), sconv);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Uname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate uname '%s' to %s",
+ archive_entry_uname(entry),
+ archive_string_conversion_charset_name(sconv));
+ ret2 = ARCHIVE_WARN;
+ }
+ r = archive_entry_gname_l(entry, &(gnutar->gname),
+ &(gnutar->gname_length), sconv);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Gname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate gname '%s' to %s",
+ archive_entry_gname(entry),
+ archive_string_conversion_charset_name(sconv));
+ ret2 = ARCHIVE_WARN;
+ }
+
+ /* If linkname is longer than 100 chars we need to add a 'K' header. */
+ r = archive_entry_hardlink_l(entry, &(gnutar->linkname),
+ &(gnutar->linkname_length), sconv);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Linkname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate linkname '%s' to %s",
+ archive_entry_hardlink(entry),
+ archive_string_conversion_charset_name(sconv));
+ ret2 = ARCHIVE_WARN;
+ }
+ if (gnutar->linkname_length == 0) {
+ r = archive_entry_symlink_l(entry, &(gnutar->linkname),
+ &(gnutar->linkname_length), sconv);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Linkname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate linkname '%s' to %s",
+ archive_entry_hardlink(entry),
+ archive_string_conversion_charset_name(sconv));
+ ret2 = ARCHIVE_WARN;
+ }
+ }
+ if (gnutar->linkname_length > GNUTAR_linkname_size) {
+ size_t todo = gnutar->linkname_length;
+ struct archive_entry *temp = archive_entry_new2(&a->archive);
+
+ /* Uname/gname here don't really matter since no one reads them;
+ * these are the values that GNU tar happens to use on FreeBSD. */
+ archive_entry_set_uname(temp, "root");
+ archive_entry_set_gname(temp, "wheel");
+
+ archive_entry_set_pathname(temp, "././@LongLink");
+ archive_entry_set_size(temp, gnutar->linkname_length + 1);
+ ret = archive_format_gnutar_header(a, buff, temp, 'K');
+ if (ret < ARCHIVE_WARN)
+ return (ret);
+ ret = __archive_write_output(a, buff, 512);
+ if(ret < ARCHIVE_WARN)
+ return (ret);
+ archive_entry_free(temp);
+ /* Write as many 512 bytes blocks as needed to write full name. */
+ ret = __archive_write_output(a, gnutar->linkname, todo);
+ if(ret < ARCHIVE_WARN)
+ return (ret);
+ ret = __archive_write_nulls(a, 0x1ff & (-(ssize_t)todo));
+ if (ret < ARCHIVE_WARN)
+ return (ret);
+ }
+
+ /* If pathname is longer than 100 chars we need to add an 'L' header. */
+ if (gnutar->pathname_length > GNUTAR_name_size) {
+ const char *pathname = gnutar->pathname;
+ size_t todo = gnutar->pathname_length;
+ struct archive_entry *temp = archive_entry_new2(&a->archive);
+
+ /* Uname/gname here don't really matter since no one reads them;
+ * these are the values that GNU tar happens to use on FreeBSD. */
+ archive_entry_set_uname(temp, "root");
+ archive_entry_set_gname(temp, "wheel");
+
+ archive_entry_set_pathname(temp, "././@LongLink");
+ archive_entry_set_size(temp, gnutar->pathname_length + 1);
+ ret = archive_format_gnutar_header(a, buff, temp, 'L');
+ if (ret < ARCHIVE_WARN)
+ return (ret);
+ ret = __archive_write_output(a, buff, 512);
+ if(ret < ARCHIVE_WARN)
+ return (ret);
+ archive_entry_free(temp);
+ /* Write as many 512 bytes blocks as needed to write full name. */
+ ret = __archive_write_output(a, pathname, todo);
+ if(ret < ARCHIVE_WARN)
+ return (ret);
+ ret = __archive_write_nulls(a, 0x1ff & (-(ssize_t)todo));
+ if (ret < ARCHIVE_WARN)
+ return (ret);
+ }
+
+ if (archive_entry_hardlink(entry) != NULL) {
+ tartype = '1';
+ } else
+ switch (archive_entry_filetype(entry)) {
+ case AE_IFREG: tartype = '0' ; break;
+ case AE_IFLNK: tartype = '2' ; break;
+ case AE_IFCHR: tartype = '3' ; break;
+ case AE_IFBLK: tartype = '4' ; break;
+ case AE_IFDIR: tartype = '5' ; break;
+ case AE_IFIFO: tartype = '6' ; break;
+ case AE_IFSOCK:
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "tar format cannot archive socket");
+ return (ARCHIVE_FAILED);
+ default:
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "tar format cannot archive this (mode=0%lo)",
+ (unsigned long)archive_entry_mode(entry));
+ return (ARCHIVE_FAILED);
+ }
+
+ ret = archive_format_gnutar_header(a, buff, entry, tartype);
+ if (ret < ARCHIVE_WARN)
+ return (ret);
+ if (ret2 < ret)
+ ret = ret2;
+ ret2 = __archive_write_output(a, buff, 512);
+ if (ret2 < ARCHIVE_WARN)
+ return (ret2);
+ if (ret2 < ret)
+ ret = ret2;
+
+ gnutar->entry_bytes_remaining = archive_entry_size(entry);
+ gnutar->entry_padding = 0x1ff & (-(int64_t)gnutar->entry_bytes_remaining);
+ return (ret);
+}
+
+static int
+archive_format_gnutar_header(struct archive_write *a, char h[512],
+ struct archive_entry *entry, int tartype)
+{
+ unsigned int checksum;
+ int i, ret;
+ size_t copy_length;
+ const char *p;
+ struct gnutar *gnutar;
+
+ gnutar = (struct gnutar *)a->format_data;
+
+ ret = 0;
+
+ /*
+ * The "template header" already includes the signature,
+ * various end-of-field markers, and other required elements.
+ */
+ memcpy(h, &template_header, 512);
+
+ /*
+ * Because the block is already null-filled, and strings
+ * are allowed to exactly fill their destination (without null),
+ * I use memcpy(dest, src, strlen()) here a lot to copy strings.
+ */
+
+ if (tartype == 'K' || tartype == 'L') {
+ p = archive_entry_pathname(entry);
+ copy_length = strlen(p);
+ } else {
+ p = gnutar->pathname;
+ copy_length = gnutar->pathname_length;
+ }
+ if (copy_length > GNUTAR_name_size)
+ copy_length = GNUTAR_name_size;
+ memcpy(h + GNUTAR_name_offset, p, copy_length);
+
+ if ((copy_length = gnutar->linkname_length) > 0) {
+ if (copy_length > GNUTAR_linkname_size)
+ copy_length = GNUTAR_linkname_size;
+ memcpy(h + GNUTAR_linkname_offset, gnutar->linkname,
+ copy_length);
+ }
+
+ /* TODO: How does GNU tar handle unames longer than GNUTAR_uname_size? */
+ if (tartype == 'K' || tartype == 'L') {
+ p = archive_entry_uname(entry);
+ copy_length = strlen(p);
+ } else {
+ p = gnutar->uname;
+ copy_length = gnutar->uname_length;
+ }
+ if (copy_length > 0) {
+ if (copy_length > GNUTAR_uname_size)
+ copy_length = GNUTAR_uname_size;
+ memcpy(h + GNUTAR_uname_offset, p, copy_length);
+ }
+
+ /* TODO: How does GNU tar handle gnames longer than GNUTAR_gname_size? */
+ if (tartype == 'K' || tartype == 'L') {
+ p = archive_entry_gname(entry);
+ copy_length = strlen(p);
+ } else {
+ p = gnutar->gname;
+ copy_length = gnutar->gname_length;
+ }
+ if (copy_length > 0) {
+ if (strlen(p) > GNUTAR_gname_size)
+ copy_length = GNUTAR_gname_size;
+ memcpy(h + GNUTAR_gname_offset, p, copy_length);
+ }
+
+ /* By truncating the mode here, we ensure it always fits. */
+ format_octal(archive_entry_mode(entry) & 07777,
+ h + GNUTAR_mode_offset, GNUTAR_mode_size);
+
+ /* TODO: How does GNU tar handle large UIDs? */
+ if (format_octal(archive_entry_uid(entry),
+ h + GNUTAR_uid_offset, GNUTAR_uid_size)) {
+ archive_set_error(&a->archive, ERANGE,
+ "Numeric user ID %jd too large",
+ (intmax_t)archive_entry_uid(entry));
+ ret = ARCHIVE_FAILED;
+ }
+
+ /* TODO: How does GNU tar handle large GIDs? */
+ if (format_octal(archive_entry_gid(entry),
+ h + GNUTAR_gid_offset, GNUTAR_gid_size)) {
+ archive_set_error(&a->archive, ERANGE,
+ "Numeric group ID %jd too large",
+ (intmax_t)archive_entry_gid(entry));
+ ret = ARCHIVE_FAILED;
+ }
+
+ /* GNU tar supports base-256 here, so should never overflow. */
+ if (format_number(archive_entry_size(entry), h + GNUTAR_size_offset,
+ GNUTAR_size_size, GNUTAR_size_max_size)) {
+ archive_set_error(&a->archive, ERANGE,
+ "File size out of range");
+ ret = ARCHIVE_FAILED;
+ }
+
+ /* Shouldn't overflow before 2106, since mtime field is 33 bits. */
+ format_octal(archive_entry_mtime(entry),
+ h + GNUTAR_mtime_offset, GNUTAR_mtime_size);
+
+ if (archive_entry_filetype(entry) == AE_IFBLK
+ || archive_entry_filetype(entry) == AE_IFCHR) {
+ if (format_octal(archive_entry_rdevmajor(entry),
+ h + GNUTAR_rdevmajor_offset,
+ GNUTAR_rdevmajor_size)) {
+ archive_set_error(&a->archive, ERANGE,
+ "Major device number too large");
+ ret = ARCHIVE_FAILED;
+ }
+
+ if (format_octal(archive_entry_rdevminor(entry),
+ h + GNUTAR_rdevminor_offset,
+ GNUTAR_rdevminor_size)) {
+ archive_set_error(&a->archive, ERANGE,
+ "Minor device number too large");
+ ret = ARCHIVE_FAILED;
+ }
+ }
+
+ h[GNUTAR_typeflag_offset] = tartype;
+
+ checksum = 0;
+ for (i = 0; i < 512; i++)
+ checksum += 255 & (unsigned int)h[i];
+ h[GNUTAR_checksum_offset + 6] = '\0'; /* Can't be pre-set in the template. */
+ /* h[GNUTAR_checksum_offset + 7] = ' '; */ /* This is pre-set in the template. */
+ format_octal(checksum, h + GNUTAR_checksum_offset, 6);
+ return (ret);
+}
+
+/*
+ * Format a number into a field, falling back to base-256 if necessary.
+ */
+static int
+format_number(int64_t v, char *p, int s, int maxsize)
+{
+ int64_t limit = ((int64_t)1 << (s*3));
+
+ if (v < limit)
+ return (format_octal(v, p, s));
+ return (format_256(v, p, maxsize));
+}
+
+/*
+ * Format a number into the specified field using base-256.
+ */
+static int
+format_256(int64_t v, char *p, int s)
+{
+ p += s;
+ while (s-- > 0) {
+ *--p = (char)(v & 0xff);
+ v >>= 8;
+ }
+ *p |= 0x80; /* Set the base-256 marker bit. */
+ return (0);
+}
+
+/*
+ * Format a number into the specified field using octal.
+ */
+static int
+format_octal(int64_t v, char *p, int s)
+{
+ int len = s;
+
+ /* Octal values can't be negative, so use 0. */
+ if (v < 0)
+ v = 0;
+
+ p += s; /* Start at the end and work backwards. */
+ while (s-- > 0) {
+ *--p = (char)('0' + (v & 7));
+ v >>= 3;
+ }
+
+ if (v == 0)
+ return (0);
+
+ /* If it overflowed, fill field with max value. */
+ while (len-- > 0)
+ *p++ = '7';
+
+ return (-1);
+}
diff --git a/libarchive/archive_write_set_format_iso9660.c b/libarchive/archive_write_set_format_iso9660.c
new file mode 100644
index 000000000000..8e1c01830e4b
--- /dev/null
+++ b/libarchive/archive_write_set_format_iso9660.c
@@ -0,0 +1,8114 @@
+/*-
+ * Copyright (c) 2009-2011 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#include <stdio.h>
+#include <stdarg.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <time.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_ZLIB_H
+#include <zlib.h>
+#endif
+
+#include "archive.h"
+#include "archive_endian.h"
+#include "archive_entry.h"
+#include "archive_entry_locale.h"
+#include "archive_private.h"
+#include "archive_rb.h"
+#include "archive_write_private.h"
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#define getuid() 0
+#define getgid() 0
+#endif
+
+/*#define DEBUG 1*/
+#ifdef DEBUG
+/* To compare to the ISO image file made by mkisofs. */
+#define COMPAT_MKISOFS 1
+#endif
+
+#define LOGICAL_BLOCK_BITS 11
+#define LOGICAL_BLOCK_SIZE 2048
+#define PATH_TABLE_BLOCK_SIZE 4096
+
+#define SYSTEM_AREA_BLOCK 16
+#define PRIMARY_VOLUME_DESCRIPTOR_BLOCK 1
+#define SUPPLEMENTARY_VOLUME_DESCRIPTOR_BLOCK 1
+#define BOOT_RECORD_DESCRIPTOR_BLOCK 1
+#define VOLUME_DESCRIPTOR_SET_TERMINATOR_BLOCK 1
+#define NON_ISO_FILE_SYSTEM_INFORMATION_BLOCK 1
+#define RRIP_ER_BLOCK 1
+#define PADDING_BLOCK 150
+
+#define FD_1_2M_SIZE (1024 * 1200)
+#define FD_1_44M_SIZE (1024 * 1440)
+#define FD_2_88M_SIZE (1024 * 2880)
+#define MULTI_EXTENT_SIZE (ARCHIVE_LITERAL_LL(1) << 32) /* 4Gi bytes. */
+#define MAX_DEPTH 8
+#define RR_CE_SIZE 28 /* SUSP "CE" extension size */
+
+#define FILE_FLAG_EXISTENCE 0x01
+#define FILE_FLAG_DIRECTORY 0x02
+#define FILE_FLAG_ASSOCIATED 0x04
+#define FILE_FLAG_RECORD 0x08
+#define FILE_FLAG_PROTECTION 0x10
+#define FILE_FLAG_MULTI_EXTENT 0x80
+
+static const char rrip_identifier[] =
+ "RRIP_1991A";
+static const char rrip_descriptor[] =
+ "THE ROCK RIDGE INTERCHANGE PROTOCOL PROVIDES SUPPORT FOR "
+ "POSIX FILE SYSTEM SEMANTICS";
+static const char rrip_source[] =
+ "PLEASE CONTACT DISC PUBLISHER FOR SPECIFICATION SOURCE. "
+ "SEE PUBLISHER IDENTIFIER IN PRIMARY VOLUME DESCRIPTOR FOR "
+ "CONTACT INFORMATION.";
+#define RRIP_ER_ID_SIZE (sizeof(rrip_identifier)-1)
+#define RRIP_ER_DSC_SIZE (sizeof(rrip_descriptor)-1)
+#define RRIP_ER_SRC_SIZE (sizeof(rrip_source)-1)
+#define RRIP_ER_SIZE (8 + RRIP_ER_ID_SIZE + \
+ RRIP_ER_DSC_SIZE + RRIP_ER_SRC_SIZE)
+
+static const unsigned char zisofs_magic[8] = {
+ 0x37, 0xE4, 0x53, 0x96, 0xC9, 0xDB, 0xD6, 0x07
+};
+
+#define ZF_HEADER_SIZE 16 /* zisofs header size. */
+#define ZF_LOG2_BS 15 /* log2 block size; 32K bytes. */
+#define ZF_BLOCK_SIZE (1UL << ZF_LOG2_BS)
+
+/*
+ * Manage extra records.
+ */
+struct extr_rec {
+ int location;
+ int offset;
+ unsigned char buf[LOGICAL_BLOCK_SIZE];
+ struct extr_rec *next;
+};
+
+struct ctl_extr_rec {
+ int use_extr;
+ unsigned char *bp;
+ struct isoent *isoent;
+ unsigned char *ce_ptr;
+ int cur_len;
+ int dr_len;
+ int limit;
+ int extr_off;
+ int extr_loc;
+};
+#define DR_SAFETY RR_CE_SIZE
+#define DR_LIMIT (254 - DR_SAFETY)
+
+/*
+ * The relation of struct isofile and isoent and archive_entry.
+ *
+ * Primary volume tree --> struct isoent
+ * |
+ * v
+ * struct isofile --> archive_entry
+ * ^
+ * |
+ * Joliet volume tree --> struct isoent
+ *
+ * struct isoent has specific information for volume.
+ */
+
+struct isofile {
+ /* Used for managing struct isofile list. */
+ struct isofile *allnext;
+ struct isofile *datanext;
+ /* Used for managing a hardlined struct isofile list. */
+ struct isofile *hlnext;
+ struct isofile *hardlink_target;
+
+ struct archive_entry *entry;
+
+ /*
+ * Used for making a directory tree.
+ */
+ struct archive_string parentdir;
+ struct archive_string basename;
+ struct archive_string basename_utf16;
+ struct archive_string symlink;
+ int dircnt; /* The number of elements of
+ * its parent directory */
+
+ /*
+ * Used for a Directory Record.
+ */
+ struct content {
+ int64_t offset_of_temp;
+ int64_t size;
+ int blocks;
+ uint32_t location;
+ /*
+ * One extent equals one content.
+ * If this entry has multi extent, `next' variable points
+ * next content data.
+ */
+ struct content *next; /* next content */
+ } content, *cur_content;
+ int write_content;
+
+ enum {
+ NO = 0,
+ BOOT_CATALOG,
+ BOOT_IMAGE,
+ } boot;
+
+ /*
+ * Used for a zisofs.
+ */
+ struct {
+ unsigned char header_size;
+ unsigned char log2_bs;
+ uint32_t uncompressed_size;
+ } zisofs;
+};
+
+struct isoent {
+ /* Keep `rbnode' at the first member of struct isoent. */
+ struct archive_rb_node rbnode;
+
+ struct isofile *file;
+
+ struct isoent *parent;
+ /* A list of children.(use chnext) */
+ struct {
+ struct isoent *first;
+ struct isoent **last;
+ int cnt;
+ } children;
+ struct archive_rb_tree rbtree;
+
+ /* A list of sub directories.(use drnext) */
+ struct {
+ struct isoent *first;
+ struct isoent **last;
+ int cnt;
+ } subdirs;
+ /* A sorted list of sub directories. */
+ struct isoent **children_sorted;
+ /* Used for managing struct isoent list. */
+ struct isoent *chnext;
+ struct isoent *drnext;
+ struct isoent *ptnext;
+
+ /*
+ * Used for making a Directory Record.
+ */
+ int dir_number;
+ struct {
+ int vd;
+ int self;
+ int parent;
+ int normal;
+ } dr_len;
+ uint32_t dir_location;
+ int dir_block;
+
+ /*
+ * Identifier:
+ * on primary, ISO9660 file/directory name.
+ * on joliet, UCS2 file/directory name.
+ * ext_off : offset of identifier extension.
+ * ext_len : length of identifier extension.
+ * id_len : byte size of identifier.
+ * on primary, this is ext_off + ext_len + version length.
+ * on joliet, this is ext_off + ext_len.
+ * mb_len : length of multibyte-character of identifier.
+ * on primary, mb_len and id_len are always the same.
+ * on joliet, mb_len and id_len are different.
+ */
+ char *identifier;
+ int ext_off;
+ int ext_len;
+ int id_len;
+ int mb_len;
+
+ /*
+ * Used for making a Rockridge extension.
+ * This is a part of Directory Records.
+ */
+ struct isoent *rr_parent;
+ struct isoent *rr_child;
+
+ /* Extra Record.(which we call in this source file)
+ * A maximum size of the Directory Record is 254.
+ * so, if generated RRIP data of a file cannot into a Directory
+ * Record because of its size, that surplus data relocate this
+ * Extra Record.
+ */
+ struct {
+ struct extr_rec *first;
+ struct extr_rec **last;
+ struct extr_rec *current;
+ } extr_rec_list;
+
+ int virtual:1;
+ /* If set to one, this file type is a directory.
+ * A convenience flag to be used as
+ * "archive_entry_filetype(isoent->file->entry) == AE_IFDIR".
+ */
+ int dir:1;
+};
+
+struct hardlink {
+ struct archive_rb_node rbnode;
+ int nlink;
+ struct {
+ struct isofile *first;
+ struct isofile **last;
+ } file_list;
+};
+
+/*
+ * ISO writer options
+ */
+struct iso_option {
+ /*
+ * Usage : abstract-file=<value>
+ * Type : string, max 37 bytes
+ * Default: Not specified
+ * COMPAT : mkisofs -abstract <value>
+ *
+ * Specifies Abstract Filename.
+ * This file shall be described in the Root Directory
+ * and containing a abstract statement.
+ */
+ unsigned int abstract_file:1;
+#define OPT_ABSTRACT_FILE_DEFAULT 0 /* Not specified */
+#define ABSTRACT_FILE_SIZE 37
+
+ /*
+ * Usage : application-id=<value>
+ * Type : string, max 128 bytes
+ * Default: Not specified
+ * COMPAT : mkisofs -A/-appid <value>.
+ *
+ * Specifies Application Identifier.
+ * If the first byte is set to '_'(5F), the remaining
+ * bytes of this option shall specify an identifier
+ * for a file containing the identification of the
+ * application.
+ * This file shall be described in the Root Directory.
+ */
+ unsigned int application_id:1;
+#define OPT_APPLICATION_ID_DEFAULT 0 /* Use default identifier */
+#define APPLICATION_IDENTIFIER_SIZE 128
+
+ /*
+ * Usage : !allow-vernum
+ * Type : boolean
+ * Default: Enabled
+ * : Violates the ISO9660 standard if disable.
+ * COMPAT: mkisofs -N
+ *
+ * Allow filenames to use version numbers.
+ */
+ unsigned int allow_vernum:1;
+#define OPT_ALLOW_VERNUM_DEFAULT 1 /* Enabled */
+
+ /*
+ * Usage : biblio-file=<value>
+ * Type : string, max 37 bytes
+ * Default: Not specified
+ * COMPAT : mkisofs -biblio <value>
+ *
+ * Specifies Bibliographic Filename.
+ * This file shall be described in the Root Directory
+ * and containing bibliographic records.
+ */
+ unsigned int biblio_file:1;
+#define OPT_BIBLIO_FILE_DEFAULT 0 /* Not specified */
+#define BIBLIO_FILE_SIZE 37
+
+ /*
+ * Usage : boot=<value>
+ * Type : string
+ * Default: Not specified
+ * COMPAT : mkisofs -b/-eltorito-boot <value>
+ *
+ * Specifies "El Torito" boot image file to make
+ * a bootable CD.
+ */
+ unsigned int boot:1;
+#define OPT_BOOT_DEFAULT 0 /* Not specified */
+
+ /*
+ * Usage : boot-catalog=<value>
+ * Type : string
+ * Default: "boot.catalog"
+ * COMPAT : mkisofs -c/-eltorito-catalog <value>
+ *
+ * Specifies a fullpath of El Torito boot catalog.
+ */
+ unsigned int boot_catalog:1;
+#define OPT_BOOT_CATALOG_DEFAULT 0 /* Not specified */
+
+ /*
+ * Usage : boot-info-table
+ * Type : boolean
+ * Default: Disabled
+ * COMPAT : mkisofs -boot-info-table
+ *
+ * Modify the boot image file specified by `boot'
+ * option; ISO writer stores boot file information
+ * into the boot file in ISO image at offset 8
+ * through offset 64.
+ */
+ unsigned int boot_info_table:1;
+#define OPT_BOOT_INFO_TABLE_DEFAULT 0 /* Disabled */
+
+ /*
+ * Usage : boot-load-seg=<value>
+ * Type : hexadecimal
+ * Default: Not specified
+ * COMPAT : mkisofs -boot-load-seg <value>
+ *
+ * Specifies a load segment for boot image.
+ * This is used with no-emulation mode.
+ */
+ unsigned int boot_load_seg:1;
+#define OPT_BOOT_LOAD_SEG_DEFAULT 0 /* Not specified */
+
+ /*
+ * Usage : boot-load-size=<value>
+ * Type : decimal
+ * Default: Not specified
+ * COMPAT : mkisofs -boot-load-size <value>
+ *
+ * Specifies a sector count for boot image.
+ * This is used with no-emulation mode.
+ */
+ unsigned int boot_load_size:1;
+#define OPT_BOOT_LOAD_SIZE_DEFAULT 0 /* Not specified */
+
+ /*
+ * Usage : boot-type=<boot-media-type>
+ * : 'no-emulation' : 'no emulation' image
+ * : 'fd' : floppy disk image
+ * : 'hard-disk' : hard disk image
+ * Type : string
+ * Default: Auto detect
+ * : We check a size of boot image;
+ * : If ths size is just 1.22M/1.44M/2.88M,
+ * : we assume boot_type is 'fd';
+ * : otherwise boot_type is 'no-emulation'.
+ * COMPAT :
+ * boot=no-emulation
+ * mkisofs -no-emul-boot
+ * boot=fd
+ * This is a default on the mkisofs.
+ * boot=hard-disk
+ * mkisofs -hard-disk-boot
+ *
+ * Specifies a type of "El Torito" boot image.
+ */
+ unsigned int boot_type:2;
+#define OPT_BOOT_TYPE_AUTO 0 /* auto detect */
+#define OPT_BOOT_TYPE_NO_EMU 1 /* ``no emulation'' image */
+#define OPT_BOOT_TYPE_FD 2 /* floppy disk image */
+#define OPT_BOOT_TYPE_HARD_DISK 3 /* hard disk image */
+#define OPT_BOOT_TYPE_DEFAULT OPT_BOOT_TYPE_AUTO
+
+ /*
+ * Usage : compression-level=<value>
+ * Type : decimal
+ * Default: Not specified
+ * COMPAT : NONE
+ *
+ * Specifies compression level for option zisofs=direct.
+ */
+ unsigned int compression_level:1;
+#define OPT_COMPRESSION_LEVEL_DEFAULT 0 /* Not specified */
+
+ /*
+ * Usage : copyright-file=<value>
+ * Type : string, max 37 bytes
+ * Default: Not specified
+ * COMPAT : mkisofs -copyright <value>
+ *
+ * Specifies Copyright Filename.
+ * This file shall be described in the Root Directory
+ * and containing a copyright statement.
+ */
+ unsigned int copyright_file:1;
+#define OPT_COPYRIGHT_FILE_DEFAULT 0 /* Not specified */
+#define COPYRIGHT_FILE_SIZE 37
+
+ /*
+ * Usage : gid=<value>
+ * Type : decimal
+ * Default: Not specified
+ * COMPAT : mkisofs -gid <value>
+ *
+ * Specifies a group id to rewrite the group id of all files.
+ */
+ unsigned int gid:1;
+#define OPT_GID_DEFAULT 0 /* Not specified */
+
+ /*
+ * Usage : iso-level=[1234]
+ * Type : decimal
+ * Default: 1
+ * COMPAT : mkisofs -iso-level <value>
+ *
+ * Specifies ISO9600 Level.
+ * Level 1: [DEFAULT]
+ * - limits each file size less than 4Gi bytes;
+ * - a File Name shall not contain more than eight
+ * d-characters or eight d1-characters;
+ * - a File Name Extension shall not contain more than
+ * three d-characters or three d1-characters;
+ * - a Directory Identifier shall not contain more
+ * than eight d-characters or eight d1-characters.
+ * Level 2:
+ * - limits each file size less than 4Giga bytes;
+ * - a File Name shall not contain more than thirty
+ * d-characters or thirty d1-characters;
+ * - a File Name Extension shall not contain more than
+ * thirty d-characters or thirty d1-characters;
+ * - a Directory Identifier shall not contain more
+ * than thirty-one d-characters or thirty-one
+ * d1-characters.
+ * Level 3:
+ * - no limit of file size; use multi extent.
+ * Level 4:
+ * - this level 4 simulates mkisofs option
+ * '-iso-level 4';
+ * - crate a enhanced volume as mkisofs doing;
+ * - allow a File Name to have leading dot;
+ * - allow a File Name to have all ASCII letters;
+ * - allow a File Name to have multiple dots;
+ * - allow more then 8 depths of directory trees;
+ * - disable a version number to a File Name;
+ * - disable a forced period to the tail of a File Name;
+ * - the maxinum length of files and directories is raised to 193.
+ * if rockridge option is disabled, raised to 207.
+ */
+ unsigned int iso_level:3;
+#define OPT_ISO_LEVEL_DEFAULT 1 /* ISO Level 1 */
+
+ /*
+ * Usage : joliet[=long]
+ * : !joliet
+ * : Do not generate Joliet Volume and Records.
+ * : joliet [DEFAULT]
+ * : Generates Joliet Volume and Directory Records.
+ * : [COMPAT: mkisofs -J/-joliet]
+ * : joliet=long
+ * : The joliet filenames are up to 103 Unicode
+ * : characters.
+ * : This option breaks the Joliet specification.
+ * : [COMPAT: mkisofs -J -joliet-long]
+ * Type : boolean/string
+ * Default: Enabled
+ * COMPAT : mkisofs -J / -joliet-long
+ *
+ * Generates Joliet Volume and Directory Records.
+ */
+ unsigned int joliet:2;
+#define OPT_JOLIET_DISABLE 0 /* Not generate Joliet Records. */
+#define OPT_JOLIET_ENABLE 1 /* Generate Joliet Records. */
+#define OPT_JOLIET_LONGNAME 2 /* Use long joliet filenames.*/
+#define OPT_JOLIET_DEFAULT OPT_JOLIET_ENABLE
+
+ /*
+ * Usage : !limit-depth
+ * Type : boolean
+ * Default: Enabled
+ * : Violates the ISO9660 standard if disable.
+ * COMPAT : mkisofs -D/-disable-deep-relocation
+ *
+ * The number of levels in hierarchy cannot exceed eight.
+ */
+ unsigned int limit_depth:1;
+#define OPT_LIMIT_DEPTH_DEFAULT 1 /* Enabled */
+
+ /*
+ * Usage : !limit-dirs
+ * Type : boolean
+ * Default: Enabled
+ * : Violates the ISO9660 standard if disable.
+ * COMPAT : mkisofs -no-limit-pathtables
+ *
+ * Limits the number of directories less than 65536 due
+ * to the size of the Parent Directory Number of Path
+ * Table.
+ */
+ unsigned int limit_dirs:1;
+#define OPT_LIMIT_DIRS_DEFAULT 1 /* Enabled */
+
+ /*
+ * Usage : !pad
+ * Type : boolean
+ * Default: Enabled
+ * COMPAT : -pad/-no-pad
+ *
+ * Pads the end of the ISO image by null of 300Ki bytes.
+ */
+ unsigned int pad:1;
+#define OPT_PAD_DEFAULT 1 /* Enabled */
+
+ /*
+ * Usage : publisher=<value>
+ * Type : string, max 128 bytes
+ * Default: Not specified
+ * COMPAT : mkisofs -publisher <value>
+ *
+ * Specifies Publisher Identifier.
+ * If the first byte is set to '_'(5F), the remaining
+ * bytes of this option shall specify an identifier
+ * for a file containing the identification of the user.
+ * This file shall be described in the Root Directory.
+ */
+ unsigned int publisher:1;
+#define OPT_PUBLISHER_DEFAULT 0 /* Not specified */
+#define PUBLISHER_IDENTIFIER_SIZE 128
+
+ /*
+ * Usage : rockridge
+ * : !rockridge
+ * : disable to generate SUSP and RR records.
+ * : rockridge
+ * : the same as 'rockridge=useful'.
+ * : rockridge=strict
+ * : generate SUSP and RR records.
+ * : [COMPAT: mkisofs -R]
+ * : rockridge=useful [DEFAULT]
+ * : generate SUSP and RR records.
+ * : [COMPAT: mkisofs -r]
+ * : NOTE Our rockridge=useful option does not set a zero
+ * : to uid and gid, you should use application
+ * : option such as --gid,--gname,--uid and --uname
+ * : badtar options instead.
+ * Type : boolean/string
+ * Default: Enabled as rockridge=useful
+ * COMPAT : mkisofs -r / -R
+ *
+ * Generates SUSP and RR records.
+ */
+ unsigned int rr:2;
+#define OPT_RR_DISABLED 0
+#define OPT_RR_STRICT 1
+#define OPT_RR_USEFUL 2
+#define OPT_RR_DEFAULT OPT_RR_USEFUL
+
+ /*
+ * Usage : volume-id=<value>
+ * Type : string, max 32 bytes
+ * Default: Not specified
+ * COMPAT : mkisofs -V <value>
+ *
+ * Specifies Volume Identifier.
+ */
+ unsigned int volume_id:1;
+#define OPT_VOLUME_ID_DEFAULT 0 /* Use default identifier */
+#define VOLUME_IDENTIFIER_SIZE 32
+
+ /*
+ * Usage : !zisofs [DEFAULT]
+ * : Disable to generate RRIP 'ZF' extension.
+ * : zisofs
+ * : Make files zisofs file and generate RRIP 'ZF'
+ * : extension. So you do not need mkzftree utility
+ * : for making zisofs.
+ * : When the file size is less than one Logical Block
+ * : size, that file will not zisofs'ed since it does
+ * : reduece an ISO-image size.
+ * :
+ * : When you specify option 'boot=<boot-image>', that
+ * : 'boot-image' file won't be converted to zisofs file.
+ * Type : boolean
+ * Default: Disabled
+ *
+ * Generates RRIP 'ZF' System Use Entry.
+ */
+ unsigned int zisofs:1;
+#define OPT_ZISOFS_DISABLED 0
+#define OPT_ZISOFS_DIRECT 1
+#define OPT_ZISOFS_DEFAULT OPT_ZISOFS_DISABLED
+
+};
+
+struct iso9660 {
+ /* The creation time of ISO image. */
+ time_t birth_time;
+ /* A file stream of a temporary file, which file contents
+ * save to until ISO iamge can be created. */
+ int temp_fd;
+
+ struct isofile *cur_file;
+ struct isoent *cur_dirent;
+ struct archive_string cur_dirstr;
+ uint64_t bytes_remaining;
+ int need_multi_extent;
+
+ /* Temporary string buffer for Joliet extension. */
+ struct archive_string utf16be;
+ struct archive_string mbs;
+
+ struct archive_string_conv *sconv_to_utf16be;
+ struct archive_string_conv *sconv_from_utf16be;
+
+ /* A list of all of struct isofile entries. */
+ struct {
+ struct isofile *first;
+ struct isofile **last;
+ } all_file_list;
+
+ /* A list of struct isofile entries which have its
+ * contents and are not a directory, a hardlined file
+ * and a symlink file. */
+ struct {
+ struct isofile *first;
+ struct isofile **last;
+ } data_file_list;
+
+ /* Used for managing to find hardlinking files. */
+ struct archive_rb_tree hardlink_rbtree;
+
+ /* Used for making the Path Table Record. */
+ struct vdd {
+ /* the root of entry tree. */
+ struct isoent *rootent;
+ enum vdd_type {
+ VDD_PRIMARY,
+ VDD_JOLIET,
+ VDD_ENHANCED
+ } vdd_type;
+
+ struct path_table {
+ struct isoent *first;
+ struct isoent **last;
+ struct isoent **sorted;
+ int cnt;
+ } *pathtbl;
+ int max_depth;
+
+ int path_table_block;
+ int path_table_size;
+ int location_type_L_path_table;
+ int location_type_M_path_table;
+ int total_dir_block;
+ } primary, joliet;
+
+ /* Used for making a Volume Descriptor. */
+ int volume_space_size;
+ int volume_sequence_number;
+ int total_file_block;
+ struct archive_string volume_identifier;
+ struct archive_string publisher_identifier;
+ struct archive_string data_preparer_identifier;
+ struct archive_string application_identifier;
+ struct archive_string copyright_file_identifier;
+ struct archive_string abstract_file_identifier;
+ struct archive_string bibliographic_file_identifier;
+
+ /* Used for making rockridge extensions. */
+ int location_rrip_er;
+
+ /* Used for making zisofs. */
+ struct {
+ int detect_magic:1;
+ int making:1;
+ int allzero:1;
+ unsigned char magic_buffer[64];
+ int magic_cnt;
+
+#ifdef HAVE_ZLIB_H
+ /*
+ * Copy a compressed file to iso9660.zisofs.temp_fd
+ * and also copy a uncompressed file(original file) to
+ * iso9660.temp_fd . If the number of logical block
+ * of the compressed file is less than the number of
+ * logical block of the uncompressed file, use it and
+ * remove the copy of the uncompressed file.
+ * but if not, we use uncompressed file and remove
+ * the copy of the compressed file.
+ */
+ uint32_t *block_pointers;
+ size_t block_pointers_allocated;
+ int block_pointers_cnt;
+ int block_pointers_idx;
+ int64_t total_size;
+ int64_t block_offset;
+
+ z_stream stream;
+ int stream_valid;
+ int64_t remaining;
+ int compression_level;
+#endif
+ } zisofs;
+
+ struct isoent *directories_too_deep;
+ int dircnt_max;
+
+ /* Write buffer. */
+#define wb_buffmax() (LOGICAL_BLOCK_SIZE * 32)
+#define wb_remaining(a) (((struct iso9660 *)(a)->format_data)->wbuff_remaining)
+#define wb_offset(a) (((struct iso9660 *)(a)->format_data)->wbuff_offset \
+ + wb_buffmax() - wb_remaining(a))
+ unsigned char wbuff[LOGICAL_BLOCK_SIZE * 32];
+ size_t wbuff_remaining;
+ enum {
+ WB_TO_STREAM,
+ WB_TO_TEMP
+ } wbuff_type;
+ int64_t wbuff_offset;
+ int64_t wbuff_written;
+ int64_t wbuff_tail;
+
+ /* 'El Torito' boot data. */
+ struct {
+ /* boot catalog file */
+ struct archive_string catalog_filename;
+ struct isoent *catalog;
+ /* boot image file */
+ struct archive_string boot_filename;
+ struct isoent *boot;
+
+ unsigned char platform_id;
+#define BOOT_PLATFORM_X86 0
+#define BOOT_PLATFORM_PPC 1
+#define BOOT_PLATFORM_MAC 2
+ struct archive_string id;
+ unsigned char media_type;
+#define BOOT_MEDIA_NO_EMULATION 0
+#define BOOT_MEDIA_1_2M_DISKETTE 1
+#define BOOT_MEDIA_1_44M_DISKETTE 2
+#define BOOT_MEDIA_2_88M_DISKETTE 3
+#define BOOT_MEDIA_HARD_DISK 4
+ unsigned char system_type;
+ uint16_t boot_load_seg;
+ uint16_t boot_load_size;
+#define BOOT_LOAD_SIZE 4
+ } el_torito;
+
+ struct iso_option opt;
+};
+
+/*
+ * Types of Volume Descriptor
+ */
+enum VD_type {
+ VDT_BOOT_RECORD=0, /* Boot Record Volume Descriptor */
+ VDT_PRIMARY=1, /* Primary Volume Descriptor */
+ VDT_SUPPLEMENTARY=2, /* Supplementary Volume Descriptor */
+ VDT_TERMINATOR=255 /* Volume Descriptor Set Terminator */
+};
+
+/*
+ * Types of Directory Record
+ */
+enum dir_rec_type {
+ DIR_REC_VD, /* Stored in Volume Descriptor. */
+ DIR_REC_SELF, /* Stored as Current Directory. */
+ DIR_REC_PARENT, /* Stored as Parent Directory. */
+ DIR_REC_NORMAL, /* Stored as Child. */
+};
+
+/*
+ * Kinds of Volume Descriptor Character
+ */
+enum vdc {
+ VDC_STD,
+ VDC_LOWERCASE,
+ VDC_UCS2,
+ VDC_UCS2_DIRECT,
+};
+
+/*
+ * IDentifier Resolver.
+ * Used for resolving duplicated filenames.
+ */
+struct idr {
+ struct idrent {
+ struct archive_rb_node rbnode;
+ /* Used in wait_list. */
+ struct idrent *wnext;
+ struct idrent *avail;
+
+ struct isoent *isoent;
+ int weight;
+ int noff;
+ int rename_num;
+ } *idrent_pool;
+
+ struct archive_rb_tree rbtree;
+
+ struct {
+ struct idrent *first;
+ struct idrent **last;
+ } wait_list;
+
+ int pool_size;
+ int pool_idx;
+ int num_size;
+ int null_size;
+
+ char char_map[0x80];
+};
+
+enum char_type {
+ A_CHAR,
+ D_CHAR,
+};
+
+
+static int iso9660_options(struct archive_write *,
+ const char *, const char *);
+static int iso9660_write_header(struct archive_write *,
+ struct archive_entry *);
+static ssize_t iso9660_write_data(struct archive_write *,
+ const void *, size_t);
+static int iso9660_finish_entry(struct archive_write *);
+static int iso9660_close(struct archive_write *);
+static int iso9660_free(struct archive_write *);
+
+static void get_system_identitier(char *, size_t);
+static void set_str(unsigned char *, const char *, size_t, char,
+ const char *);
+static inline int joliet_allowed_char(unsigned char, unsigned char);
+static int set_str_utf16be(struct archive_write *, unsigned char *,
+ const char *, size_t, uint16_t, enum vdc);
+static int set_str_a_characters_bp(struct archive_write *,
+ unsigned char *, int, int, const char *, enum vdc);
+static int set_str_d_characters_bp(struct archive_write *,
+ unsigned char *, int, int, const char *, enum vdc);
+static void set_VD_bp(unsigned char *, enum VD_type, unsigned char);
+static inline void set_unused_field_bp(unsigned char *, int, int);
+
+static unsigned char *extra_open_record(unsigned char *, int,
+ struct isoent *, struct ctl_extr_rec *);
+static void extra_close_record(struct ctl_extr_rec *, int);
+static unsigned char * extra_next_record(struct ctl_extr_rec *, int);
+static unsigned char *extra_get_record(struct isoent *, int *, int *, int *);
+static void extra_tell_used_size(struct ctl_extr_rec *, int);
+static int extra_setup_location(struct isoent *, int);
+static int set_directory_record_rr(unsigned char *, int,
+ struct isoent *, struct iso9660 *, enum dir_rec_type);
+static int set_directory_record(unsigned char *, size_t,
+ struct isoent *, struct iso9660 *, enum dir_rec_type,
+ enum vdd_type);
+static inline int get_dir_rec_size(struct iso9660 *, struct isoent *,
+ enum dir_rec_type, enum vdd_type);
+static inline unsigned char *wb_buffptr(struct archive_write *);
+static int wb_write_out(struct archive_write *);
+static int wb_consume(struct archive_write *, size_t);
+#ifdef HAVE_ZLIB_H
+static int wb_set_offset(struct archive_write *, int64_t);
+#endif
+static int write_null(struct archive_write *, size_t);
+static int write_VD_terminator(struct archive_write *);
+static int set_file_identifier(unsigned char *, int, int, enum vdc,
+ struct archive_write *, struct vdd *,
+ struct archive_string *, const char *, int,
+ enum char_type);
+static int write_VD(struct archive_write *, struct vdd *);
+static int write_VD_boot_record(struct archive_write *);
+static int write_information_block(struct archive_write *);
+static int write_path_table(struct archive_write *, int,
+ struct vdd *);
+static int write_directory_descriptors(struct archive_write *,
+ struct vdd *);
+static int write_file_descriptors(struct archive_write *);
+static int write_rr_ER(struct archive_write *);
+static void calculate_path_table_size(struct vdd *);
+
+static void isofile_init_entry_list(struct iso9660 *);
+static void isofile_add_entry(struct iso9660 *, struct isofile *);
+static void isofile_free_all_entries(struct iso9660 *);
+static void isofile_init_entry_data_file_list(struct iso9660 *);
+static void isofile_add_data_file(struct iso9660 *, struct isofile *);
+static struct isofile * isofile_new(struct archive_write *,
+ struct archive_entry *);
+static void isofile_free(struct isofile *);
+static int isofile_gen_utility_names(struct archive_write *,
+ struct isofile *);
+static int isofile_register_hardlink(struct archive_write *,
+ struct isofile *);
+static void isofile_connect_hardlink_files(struct iso9660 *);
+static void isofile_init_hardlinks(struct iso9660 *);
+static void isofile_free_hardlinks(struct iso9660 *);
+
+static struct isoent *isoent_new(struct isofile *);
+static int isoent_clone_tree(struct archive_write *,
+ struct isoent **, struct isoent *);
+static void _isoent_free(struct isoent *isoent);
+static void isoent_free_all(struct isoent *);
+static struct isoent * isoent_create_virtual_dir(struct archive_write *,
+ struct iso9660 *, const char *);
+static int isoent_cmp_node(const struct archive_rb_node *,
+ const struct archive_rb_node *);
+static int isoent_cmp_key(const struct archive_rb_node *,
+ const void *);
+static int isoent_add_child_head(struct isoent *, struct isoent *);
+static int isoent_add_child_tail(struct isoent *, struct isoent *);
+static void isoent_remove_child(struct isoent *, struct isoent *);
+static void isoent_setup_directory_location(struct iso9660 *,
+ int, struct vdd *);
+static void isoent_setup_file_location(struct iso9660 *, int);
+static int get_path_component(char *, int, const char *);
+static int isoent_tree(struct archive_write *, struct isoent **);
+static struct isoent *isoent_find_child(struct isoent *, const char *);
+static struct isoent *isoent_find_entry(struct isoent *, const char *);
+static void idr_relaxed_filenames(char *);
+static void idr_init(struct iso9660 *, struct vdd *, struct idr *);
+static void idr_cleanup(struct idr *);
+static int idr_ensure_poolsize(struct archive_write *, struct idr *,
+ int);
+static int idr_start(struct archive_write *, struct idr *,
+ int, int, int, int, const struct archive_rb_tree_ops *);
+static void idr_register(struct idr *, struct isoent *, int,
+ int);
+static void idr_extend_identifier(struct idrent *, int, int);
+static void idr_resolve(struct idr *, void (*)(unsigned char *, int));
+static void idr_set_num(unsigned char *, int);
+static void idr_set_num_beutf16(unsigned char *, int);
+static int isoent_gen_iso9660_identifier(struct archive_write *,
+ struct isoent *, struct idr *);
+static int isoent_gen_joliet_identifier(struct archive_write *,
+ struct isoent *, struct idr *);
+static int isoent_cmp_iso9660_identifier(const struct isoent *,
+ const struct isoent *);
+static int isoent_cmp_node_iso9660(const struct archive_rb_node *,
+ const struct archive_rb_node *);
+static int isoent_cmp_key_iso9660(const struct archive_rb_node *,
+ const void *);
+static int isoent_cmp_joliet_identifier(const struct isoent *,
+ const struct isoent *);
+static int isoent_cmp_node_joliet(const struct archive_rb_node *,
+ const struct archive_rb_node *);
+static int isoent_cmp_key_joliet(const struct archive_rb_node *,
+ const void *);
+static inline void path_table_add_entry(struct path_table *, struct isoent *);
+static inline struct isoent * path_table_last_entry(struct path_table *);
+static int isoent_make_path_table(struct archive_write *);
+static int isoent_find_out_boot_file(struct archive_write *,
+ struct isoent *);
+static int isoent_create_boot_catalog(struct archive_write *,
+ struct isoent *);
+static size_t fd_boot_image_size(int);
+static int make_boot_catalog(struct archive_write *);
+static int setup_boot_information(struct archive_write *);
+
+static int zisofs_init(struct archive_write *, struct isofile *);
+static void zisofs_detect_magic(struct archive_write *,
+ const void *, size_t);
+static int zisofs_write_to_temp(struct archive_write *,
+ const void *, size_t);
+static int zisofs_finish_entry(struct archive_write *);
+static int zisofs_rewind_boot_file(struct archive_write *);
+static int zisofs_free(struct archive_write *);
+
+int
+archive_write_set_format_iso9660(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ struct iso9660 *iso9660;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_iso9660");
+
+ /* If another format was already registered, unregister it. */
+ if (a->format_free != NULL)
+ (a->format_free)(a);
+
+ iso9660 = calloc(1, sizeof(*iso9660));
+ if (iso9660 == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate iso9660 data");
+ return (ARCHIVE_FATAL);
+ }
+ iso9660->birth_time = 0;
+ iso9660->temp_fd = -1;
+ iso9660->cur_file = NULL;
+ iso9660->primary.max_depth = 0;
+ iso9660->primary.vdd_type = VDD_PRIMARY;
+ iso9660->primary.pathtbl = NULL;
+ iso9660->joliet.rootent = NULL;
+ iso9660->joliet.max_depth = 0;
+ iso9660->joliet.vdd_type = VDD_JOLIET;
+ iso9660->joliet.pathtbl = NULL;
+ isofile_init_entry_list(iso9660);
+ isofile_init_entry_data_file_list(iso9660);
+ isofile_init_hardlinks(iso9660);
+ iso9660->directories_too_deep = NULL;
+ iso9660->dircnt_max = 1;
+ iso9660->wbuff_remaining = wb_buffmax();
+ iso9660->wbuff_type = WB_TO_TEMP;
+ iso9660->wbuff_offset = 0;
+ iso9660->wbuff_written = 0;
+ iso9660->wbuff_tail = 0;
+ archive_string_init(&(iso9660->utf16be));
+ archive_string_init(&(iso9660->mbs));
+
+ /*
+ * Init Identifiers used for PVD and SVD.
+ */
+ archive_string_init(&(iso9660->volume_identifier));
+ archive_strcpy(&(iso9660->volume_identifier), "CDROM");
+ archive_string_init(&(iso9660->publisher_identifier));
+ archive_string_init(&(iso9660->data_preparer_identifier));
+ archive_string_init(&(iso9660->application_identifier));
+ archive_strcpy(&(iso9660->application_identifier),
+ archive_version_string());
+ archive_string_init(&(iso9660->copyright_file_identifier));
+ archive_string_init(&(iso9660->abstract_file_identifier));
+ archive_string_init(&(iso9660->bibliographic_file_identifier));
+
+ /*
+ * Init El Torito bootable CD variables.
+ */
+ archive_string_init(&(iso9660->el_torito.catalog_filename));
+ iso9660->el_torito.catalog = NULL;
+ /* Set default file name of boot catalog */
+ archive_strcpy(&(iso9660->el_torito.catalog_filename),
+ "boot.catalog");
+ archive_string_init(&(iso9660->el_torito.boot_filename));
+ iso9660->el_torito.boot = NULL;
+ iso9660->el_torito.platform_id = BOOT_PLATFORM_X86;
+ archive_string_init(&(iso9660->el_torito.id));
+ iso9660->el_torito.boot_load_seg = 0;
+ iso9660->el_torito.boot_load_size = BOOT_LOAD_SIZE;
+
+ /*
+ * Init zisofs variables.
+ */
+#ifdef HAVE_ZLIB_H
+ iso9660->zisofs.block_pointers = NULL;
+ iso9660->zisofs.block_pointers_allocated = 0;
+ iso9660->zisofs.stream_valid = 0;
+ iso9660->zisofs.compression_level = 9;
+ memset(&(iso9660->zisofs.stream), 0,
+ sizeof(iso9660->zisofs.stream));
+#endif
+
+ /*
+ * Set default value of iso9660 options.
+ */
+ iso9660->opt.abstract_file = OPT_ABSTRACT_FILE_DEFAULT;
+ iso9660->opt.application_id = OPT_APPLICATION_ID_DEFAULT;
+ iso9660->opt.allow_vernum = OPT_ALLOW_VERNUM_DEFAULT;
+ iso9660->opt.biblio_file = OPT_BIBLIO_FILE_DEFAULT;
+ iso9660->opt.boot = OPT_BOOT_DEFAULT;
+ iso9660->opt.boot_catalog = OPT_BOOT_CATALOG_DEFAULT;
+ iso9660->opt.boot_info_table = OPT_BOOT_INFO_TABLE_DEFAULT;
+ iso9660->opt.boot_load_seg = OPT_BOOT_LOAD_SEG_DEFAULT;
+ iso9660->opt.boot_load_size = OPT_BOOT_LOAD_SIZE_DEFAULT;
+ iso9660->opt.boot_type = OPT_BOOT_TYPE_DEFAULT;
+ iso9660->opt.compression_level = OPT_COMPRESSION_LEVEL_DEFAULT;
+ iso9660->opt.copyright_file = OPT_COPYRIGHT_FILE_DEFAULT;
+ iso9660->opt.iso_level = OPT_ISO_LEVEL_DEFAULT;
+ iso9660->opt.joliet = OPT_JOLIET_DEFAULT;
+ iso9660->opt.limit_depth = OPT_LIMIT_DEPTH_DEFAULT;
+ iso9660->opt.limit_dirs = OPT_LIMIT_DIRS_DEFAULT;
+ iso9660->opt.pad = OPT_PAD_DEFAULT;
+ iso9660->opt.publisher = OPT_PUBLISHER_DEFAULT;
+ iso9660->opt.rr = OPT_RR_DEFAULT;
+ iso9660->opt.volume_id = OPT_VOLUME_ID_DEFAULT;
+ iso9660->opt.zisofs = OPT_ZISOFS_DEFAULT;
+
+ /* Create the root directory. */
+ iso9660->primary.rootent =
+ isoent_create_virtual_dir(a, iso9660, "");
+ if (iso9660->primary.rootent == NULL) {
+ free(iso9660);
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ iso9660->primary.rootent->parent = iso9660->primary.rootent;
+ iso9660->cur_dirent = iso9660->primary.rootent;
+ archive_string_init(&(iso9660->cur_dirstr));
+ archive_string_ensure(&(iso9660->cur_dirstr), 1);
+ iso9660->cur_dirstr.s[0] = 0;
+ iso9660->sconv_to_utf16be = NULL;
+ iso9660->sconv_from_utf16be = NULL;
+
+ a->format_data = iso9660;
+ a->format_name = "iso9660";
+ a->format_options = iso9660_options;
+ a->format_write_header = iso9660_write_header;
+ a->format_write_data = iso9660_write_data;
+ a->format_finish_entry = iso9660_finish_entry;
+ a->format_close = iso9660_close;
+ a->format_free = iso9660_free;
+ a->archive.archive_format = ARCHIVE_FORMAT_ISO9660;
+ a->archive.archive_format_name = "ISO9660";
+
+ return (ARCHIVE_OK);
+}
+
+static int
+get_str_opt(struct archive_write *a, struct archive_string *s,
+ size_t maxsize, const char *key, const char *value)
+{
+
+ if (strlen(value) > maxsize) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Value is longer than %zu characters "
+ "for option ``%s''", maxsize, key);
+ return (ARCHIVE_FATAL);
+ }
+ archive_strcpy(s, value);
+ return (ARCHIVE_OK);
+}
+
+static int
+get_num_opt(struct archive_write *a, int *num, int high, int low,
+ const char *key, const char *value)
+{
+ const char *p = value;
+ int data = 0;
+ int neg = 0;
+
+ if (p == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Invalid value(empty) for option ``%s''", key);
+ return (ARCHIVE_FATAL);
+ }
+ if (*p == '-') {
+ neg = 1;
+ p++;
+ }
+ while (*p) {
+ if (*p >= '0' && *p <= '9')
+ data = data * 10 + *p - '0';
+ else {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Invalid value for option ``%s''", key);
+ return (ARCHIVE_FATAL);
+ }
+ if (data > high) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Invalid value(over %d) for "
+ "option ``%s''", high, key);
+ return (ARCHIVE_FATAL);
+ }
+ if (data < low) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Invalid value(under %d) for "
+ "option ``%s''", low, key);
+ return (ARCHIVE_FATAL);
+ }
+ p++;
+ }
+ if (neg)
+ data *= -1;
+ *num = data;
+
+ return (ARCHIVE_OK);
+}
+
+static int
+iso9660_options(struct archive_write *a, const char *key, const char *value)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ const char *p;
+ int r;
+
+ switch (key[0]) {
+ case 'a':
+ if (strcmp(key, "abstract-file") == 0) {
+ r = get_str_opt(a,
+ &(iso9660->abstract_file_identifier),
+ ABSTRACT_FILE_SIZE, key, value);
+ iso9660->opt.abstract_file = r == ARCHIVE_OK;
+ return (r);
+ }
+ if (strcmp(key, "application-id") == 0) {
+ r = get_str_opt(a,
+ &(iso9660->application_identifier),
+ APPLICATION_IDENTIFIER_SIZE, key, value);
+ iso9660->opt.application_id = r == ARCHIVE_OK;
+ return (r);
+ }
+ if (strcmp(key, "allow-vernum") == 0) {
+ iso9660->opt.allow_vernum = value != NULL;
+ return (ARCHIVE_OK);
+ }
+ break;
+ case 'b':
+ if (strcmp(key, "biblio-file") == 0) {
+ r = get_str_opt(a,
+ &(iso9660->bibliographic_file_identifier),
+ BIBLIO_FILE_SIZE, key, value);
+ iso9660->opt.biblio_file = r == ARCHIVE_OK;
+ return (r);
+ }
+ if (strcmp(key, "boot") == 0) {
+ if (value == NULL)
+ iso9660->opt.boot = 0;
+ else {
+ iso9660->opt.boot = 1;
+ archive_strcpy(
+ &(iso9660->el_torito.boot_filename),
+ value);
+ }
+ return (ARCHIVE_OK);
+ }
+ if (strcmp(key, "boot-catalog") == 0) {
+ r = get_str_opt(a,
+ &(iso9660->el_torito.catalog_filename),
+ 1024, key, value);
+ iso9660->opt.boot_catalog = r == ARCHIVE_OK;
+ return (r);
+ }
+ if (strcmp(key, "boot-info-table") == 0) {
+ iso9660->opt.boot_info_table = value != NULL;
+ return (ARCHIVE_OK);
+ }
+ if (strcmp(key, "boot-load-seg") == 0) {
+ uint32_t seg;
+
+ iso9660->opt.boot_load_seg = 0;
+ if (value == NULL)
+ goto invalid_value;
+ seg = 0;
+ p = value;
+ if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X'))
+ p += 2;
+ while (*p) {
+ if (seg)
+ seg <<= 4;
+ if (*p >= 'A' && *p <= 'F')
+ seg += *p - 'A' + 0x0a;
+ else if (*p >= 'a' && *p <= 'f')
+ seg += *p - 'a' + 0x0a;
+ else if (*p >= '0' && *p <= '9')
+ seg += *p - '0';
+ else
+ goto invalid_value;
+ if (seg > 0xffff) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Invalid value(over 0xffff) for "
+ "option ``%s''", key);
+ return (ARCHIVE_FATAL);
+ }
+ p++;
+ }
+ iso9660->el_torito.boot_load_seg = (uint16_t)seg;
+ iso9660->opt.boot_load_seg = 1;
+ return (ARCHIVE_OK);
+ }
+ if (strcmp(key, "boot-load-size") == 0) {
+ int num = 0;
+ r = get_num_opt(a, &num, 0xffff, 1, key, value);
+ iso9660->opt.boot_load_size = r == ARCHIVE_OK;
+ if (r != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ iso9660->el_torito.boot_load_size = (uint16_t)num;
+ return (ARCHIVE_OK);
+ }
+ if (strcmp(key, "boot-type") == 0) {
+ if (value == NULL)
+ goto invalid_value;
+ if (strcmp(value, "no-emulation") == 0)
+ iso9660->opt.boot_type = OPT_BOOT_TYPE_NO_EMU;
+ else if (strcmp(value, "fd") == 0)
+ iso9660->opt.boot_type = OPT_BOOT_TYPE_FD;
+ else if (strcmp(value, "hard-disk") == 0)
+ iso9660->opt.boot_type = OPT_BOOT_TYPE_HARD_DISK;
+ else
+ goto invalid_value;
+ return (ARCHIVE_OK);
+ }
+ break;
+ case 'c':
+ if (strcmp(key, "compression-level") == 0) {
+#ifdef HAVE_ZLIB_H
+ if (value == NULL ||
+ !(value[0] >= '0' && value[0] <= '9') ||
+ value[1] != '\0')
+ goto invalid_value;
+ iso9660->zisofs.compression_level = value[0] - '0';
+ iso9660->opt.compression_level = 1;
+ return (ARCHIVE_OK);
+#else
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Option ``%s'' "
+ "is not supported on this platform.", key);
+ return (ARCHIVE_FATAL);
+#endif
+ }
+ if (strcmp(key, "copyright-file") == 0) {
+ r = get_str_opt(a,
+ &(iso9660->copyright_file_identifier),
+ COPYRIGHT_FILE_SIZE, key, value);
+ iso9660->opt.copyright_file = r == ARCHIVE_OK;
+ return (r);
+ }
+#ifdef DEBUG
+ /* Specifies Volume creation date and time;
+ * year(4),month(2),day(2),hour(2),minute(2),second(2).
+ * e.g. "20090929033757"
+ */
+ if (strcmp(key, "creation") == 0) {
+ struct tm tm;
+ char buf[5];
+
+ p = value;
+ if (p == NULL || strlen(p) < 14)
+ goto invalid_value;
+ memset(&tm, 0, sizeof(tm));
+ memcpy(buf, p, 4); buf[4] = '\0'; p += 4;
+ tm.tm_year = strtol(buf, NULL, 10) - 1900;
+ memcpy(buf, p, 2); buf[2] = '\0'; p += 2;
+ tm.tm_mon = strtol(buf, NULL, 10) - 1;
+ memcpy(buf, p, 2); buf[2] = '\0'; p += 2;
+ tm.tm_mday = strtol(buf, NULL, 10);
+ memcpy(buf, p, 2); buf[2] = '\0'; p += 2;
+ tm.tm_hour = strtol(buf, NULL, 10);
+ memcpy(buf, p, 2); buf[2] = '\0'; p += 2;
+ tm.tm_min = strtol(buf, NULL, 10);
+ memcpy(buf, p, 2); buf[2] = '\0';
+ tm.tm_sec = strtol(buf, NULL, 10);
+ iso9660->birth_time = mktime(&tm);
+ return (ARCHIVE_OK);
+ }
+#endif
+ break;
+ case 'i':
+ if (strcmp(key, "iso-level") == 0) {
+ if (value != NULL && value[1] == '\0' &&
+ (value[0] >= '1' && value[0] <= '4')) {
+ iso9660->opt.iso_level = value[0]-'0';
+ return (ARCHIVE_OK);
+ }
+ goto invalid_value;
+ }
+ break;
+ case 'j':
+ if (strcmp(key, "joliet") == 0) {
+ if (value == NULL)
+ iso9660->opt.joliet = OPT_JOLIET_DISABLE;
+ else if (strcmp(value, "1") == 0)
+ iso9660->opt.joliet = OPT_JOLIET_ENABLE;
+ else if (strcmp(value, "long") == 0)
+ iso9660->opt.joliet = OPT_JOLIET_LONGNAME;
+ else
+ goto invalid_value;
+ return (ARCHIVE_OK);
+ }
+ break;
+ case 'l':
+ if (strcmp(key, "limit-depth") == 0) {
+ iso9660->opt.limit_depth = value != NULL;
+ return (ARCHIVE_OK);
+ }
+ if (strcmp(key, "limit-dirs") == 0) {
+ iso9660->opt.limit_dirs = value != NULL;
+ return (ARCHIVE_OK);
+ }
+ break;
+ case 'p':
+ if (strcmp(key, "pad") == 0) {
+ iso9660->opt.pad = value != NULL;
+ return (ARCHIVE_OK);
+ }
+ if (strcmp(key, "publisher") == 0) {
+ r = get_str_opt(a,
+ &(iso9660->publisher_identifier),
+ PUBLISHER_IDENTIFIER_SIZE, key, value);
+ iso9660->opt.publisher = r == ARCHIVE_OK;
+ return (r);
+ }
+ break;
+ case 'r':
+ if (strcmp(key, "rockridge") == 0 ||
+ strcmp(key, "Rockridge") == 0) {
+ if (value == NULL)
+ iso9660->opt.rr = OPT_RR_DISABLED;
+ else if (strcmp(value, "1") == 0)
+ iso9660->opt.rr = OPT_RR_USEFUL;
+ else if (strcmp(value, "strict") == 0)
+ iso9660->opt.rr = OPT_RR_STRICT;
+ else if (strcmp(value, "useful") == 0)
+ iso9660->opt.rr = OPT_RR_USEFUL;
+ else
+ goto invalid_value;
+ return (ARCHIVE_OK);
+ }
+ break;
+ case 'v':
+ if (strcmp(key, "volume-id") == 0) {
+ r = get_str_opt(a, &(iso9660->volume_identifier),
+ VOLUME_IDENTIFIER_SIZE, key, value);
+ iso9660->opt.volume_id = r == ARCHIVE_OK;
+ return (r);
+ }
+ break;
+ case 'z':
+ if (strcmp(key, "zisofs") == 0) {
+ if (value == NULL)
+ iso9660->opt.zisofs = OPT_ZISOFS_DISABLED;
+ else {
+#ifdef HAVE_ZLIB_H
+ iso9660->opt.zisofs = OPT_ZISOFS_DIRECT;
+#else
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "``zisofs'' "
+ "is not supported on this platform.");
+ return (ARCHIVE_FATAL);
+#endif
+ }
+ return (ARCHIVE_OK);
+ }
+ break;
+ }
+
+invalid_value:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Invalid value for option ``%s''", key);
+ return (ARCHIVE_FAILED);
+}
+
+static int
+iso9660_write_header(struct archive_write *a, struct archive_entry *entry)
+{
+ struct iso9660 *iso9660;
+ struct isofile *file;
+ struct isoent *isoent;
+ int r, ret = ARCHIVE_OK;
+
+ iso9660 = a->format_data;
+
+ iso9660->cur_file = NULL;
+ iso9660->bytes_remaining = 0;
+ iso9660->need_multi_extent = 0;
+ if (archive_entry_filetype(entry) == AE_IFLNK
+ && iso9660->opt.rr == OPT_RR_DISABLED) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Ignore symlink file.");
+ iso9660->cur_file = NULL;
+ return (ARCHIVE_WARN);
+ }
+ if (archive_entry_filetype(entry) == AE_IFREG &&
+ archive_entry_size(entry) >= MULTI_EXTENT_SIZE) {
+ if (iso9660->opt.iso_level < 3) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Ignore over %lld bytes file. "
+ "This file too large.",
+ MULTI_EXTENT_SIZE);
+ iso9660->cur_file = NULL;
+ return (ARCHIVE_WARN);
+ }
+ iso9660->need_multi_extent = 1;
+ }
+
+ file = isofile_new(a, entry);
+ if (file == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate data");
+ return (ARCHIVE_FATAL);
+ }
+ r = isofile_gen_utility_names(a, file);
+ if (r < ARCHIVE_WARN) {
+ isofile_free(file);
+ return (r);
+ }
+ else if (r < ret)
+ ret = r;
+
+ /*
+ * Ignore a path which looks like the top of directory name
+ * since we have already made the root directory of an ISO image.
+ */
+ if (archive_strlen(&(file->parentdir)) == 0 &&
+ archive_strlen(&(file->basename)) == 0) {
+ isofile_free(file);
+ return (r);
+ }
+
+ isofile_add_entry(iso9660, file);
+ isoent = isoent_new(file);
+ if (isoent == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate data");
+ return (ARCHIVE_FATAL);
+ }
+ if (isoent->file->dircnt > iso9660->dircnt_max)
+ iso9660->dircnt_max = isoent->file->dircnt;
+
+ /* Add the current file into tree */
+ r = isoent_tree(a, &isoent);
+ if (r != ARCHIVE_OK)
+ return (r);
+
+ /* If there is the same file in tree and
+ * the current file is older than the file in tree.
+ * So we don't need the current file data anymore. */
+ if (isoent->file != file)
+ return (ARCHIVE_OK);
+
+ /* Non regular files contents are unneeded to be saved to
+ * temporary files. */
+ if (archive_entry_filetype(file->entry) != AE_IFREG)
+ return (ret);
+
+ /*
+ * Set the current file to cur_file to read its contents.
+ */
+ iso9660->cur_file = file;
+
+ if (archive_entry_nlink(file->entry) > 1) {
+ r = isofile_register_hardlink(a, file);
+ if (r != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+
+ /*
+ * Prepare to save the contents of the file.
+ */
+ if (iso9660->temp_fd < 0) {
+ iso9660->temp_fd = __archive_mktemp(NULL);
+ if (iso9660->temp_fd < 0) {
+ archive_set_error(&a->archive, errno,
+ "Couldn't create temporary file");
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ /* Save an offset of current file in temporary file. */
+ file->content.offset_of_temp = wb_offset(a);
+ file->cur_content = &(file->content);
+ r = zisofs_init(a, file);
+ if (r < ret)
+ ret = r;
+ iso9660->bytes_remaining = archive_entry_size(file->entry);
+
+ return (ret);
+}
+
+static int
+write_to_temp(struct archive_write *a, const void *buff, size_t s)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ ssize_t written;
+ const unsigned char *b;
+
+ b = (const unsigned char *)buff;
+ while (s) {
+ written = write(iso9660->temp_fd, b, s);
+ if (written < 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't write to temporary file");
+ return (ARCHIVE_FATAL);
+ }
+ s -= written;
+ b += written;
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+wb_write_to_temp(struct archive_write *a, const void *buff, size_t s)
+{
+ const char *xp = buff;
+ size_t xs = s;
+
+ /*
+ * If a written data size is big enough to use system-call
+ * and there is no waiting data, this calls write_to_temp() in
+ * order to reduce a extra memory copy.
+ */
+ if (wb_remaining(a) == wb_buffmax() && s > (1024 * 16)) {
+ struct iso9660 *iso9660 = (struct iso9660 *)a->format_data;
+ xs = s % LOGICAL_BLOCK_SIZE;
+ iso9660->wbuff_offset += s - xs;
+ if (write_to_temp(a, buff, s - xs) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ if (xs == 0)
+ return (ARCHIVE_OK);
+ xp += s - xs;
+ }
+
+ while (xs) {
+ size_t size = xs;
+ if (size > wb_remaining(a))
+ size = wb_remaining(a);
+ memcpy(wb_buffptr(a), xp, size);
+ if (wb_consume(a, size) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ xs -= size;
+ xp += size;
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+wb_write_padding_to_temp(struct archive_write *a, int64_t csize)
+{
+ size_t ns;
+ int ret;
+
+ ns = csize % LOGICAL_BLOCK_SIZE;
+ if (ns != 0)
+ ret = write_null(a, LOGICAL_BLOCK_SIZE - ns);
+ else
+ ret = ARCHIVE_OK;
+ return (ret);
+}
+
+static ssize_t
+write_iso9660_data(struct archive_write *a, const void *buff, size_t s)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ size_t ws;
+
+ if (iso9660->temp_fd < 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Couldn't create temporary file");
+ return (ARCHIVE_FATAL);
+ }
+
+ ws = s;
+ if (iso9660->need_multi_extent &&
+ (iso9660->cur_file->cur_content->size + ws) >=
+ (MULTI_EXTENT_SIZE - LOGICAL_BLOCK_SIZE)) {
+ struct content *con;
+ size_t ts;
+
+ ts = MULTI_EXTENT_SIZE - LOGICAL_BLOCK_SIZE -
+ iso9660->cur_file->cur_content->size;
+
+ if (iso9660->zisofs.detect_magic)
+ zisofs_detect_magic(a, buff, ts);
+
+ if (iso9660->zisofs.making) {
+ if (zisofs_write_to_temp(a, buff, ts) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ } else {
+ if (wb_write_to_temp(a, buff, ts) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ iso9660->cur_file->cur_content->size += ts;
+ }
+
+ /* Write padding. */
+ if (wb_write_padding_to_temp(a,
+ iso9660->cur_file->cur_content->size) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /* Compute the logical block number. */
+ iso9660->cur_file->cur_content->blocks =
+ (iso9660->cur_file->cur_content->size
+ + LOGICAL_BLOCK_SIZE -1) >> LOGICAL_BLOCK_BITS;
+
+ /*
+ * Make next extent.
+ */
+ ws -= ts;
+ buff = (const void *)(((const unsigned char *)buff) + ts);
+ /* Make a content for next extent. */
+ con = calloc(1, sizeof(*con));
+ if (con == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate content data");
+ return (ARCHIVE_FATAL);
+ }
+ con->offset_of_temp = wb_offset(a);
+ iso9660->cur_file->cur_content->next = con;
+ iso9660->cur_file->cur_content = con;
+#ifdef HAVE_ZLIB_H
+ iso9660->zisofs.block_offset = 0;
+#endif
+ }
+
+ if (iso9660->zisofs.detect_magic)
+ zisofs_detect_magic(a, buff, ws);
+
+ if (iso9660->zisofs.making) {
+ if (zisofs_write_to_temp(a, buff, ws) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ } else {
+ if (wb_write_to_temp(a, buff, ws) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ iso9660->cur_file->cur_content->size += ws;
+ }
+
+ return (s);
+}
+
+static ssize_t
+iso9660_write_data(struct archive_write *a, const void *buff, size_t s)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ ssize_t r;
+
+ if (iso9660->cur_file == NULL)
+ return (0);
+ if (archive_entry_filetype(iso9660->cur_file->entry) != AE_IFREG)
+ return (0);
+ if (s > iso9660->bytes_remaining)
+ s = iso9660->bytes_remaining;
+ if (s == 0)
+ return (0);
+
+ r = write_iso9660_data(a, buff, s);
+ if (r > 0)
+ iso9660->bytes_remaining -= r;
+ return (r);
+}
+
+static int
+iso9660_finish_entry(struct archive_write *a)
+{
+ struct iso9660 *iso9660 = a->format_data;
+
+ if (iso9660->cur_file == NULL)
+ return (ARCHIVE_OK);
+ if (archive_entry_filetype(iso9660->cur_file->entry) != AE_IFREG)
+ return (ARCHIVE_OK);
+ if (iso9660->cur_file->content.size == 0)
+ return (ARCHIVE_OK);
+
+ /* If there are unwritten data, write null data instead. */
+ while (iso9660->bytes_remaining > 0) {
+ size_t s;
+
+ s = (iso9660->bytes_remaining > a->null_length)?
+ a->null_length: (size_t)iso9660->bytes_remaining;
+ if (write_iso9660_data(a, a->nulls, s) < 0)
+ return (ARCHIVE_FATAL);
+ iso9660->bytes_remaining -= s;
+ }
+
+ if (iso9660->zisofs.making && zisofs_finish_entry(a) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /* Write padding. */
+ if (wb_write_padding_to_temp(a, iso9660->cur_file->cur_content->size)
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /* Compute the logical block number. */
+ iso9660->cur_file->cur_content->blocks =
+ (iso9660->cur_file->cur_content->size
+ + LOGICAL_BLOCK_SIZE -1) >> LOGICAL_BLOCK_BITS;
+
+ /* Add the current file to data file list. */
+ isofile_add_data_file(iso9660, iso9660->cur_file);
+
+ return (ARCHIVE_OK);
+}
+
+static int
+iso9660_close(struct archive_write *a)
+{
+ struct iso9660 *iso9660;
+ int ret, blocks;
+
+ iso9660 = a->format_data;
+
+ /*
+ * Write remaining data out to the temporary file.
+ */
+ if (wb_remaining(a) > 0) {
+ ret = wb_write_out(a);
+ if (ret < 0)
+ return (ret);
+ }
+
+ /*
+ * Preparations...
+ */
+#ifdef DEBUG
+ if (iso9660->birth_time == 0)
+#endif
+ time(&(iso9660->birth_time));
+
+ /*
+ * Prepare a bootable ISO image.
+ */
+ if (iso9660->opt.boot) {
+ /* Find out the boot file entry. */
+ ret = isoent_find_out_boot_file(a, iso9660->primary.rootent);
+ if (ret < 0)
+ return (ret);
+ /* Reconvert the boot file from zisofs'ed form to
+ * plain form. */
+ ret = zisofs_rewind_boot_file(a);
+ if (ret < 0)
+ return (ret);
+ /* Write remaining data out to the temporary file. */
+ if (wb_remaining(a) > 0) {
+ ret = wb_write_out(a);
+ if (ret < 0)
+ return (ret);
+ }
+ /* Create the boot catalog. */
+ ret = isoent_create_boot_catalog(a, iso9660->primary.rootent);
+ if (ret < 0)
+ return (ret);
+ }
+
+ /*
+ * Prepare joliet extensions.
+ */
+ if (iso9660->opt.joliet) {
+ /* Make a new tree for joliet. */
+ ret = isoent_clone_tree(a, &(iso9660->joliet.rootent),
+ iso9660->primary.rootent);
+ if (ret < 0)
+ return (ret);
+ /* Make sure we have UTF-16BE convertors.
+ * if there is no file entry, convertors are still
+ * uninitilized. */
+ if (iso9660->sconv_to_utf16be == NULL) {
+ iso9660->sconv_to_utf16be =
+ archive_string_conversion_to_charset(
+ &(a->archive), "UTF-16BE", 1);
+ if (iso9660->sconv_to_utf16be == NULL)
+ /* Couldn't allocate memory */
+ return (ARCHIVE_FATAL);
+ iso9660->sconv_from_utf16be =
+ archive_string_conversion_from_charset(
+ &(a->archive), "UTF-16BE", 1);
+ if (iso9660->sconv_from_utf16be == NULL)
+ /* Couldn't allocate memory */
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ /*
+ * Make Path Tables.
+ */
+ ret = isoent_make_path_table(a);
+ if (ret < 0)
+ return (ret);
+
+ /*
+ * Calculate a total volume size and setup all locations of
+ * contents of an iso9660 image.
+ */
+ blocks = SYSTEM_AREA_BLOCK
+ + PRIMARY_VOLUME_DESCRIPTOR_BLOCK
+ + VOLUME_DESCRIPTOR_SET_TERMINATOR_BLOCK
+ + NON_ISO_FILE_SYSTEM_INFORMATION_BLOCK;
+ if (iso9660->opt.boot)
+ blocks += BOOT_RECORD_DESCRIPTOR_BLOCK;
+ if (iso9660->opt.joliet)
+ blocks += SUPPLEMENTARY_VOLUME_DESCRIPTOR_BLOCK;
+ if (iso9660->opt.iso_level == 4)
+ blocks += SUPPLEMENTARY_VOLUME_DESCRIPTOR_BLOCK;
+
+ /* Setup the locations of Path Table. */
+ iso9660->primary.location_type_L_path_table = blocks;
+ blocks += iso9660->primary.path_table_block;
+ iso9660->primary.location_type_M_path_table = blocks;
+ blocks += iso9660->primary.path_table_block;
+ if (iso9660->opt.joliet) {
+ iso9660->joliet.location_type_L_path_table = blocks;
+ blocks += iso9660->joliet.path_table_block;
+ iso9660->joliet.location_type_M_path_table = blocks;
+ blocks += iso9660->joliet.path_table_block;
+ }
+
+ /* Setup the locations of directories. */
+ isoent_setup_directory_location(iso9660, blocks,
+ &(iso9660->primary));
+ blocks += iso9660->primary.total_dir_block;
+ if (iso9660->opt.joliet) {
+ isoent_setup_directory_location(iso9660, blocks,
+ &(iso9660->joliet));
+ blocks += iso9660->joliet.total_dir_block;
+ }
+
+ if (iso9660->opt.rr) {
+ iso9660->location_rrip_er = blocks;
+ blocks += RRIP_ER_BLOCK;
+ }
+
+ /* Setup the locations of all file contents. */
+ isoent_setup_file_location(iso9660, blocks);
+ blocks += iso9660->total_file_block;
+ if (iso9660->opt.boot && iso9660->opt.boot_info_table) {
+ ret = setup_boot_information(a);
+ if (ret < 0)
+ return (ret);
+ }
+
+ /* Now we have a total volume size. */
+ iso9660->volume_space_size = blocks;
+ if (iso9660->opt.pad)
+ iso9660->volume_space_size += PADDING_BLOCK;
+ iso9660->volume_sequence_number = 1;
+
+
+ /*
+ * Write an ISO 9660 image.
+ */
+
+ /* Switc to start using wbuff as file buffer. */
+ iso9660->wbuff_remaining = wb_buffmax();
+ iso9660->wbuff_type = WB_TO_STREAM;
+ iso9660->wbuff_offset = 0;
+ iso9660->wbuff_written = 0;
+ iso9660->wbuff_tail = 0;
+
+ /* Write The System Area */
+ ret = write_null(a, SYSTEM_AREA_BLOCK * LOGICAL_BLOCK_SIZE);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /* Write Primary Volume Descriptor */
+ ret = write_VD(a, &(iso9660->primary));
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ if (iso9660->opt.boot) {
+ /* Write Boot Record Volume Descriptor */
+ ret = write_VD_boot_record(a);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+
+ if (iso9660->opt.iso_level == 4) {
+ /* Write Enhanced Volume Descriptor */
+ iso9660->primary.vdd_type = VDD_ENHANCED;
+ ret = write_VD(a, &(iso9660->primary));
+ iso9660->primary.vdd_type = VDD_PRIMARY;
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+
+ if (iso9660->opt.joliet) {
+ ret = write_VD(a, &(iso9660->joliet));
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+
+ /* Write Volume Descriptor Set Terminator */
+ ret = write_VD_terminator(a);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /* Write Non-ISO File System Information */
+ ret = write_information_block(a);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /* Write Type L Path Table */
+ ret = write_path_table(a, 0, &(iso9660->primary));
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /* Write Type M Path Table */
+ ret = write_path_table(a, 1, &(iso9660->primary));
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ if (iso9660->opt.joliet) {
+ /* Write Type L Path Table */
+ ret = write_path_table(a, 0, &(iso9660->joliet));
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /* Write Type M Path Table */
+ ret = write_path_table(a, 1, &(iso9660->joliet));
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+
+ /* Write Directory Descriptors */
+ ret = write_directory_descriptors(a, &(iso9660->primary));
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ if (iso9660->opt.joliet) {
+ ret = write_directory_descriptors(a, &(iso9660->joliet));
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+
+ if (iso9660->opt.rr) {
+ /* Write Rockridge ER(Extensions Reference) */
+ ret = write_rr_ER(a);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+
+ /* Write File Descriptors */
+ ret = write_file_descriptors(a);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /* Write Padding */
+ if (iso9660->opt.pad) {
+ ret = write_null(a, PADDING_BLOCK * LOGICAL_BLOCK_SIZE);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+
+ if (iso9660->directories_too_deep != NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "%s: Directories too deep.",
+ archive_entry_pathname(
+ iso9660->directories_too_deep->file->entry));
+ return (ARCHIVE_WARN);
+ }
+
+ /* Write remaining data out. */
+ ret = wb_write_out(a);
+
+ return (ret);
+}
+
+static int
+iso9660_free(struct archive_write *a)
+{
+ struct iso9660 *iso9660;
+ int i, ret;
+
+ iso9660 = a->format_data;
+
+ /* Close the temporary file. */
+ if (iso9660->temp_fd >= 0)
+ close(iso9660->temp_fd);
+
+ /* Free some stuff for zisofs operations. */
+ ret = zisofs_free(a);
+
+ /* Remove directory entries in tree which includes file entries. */
+ isoent_free_all(iso9660->primary.rootent);
+ for (i = 0; i < iso9660->primary.max_depth; i++)
+ free(iso9660->primary.pathtbl[i].sorted);
+ free(iso9660->primary.pathtbl);
+
+ if (iso9660->opt.joliet) {
+ isoent_free_all(iso9660->joliet.rootent);
+ for (i = 0; i < iso9660->joliet.max_depth; i++)
+ free(iso9660->joliet.pathtbl[i].sorted);
+ free(iso9660->joliet.pathtbl);
+ }
+
+ /* Remove isofile entries. */
+ isofile_free_all_entries(iso9660);
+ isofile_free_hardlinks(iso9660);
+
+ archive_string_free(&(iso9660->cur_dirstr));
+ archive_string_free(&(iso9660->volume_identifier));
+ archive_string_free(&(iso9660->publisher_identifier));
+ archive_string_free(&(iso9660->data_preparer_identifier));
+ archive_string_free(&(iso9660->application_identifier));
+ archive_string_free(&(iso9660->copyright_file_identifier));
+ archive_string_free(&(iso9660->abstract_file_identifier));
+ archive_string_free(&(iso9660->bibliographic_file_identifier));
+ archive_string_free(&(iso9660->el_torito.catalog_filename));
+ archive_string_free(&(iso9660->el_torito.boot_filename));
+ archive_string_free(&(iso9660->el_torito.id));
+ archive_string_free(&(iso9660->utf16be));
+ archive_string_free(&(iso9660->mbs));
+
+ free(iso9660);
+ a->format_data = NULL;
+
+ return (ret);
+}
+
+/*
+ * Get the System Identifier
+ */
+static void
+get_system_identitier(char *system_id, size_t size)
+{
+#if defined(HAVE_SYS_UTSNAME_H)
+ struct utsname u;
+
+ uname(&u);
+ strncpy(system_id, u.sysname, size-1);
+ system_id[size-1] = '\0';
+#elif defined(_WIN32) && !defined(__CYGWIN__)
+ strncpy(system_id, "Windows", size-1);
+ system_id[size-1] = '\0';
+#else
+#error no way to get the system identifier on your platform.
+#endif
+}
+
+static void
+set_str(unsigned char *p, const char *s, size_t l, char f, const char *map)
+{
+ unsigned char c;
+
+ if (s == NULL)
+ s = "";
+ while ((c = *s++) != 0 && l > 0) {
+ if (c >= 0x80 || map[c] == 0)
+ {
+ /* illegal character */
+ if (c >= 'a' && c <= 'z') {
+ /* convert c from a-z to A-Z */
+ c -= 0x20;
+ } else
+ c = 0x5f;
+ }
+ *p++ = c;
+ l--;
+ }
+ /* If l isn't zero, fill p buffer by the character
+ * which indicated by f. */
+ if (l > 0)
+ memset(p , f, l);
+}
+
+static inline int
+joliet_allowed_char(unsigned char high, unsigned char low)
+{
+ int utf16 = (high << 8) | low;
+
+ if (utf16 <= 0x001F)
+ return (0);
+
+ switch (utf16) {
+ case 0x002A: /* '*' */
+ case 0x002F: /* '/' */
+ case 0x003A: /* ':' */
+ case 0x003B: /* ';' */
+ case 0x003F: /* '?' */
+ case 0x005C: /* '\' */
+ return (0);/* Not allowed. */
+ }
+ return (1);
+}
+
+static int
+set_str_utf16be(struct archive_write *a, unsigned char *p, const char *s,
+ size_t l, uint16_t uf, enum vdc vdc)
+{
+ size_t size, i;
+ int onepad;
+
+ if (s == NULL)
+ s = "";
+ if (l & 0x01) {
+ onepad = 1;
+ l &= ~1;
+ } else
+ onepad = 0;
+ if (vdc == VDC_UCS2) {
+ struct iso9660 *iso9660 = a->format_data;
+ if (archive_strncpy_in_locale(&iso9660->utf16be, s, strlen(s),
+ iso9660->sconv_to_utf16be) != 0 && errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for UTF-16BE");
+ return (ARCHIVE_FATAL);
+ }
+ size = iso9660->utf16be.length;
+ if (size > l)
+ size = l;
+ memcpy(p, iso9660->utf16be.s, size);
+ } else {
+ const uint16_t *u16 = (const uint16_t *)s;
+
+ size = 0;
+ while (*u16++)
+ size += 2;
+ if (size > l)
+ size = l;
+ memcpy(p, s, size);
+ }
+ for (i = 0; i < size; i += 2, p += 2) {
+ if (!joliet_allowed_char(p[0], p[1]))
+ archive_be16enc(p, 0x005F);/* '_' */
+ }
+ l -= size;
+ while (l > 0) {
+ archive_be16enc(p, uf);
+ p += 2;
+ l -= 2;
+ }
+ if (onepad)
+ *p = 0;
+ return (ARCHIVE_OK);
+}
+
+static const char a_characters_map[0x80] = {
+/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 00-0F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 10-1F */
+ 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 20-2F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 30-3F */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40-4F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,/* 50-5F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 60-6F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 70-7F */
+};
+
+static const char a1_characters_map[0x80] = {
+/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 00-0F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 10-1F */
+ 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 20-2F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 30-3F */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40-4F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,/* 50-5F */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 60-6F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,/* 70-7F */
+};
+
+static const char d_characters_map[0x80] = {
+/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 00-0F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 10-1F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 20-2F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,/* 30-3F */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40-4F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,/* 50-5F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 60-6F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 70-7F */
+};
+
+static const char d1_characters_map[0x80] = {
+/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 00-0F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 10-1F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 20-2F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,/* 30-3F */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40-4F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,/* 50-5F */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 60-6F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,/* 70-7F */
+};
+
+static int
+set_str_a_characters_bp(struct archive_write *a, unsigned char *bp,
+ int from, int to, const char *s, enum vdc vdc)
+{
+ int r;
+
+ switch (vdc) {
+ case VDC_STD:
+ set_str(bp+from, s, to - from + 1, 0x20,
+ a_characters_map);
+ r = ARCHIVE_OK;
+ break;
+ case VDC_LOWERCASE:
+ set_str(bp+from, s, to - from + 1, 0x20,
+ a1_characters_map);
+ r = ARCHIVE_OK;
+ break;
+ case VDC_UCS2:
+ case VDC_UCS2_DIRECT:
+ r = set_str_utf16be(a, bp+from, s, to - from + 1,
+ 0x0020, vdc);
+ break;
+ default:
+ r = ARCHIVE_FATAL;
+ }
+ return (r);
+}
+
+static int
+set_str_d_characters_bp(struct archive_write *a, unsigned char *bp,
+ int from, int to, const char *s, enum vdc vdc)
+{
+ int r;
+
+ switch (vdc) {
+ case VDC_STD:
+ set_str(bp+from, s, to - from + 1, 0x20,
+ d_characters_map);
+ r = ARCHIVE_OK;
+ break;
+ case VDC_LOWERCASE:
+ set_str(bp+from, s, to - from + 1, 0x20,
+ d1_characters_map);
+ r = ARCHIVE_OK;
+ break;
+ case VDC_UCS2:
+ case VDC_UCS2_DIRECT:
+ r = set_str_utf16be(a, bp+from, s, to - from + 1,
+ 0x0020, vdc);
+ break;
+ default:
+ r = ARCHIVE_FATAL;
+ }
+ return (r);
+}
+
+static void
+set_VD_bp(unsigned char *bp, enum VD_type type, unsigned char ver)
+{
+
+ /* Volume Descriptor Type */
+ bp[1] = (unsigned char)type;
+ /* Standard Identifier */
+ memcpy(bp + 2, "CD001", 5);
+ /* Volume Descriptor Version */
+ bp[7] = ver;
+}
+
+static inline void
+set_unused_field_bp(unsigned char *bp, int from, int to)
+{
+ memset(bp + from, 0, to - from + 1);
+}
+
+/*
+ * 8-bit unsigned numerical values.
+ * ISO9660 Standard 7.1.1
+ */
+static inline void
+set_num_711(unsigned char *p, unsigned char value)
+{
+ *p = value;
+}
+
+/*
+ * 8-bit signed numerical values.
+ * ISO9660 Standard 7.1.2
+ */
+static inline void
+set_num_712(unsigned char *p, char value)
+{
+ *((char *)p) = value;
+}
+
+/*
+ * Least significant byte first.
+ * ISO9660 Standard 7.2.1
+ */
+static inline void
+set_num_721(unsigned char *p, uint16_t value)
+{
+ archive_le16enc(p, value);
+}
+
+/*
+ * Most significant byte first.
+ * ISO9660 Standard 7.2.2
+ */
+static inline void
+set_num_722(unsigned char *p, uint16_t value)
+{
+ archive_be16enc(p, value);
+}
+
+/*
+ * Both-byte orders.
+ * ISO9660 Standard 7.2.3
+ */
+static void
+set_num_723(unsigned char *p, uint16_t value)
+{
+ archive_le16enc(p, value);
+ archive_be16enc(p+2, value);
+}
+
+/*
+ * Least significant byte first.
+ * ISO9660 Standard 7.3.1
+ */
+static inline void
+set_num_731(unsigned char *p, uint32_t value)
+{
+ archive_le32enc(p, value);
+}
+
+/*
+ * Most significant byte first.
+ * ISO9660 Standard 7.3.2
+ */
+static inline void
+set_num_732(unsigned char *p, uint32_t value)
+{
+ archive_be32enc(p, value);
+}
+
+/*
+ * Both-byte orders.
+ * ISO9660 Standard 7.3.3
+ */
+static inline void
+set_num_733(unsigned char *p, uint32_t value)
+{
+ archive_le32enc(p, value);
+ archive_be32enc(p+4, value);
+}
+
+static void
+set_digit(unsigned char *p, size_t s, int value)
+{
+
+ while (s--) {
+ p[s] = '0' + (value % 10);
+ value /= 10;
+ }
+}
+
+#if defined(HAVE_STRUCT_TM_TM_GMTOFF)
+#define get_gmoffset(tm) ((tm)->tm_gmtoff)
+#elif defined(HAVE_STRUCT_TM___TM_GMTOFF)
+#define get_gmoffset(tm) ((tm)->__tm_gmtoff)
+#else
+static long
+get_gmoffset(struct tm *tm)
+{
+ long offset;
+
+#if defined(HAVE__GET_TIMEZONE)
+ _get_timezone(&offset);
+#elif defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__)
+ offset = _timezone;
+#else
+ offset = timezone;
+#endif
+ offset *= -1;
+ if (tm->tm_isdst)
+ offset += 3600;
+ return (offset);
+}
+#endif
+
+static void
+get_tmfromtime(struct tm *tm, time_t *t)
+{
+#if HAVE_LOCALTIME_R
+ tzset();
+ localtime_r(t, tm);
+#elif HAVE__LOCALTIME64_S
+ _localtime64_s(tm, t);
+#else
+ memcpy(tm, localtime(t), sizeof(*tm));
+#endif
+}
+
+/*
+ * Date and Time Format.
+ * ISO9660 Standard 8.4.26.1
+ */
+static void
+set_date_time(unsigned char *p, time_t t)
+{
+ struct tm tm;
+
+ get_tmfromtime(&tm, &t);
+ set_digit(p, 4, tm.tm_year + 1900);
+ set_digit(p+4, 2, tm.tm_mon + 1);
+ set_digit(p+6, 2, tm.tm_mday);
+ set_digit(p+8, 2, tm.tm_hour);
+ set_digit(p+10, 2, tm.tm_min);
+ set_digit(p+12, 2, tm.tm_sec);
+ set_digit(p+14, 2, 0);
+ set_num_712(p+16, get_gmoffset(&tm)/(60*15));
+}
+
+static void
+set_date_time_null(unsigned char *p)
+{
+ memset(p, '0', 16);
+ p[16] = 0;
+}
+
+static void
+set_time_915(unsigned char *p, time_t t)
+{
+ struct tm tm;
+
+ get_tmfromtime(&tm, &t);
+ set_num_711(p+0, tm.tm_year);
+ set_num_711(p+1, tm.tm_mon+1);
+ set_num_711(p+2, tm.tm_mday);
+ set_num_711(p+3, tm.tm_hour);
+ set_num_711(p+4, tm.tm_min);
+ set_num_711(p+5, tm.tm_sec);
+ set_num_712(p+6, get_gmoffset(&tm)/(60*15));
+}
+
+
+/*
+ * Write SUSP "CE" System Use Entry.
+ */
+static int
+set_SUSP_CE(unsigned char *p, int location, int offset, int size)
+{
+ unsigned char *bp = p -1;
+ /* Extend the System Use Area
+ * "CE" Format:
+ * len ver
+ * +----+----+----+----+-----------+-----------+
+ * | 'C'| 'E'| 1C | 01 | LOCATION1 | LOCATION2 |
+ * +----+----+----+----+-----------+-----------+
+ * 0 1 2 3 4 12 20
+ * +-----------+
+ * | LOCATION3 |
+ * +-----------+
+ * 20 28
+ * LOCATION1 : Location of Continuation of System Use Area.
+ * LOCATION2 : Offset to Start of Continuation.
+ * LOCATION3 : Length of the Continuation.
+ */
+
+ bp[1] = 'C';
+ bp[2] = 'E';
+ bp[3] = RR_CE_SIZE; /* length */
+ bp[4] = 1; /* version */
+ set_num_733(bp+5, location);
+ set_num_733(bp+13, offset);
+ set_num_733(bp+21, size);
+ return (RR_CE_SIZE);
+}
+
+/*
+ * The functions, which names are beginning with extra_, are used to
+ * control extra records.
+ * The maximum size of a Directory Record is 254. When a filename is
+ * very long, all of RRIP data of a file won't stored to the Directory
+ * Record and so remaining RRIP data store to an extra record instead.
+ */
+static unsigned char *
+extra_open_record(unsigned char *bp, int dr_len, struct isoent *isoent,
+ struct ctl_extr_rec *ctl)
+{
+ ctl->bp = bp;
+ if (bp != NULL)
+ bp += dr_len;
+ ctl->use_extr = 0;
+ ctl->isoent = isoent;
+ ctl->ce_ptr = NULL;
+ ctl->cur_len = ctl->dr_len = dr_len;
+ ctl->limit = DR_LIMIT;
+
+ return (bp);
+}
+
+static void
+extra_close_record(struct ctl_extr_rec *ctl, int ce_size)
+{
+ int padding = 0;
+
+ if (ce_size > 0)
+ extra_tell_used_size(ctl, ce_size);
+ /* Padding. */
+ if (ctl->cur_len & 0x01) {
+ ctl->cur_len++;
+ if (ctl->bp != NULL)
+ ctl->bp[ctl->cur_len] = 0;
+ padding = 1;
+ }
+ if (ctl->use_extr) {
+ if (ctl->ce_ptr != NULL)
+ set_SUSP_CE(ctl->ce_ptr, ctl->extr_loc,
+ ctl->extr_off, ctl->cur_len - padding);
+ } else
+ ctl->dr_len = ctl->cur_len;
+}
+
+#define extra_space(ctl) ((ctl)->limit - (ctl)->cur_len)
+
+static unsigned char *
+extra_next_record(struct ctl_extr_rec *ctl, int length)
+{
+ int cur_len = ctl->cur_len;/* save cur_len */
+
+ /* Close the current extra record or Directory Record. */
+ extra_close_record(ctl, RR_CE_SIZE);
+
+ /* Get a next extra record. */
+ ctl->use_extr = 1;
+ if (ctl->bp != NULL) {
+ /* Storing data into an extra record. */
+ unsigned char *p;
+
+ /* Save the pointer where a CE extension will be
+ * stored to. */
+ ctl->ce_ptr = &ctl->bp[cur_len+1];
+ p = extra_get_record(ctl->isoent,
+ &ctl->limit, &ctl->extr_off, &ctl->extr_loc);
+ ctl->bp = p - 1;/* the base of bp offset is 1. */
+ } else
+ /* Calculating the size of an extra record. */
+ (void)extra_get_record(ctl->isoent,
+ &ctl->limit, NULL, NULL);
+ ctl->cur_len = 0;
+ /* Check if an extra record is almost full.
+ * If so, get a next one. */
+ if (extra_space(ctl) < length)
+ (void)extra_next_record(ctl, length);
+
+ return (ctl->bp);
+}
+
+static inline struct extr_rec *
+extra_last_record(struct isoent *isoent)
+{
+ if (isoent->extr_rec_list.first == NULL)
+ return (NULL);
+ return ((struct extr_rec *)(void *)
+ ((char *)(isoent->extr_rec_list.last)
+ - offsetof(struct extr_rec, next)));
+}
+
+static unsigned char *
+extra_get_record(struct isoent *isoent, int *space, int *off, int *loc)
+{
+ struct extr_rec *rec;
+
+ isoent = isoent->parent;
+ if (off != NULL) {
+ /* Storing data into an extra record. */
+ rec = isoent->extr_rec_list.current;
+ if (DR_SAFETY > LOGICAL_BLOCK_SIZE - rec->offset)
+ rec = rec->next;
+ } else {
+ /* Calculating the size of an extra record. */
+ rec = extra_last_record(isoent);
+ if (rec == NULL ||
+ DR_SAFETY > LOGICAL_BLOCK_SIZE - rec->offset) {
+ rec = malloc(sizeof(*rec));
+ if (rec == NULL)
+ return (NULL);
+ rec->location = 0;
+ rec->offset = 0;
+ /* Insert `rec` into the tail of isoent->extr_rec_list */
+ rec->next = NULL;
+ *isoent->extr_rec_list.last = rec;
+ isoent->extr_rec_list.last = &(rec->next);
+ }
+ }
+ *space = LOGICAL_BLOCK_SIZE - rec->offset - DR_SAFETY;
+ if (*space & 0x01)
+ *space -= 1;/* Keep padding space. */
+ if (off != NULL)
+ *off = rec->offset;
+ if (loc != NULL)
+ *loc = rec->location;
+ isoent->extr_rec_list.current = rec;
+
+ return (&rec->buf[rec->offset]);
+}
+
+static void
+extra_tell_used_size(struct ctl_extr_rec *ctl, int size)
+{
+ struct isoent *isoent;
+ struct extr_rec *rec;
+
+ if (ctl->use_extr) {
+ isoent = ctl->isoent->parent;
+ rec = isoent->extr_rec_list.current;
+ if (rec != NULL)
+ rec->offset += size;
+ }
+ ctl->cur_len += size;
+}
+
+static int
+extra_setup_location(struct isoent *isoent, int location)
+{
+ struct extr_rec *rec;
+ int cnt;
+
+ cnt = 0;
+ rec = isoent->extr_rec_list.first;
+ isoent->extr_rec_list.current = rec;
+ while (rec) {
+ cnt++;
+ rec->location = location++;
+ rec->offset = 0;
+ rec = rec->next;
+ }
+ return (cnt);
+}
+
+/*
+ * Create the RRIP entries.
+ */
+static int
+set_directory_record_rr(unsigned char *bp, int dr_len,
+ struct isoent *isoent, struct iso9660 *iso9660, enum dir_rec_type t)
+{
+ /* Flags(BP 5) of the Rockridge "RR" System Use Field */
+ unsigned char rr_flag;
+#define RR_USE_PX 0x01
+#define RR_USE_PN 0x02
+#define RR_USE_SL 0x04
+#define RR_USE_NM 0x08
+#define RR_USE_CL 0x10
+#define RR_USE_PL 0x20
+#define RR_USE_RE 0x40
+#define RR_USE_TF 0x80
+ int length;
+ struct ctl_extr_rec ctl;
+ struct isoent *rr_parent, *pxent;
+ struct isofile *file;
+
+ bp = extra_open_record(bp, dr_len, isoent, &ctl);
+
+ if (t == DIR_REC_PARENT) {
+ rr_parent = isoent->rr_parent;
+ pxent = isoent->parent;
+ if (rr_parent != NULL)
+ isoent = rr_parent;
+ else
+ isoent = isoent->parent;
+ } else {
+ rr_parent = NULL;
+ pxent = isoent;
+ }
+ file = isoent->file;
+
+ if (t != DIR_REC_NORMAL) {
+ rr_flag = RR_USE_PX | RR_USE_TF;
+ if (rr_parent != NULL)
+ rr_flag |= RR_USE_PL;
+ } else {
+ rr_flag = RR_USE_PX | RR_USE_NM | RR_USE_TF;
+ if (archive_entry_filetype(file->entry) == AE_IFLNK)
+ rr_flag |= RR_USE_SL;
+ if (isoent->rr_parent != NULL)
+ rr_flag |= RR_USE_RE;
+ if (isoent->rr_child != NULL)
+ rr_flag |= RR_USE_CL;
+ if (archive_entry_filetype(file->entry) == AE_IFCHR ||
+ archive_entry_filetype(file->entry) == AE_IFBLK)
+ rr_flag |= RR_USE_PN;
+#ifdef COMPAT_MKISOFS
+ /*
+ * mkisofs 2.01.01a63 records "RE" extension to
+ * the entry of "rr_moved" directory.
+ * I don't understand this behavior.
+ */
+ if (isoent->virtual &&
+ isoent->parent == iso9660->primary.rootent &&
+ strcmp(isoent->file->basename.s, "rr_moved") == 0)
+ rr_flag |= RR_USE_RE;
+#endif
+ }
+
+ /* Write "SP" System Use Entry. */
+ if (t == DIR_REC_SELF && isoent == isoent->parent) {
+ length = 7;
+ if (bp != NULL) {
+ bp[1] = 'S';
+ bp[2] = 'P';
+ bp[3] = length;
+ bp[4] = 1; /* version */
+ bp[5] = 0xBE; /* Check Byte */
+ bp[6] = 0xEF; /* Check Byte */
+ bp[7] = 0;
+ bp += length;
+ }
+ extra_tell_used_size(&ctl, length);
+ }
+
+ /* Write "RR" System Use Entry. */
+ length = 5;
+ if (extra_space(&ctl) < length)
+ bp = extra_next_record(&ctl, length);
+ if (bp != NULL) {
+ bp[1] = 'R';
+ bp[2] = 'R';
+ bp[3] = length;
+ bp[4] = 1; /* version */
+ bp[5] = rr_flag;
+ bp += length;
+ }
+ extra_tell_used_size(&ctl, length);
+
+ /* Write "NM" System Use Entry. */
+ if (rr_flag & RR_USE_NM) {
+ /*
+ * "NM" Format:
+ * e.g. a basename is 'foo'
+ * len ver flg
+ * +----+----+----+----+----+----+----+----+
+ * | 'N'| 'M'| 08 | 01 | 00 | 'f'| 'o'| 'o'|
+ * +----+----+----+----+----+----+----+----+
+ * <----------------- len ----------------->
+ */
+ size_t nmlen = file->basename.length;
+ const char *nm = file->basename.s;
+ size_t nmmax;
+
+ if (extra_space(&ctl) < 6)
+ bp = extra_next_record(&ctl, 6);
+ if (bp != NULL) {
+ bp[1] = 'N';
+ bp[2] = 'M';
+ bp[4] = 1; /* version */
+ }
+ nmmax = extra_space(&ctl);
+ if (nmmax > 0xff)
+ nmmax = 0xff;
+ while (nmlen + 5 > nmmax) {
+ length = nmmax;
+ if (bp != NULL) {
+ bp[3] = length;
+ bp[5] = 0x01;/* Alternate Name continues
+ * in next "NM" field */
+ memcpy(bp+6, nm, length - 5);
+ bp += length;
+ }
+ nmlen -= length - 5;
+ nm += length - 5;
+ extra_tell_used_size(&ctl, length);
+ if (extra_space(&ctl) < 6) {
+ bp = extra_next_record(&ctl, 6);
+ nmmax = extra_space(&ctl);
+ if (nmmax > 0xff)
+ nmmax = 0xff;
+ }
+ if (bp != NULL) {
+ bp[1] = 'N';
+ bp[2] = 'M';
+ bp[4] = 1; /* version */
+ }
+ }
+ length = 5 + nmlen;
+ if (bp != NULL) {
+ bp[3] = length;
+ bp[5] = 0;
+ memcpy(bp+6, nm, nmlen);
+ bp += length;
+ }
+ extra_tell_used_size(&ctl, length);
+ }
+
+ /* Write "PX" System Use Entry. */
+ if (rr_flag & RR_USE_PX) {
+ /*
+ * "PX" Format:
+ * len ver
+ * +----+----+----+----+-----------+-----------+
+ * | 'P'| 'X'| 2C | 01 | FILE MODE | LINKS |
+ * +----+----+----+----+-----------+-----------+
+ * 0 1 2 3 4 12 20
+ * +-----------+-----------+------------------+
+ * | USER ID | GROUP ID |FILE SERIAL NUMBER|
+ * +-----------+-----------+------------------+
+ * 20 28 36 44
+ */
+ length = 44;
+ if (extra_space(&ctl) < length)
+ bp = extra_next_record(&ctl, length);
+ if (bp != NULL) {
+ mode_t mode;
+ uid_t uid;
+ gid_t gid;
+
+ mode = archive_entry_mode(file->entry);
+ uid = archive_entry_uid(file->entry);
+ gid = archive_entry_gid(file->entry);
+ if (iso9660->opt.rr == OPT_RR_USEFUL) {
+ /*
+ * This action is simular mkisofs -r option
+ * but our rockridge=useful option does not
+ * set a zero to uid and gid.
+ */
+ /* set all read bit ON */
+ mode |= 0444;
+#if !defined(_WIN32) && !defined(__CYGWIN__)
+ if (mode & 0111)
+#endif
+ /* set all exec bit ON */
+ mode |= 0111;
+ /* clear all write bits. */
+ mode &= ~0222;
+ /* clear setuid,setgid,sticky bits. */
+ mode &= ~07000;
+ }
+
+ bp[1] = 'P';
+ bp[2] = 'X';
+ bp[3] = length;
+ bp[4] = 1; /* version */
+ /* file mode */
+ set_num_733(bp+5, mode);
+ /* file links (stat.st_nlink) */
+ set_num_733(bp+13,
+ archive_entry_nlink(file->entry));
+ set_num_733(bp+21, uid);
+ set_num_733(bp+29, gid);
+ /* File Serial Number */
+ if (pxent->dir)
+ set_num_733(bp+37, pxent->dir_location);
+ else if (file->hardlink_target != NULL)
+ set_num_733(bp+37,
+ file->hardlink_target->cur_content->location);
+ else
+ set_num_733(bp+37,
+ file->cur_content->location);
+ bp += length;
+ }
+ extra_tell_used_size(&ctl, length);
+ }
+
+ /* Write "SL" System Use Entry. */
+ if (rr_flag & RR_USE_SL) {
+ /*
+ * "SL" Format:
+ * e.g. a symbolic name is 'foo/bar'
+ * len ver flg
+ * +----+----+----+----+----+------------+
+ * | 'S'| 'L'| 0F | 01 | 00 | components |
+ * +----+----+----+----+----+-----+------+
+ * 0 1 2 3 4 5 ...|... 15
+ * <----------------- len --------+------>
+ * components : |
+ * cflg clen |
+ * +----+----+----+----+----+ |
+ * | 00 | 03 | 'f'| 'o'| 'o'| <---+
+ * +----+----+----+----+----+ |
+ * 5 6 7 8 9 10 |
+ * cflg clen |
+ * +----+----+----+----+----+ |
+ * | 00 | 03 | 'b'| 'a'| 'r'| <---+
+ * +----+----+----+----+----+
+ * 10 11 12 13 14 15
+ *
+ * - cflg : flag of componet
+ * - clen : length of componet
+ */
+ const char *sl;
+ char sl_last;
+
+ if (extra_space(&ctl) < 7)
+ bp = extra_next_record(&ctl, 7);
+ sl = file->symlink.s;
+ sl_last = '\0';
+ if (bp != NULL) {
+ bp[1] = 'S';
+ bp[2] = 'L';
+ bp[4] = 1; /* version */
+ }
+ for (;;) {
+ unsigned char *nc, *cf, *cl, cldmy = 0;
+ int sllen, slmax;
+
+ slmax = extra_space(&ctl);
+ if (slmax > 0xff)
+ slmax = 0xff;
+ if (bp != NULL)
+ nc = &bp[6];
+ else
+ nc = NULL;
+ cf = cl = NULL;
+ sllen = 0;
+ while (*sl && sllen + 11 < slmax) {
+ if (sl_last == '\0' && sl[0] == '/') {
+ /*
+ * flg len
+ * +----+----+
+ * | 08 | 00 | ROOT component.
+ * +----+----+ ("/")
+ *
+ * Root component has to appear
+ * at the first component only.
+ */
+ if (nc != NULL) {
+ cf = nc++;
+ *cf = 0x08; /* ROOT */
+ *nc++ = 0;
+ }
+ sllen += 2;
+ sl++;
+ sl_last = '/';
+ cl = NULL;
+ continue;
+ }
+ if (((sl_last == '\0' || sl_last == '/') &&
+ sl[0] == '.' && sl[1] == '.' &&
+ (sl[2] == '/' || sl[2] == '\0')) ||
+ (sl[0] == '/' &&
+ sl[1] == '.' && sl[2] == '.' &&
+ (sl[3] == '/' || sl[3] == '\0'))) {
+ /*
+ * flg len
+ * +----+----+
+ * | 04 | 00 | PARENT component.
+ * +----+----+ ("..")
+ */
+ if (nc != NULL) {
+ cf = nc++;
+ *cf = 0x04; /* PARENT */
+ *nc++ = 0;
+ }
+ sllen += 2;
+ if (sl[0] == '/')
+ sl += 3;/* skip "/.." */
+ else
+ sl += 2;/* skip ".." */
+ sl_last = '.';
+ cl = NULL;
+ continue;
+ }
+ if (((sl_last == '\0' || sl_last == '/') &&
+ sl[0] == '.' &&
+ (sl[1] == '/' || sl[1] == '\0')) ||
+ (sl[0] == '/' && sl[1] == '.' &&
+ (sl[2] == '/' || sl[2] == '\0'))) {
+ /*
+ * flg len
+ * +----+----+
+ * | 02 | 00 | CURREENT component.
+ * +----+----+ (".")
+ */
+ if (nc != NULL) {
+ cf = nc++;
+ *cf = 0x02; /* CURRENT */
+ *nc++ = 0;
+ }
+ sllen += 2;
+ if (sl[0] == '/')
+ sl += 2;/* skip "/." */
+ else
+ sl ++; /* skip "." */
+ sl_last = '.';
+ cl = NULL;
+ continue;
+ }
+ if (sl[0] == '/' || cl == NULL) {
+ if (nc != NULL) {
+ cf = nc++;
+ *cf = 0;
+ cl = nc++;
+ *cl = 0;
+ } else
+ cl = &cldmy;
+ sllen += 2;
+ if (sl[0] == '/') {
+ sl_last = *sl++;
+ continue;
+ }
+ }
+ sl_last = *sl++;
+ if (nc != NULL) {
+ *nc++ = sl_last;
+ (*cl) ++;
+ }
+ sllen++;
+ }
+ if (*sl) {
+ length = 5 + sllen;
+ if (bp != NULL) {
+ /*
+ * Mark flg as CONTINUE component.
+ */
+ *cf |= 0x01;
+ /*
+ * len ver flg
+ * +----+----+----+----+----+-
+ * | 'S'| 'L'| XX | 01 | 01 |
+ * +----+----+----+----+----+-
+ * ^
+ * continues in next "SL"
+ */
+ bp[3] = length;
+ bp[5] = 0x01;/* This Symbolic Link
+ * continues in next
+ * "SL" field */
+ bp += length;
+ }
+ extra_tell_used_size(&ctl, length);
+ if (extra_space(&ctl) < 11)
+ bp = extra_next_record(&ctl, 11);
+ if (bp != NULL) {
+ /* Next 'SL' */
+ bp[1] = 'S';
+ bp[2] = 'L';
+ bp[4] = 1; /* version */
+ }
+ } else {
+ length = 5 + sllen;
+ if (bp != NULL) {
+ bp[3] = length;
+ bp[5] = 0;
+ bp += length;
+ }
+ extra_tell_used_size(&ctl, length);
+ break;
+ }
+ }
+ }
+
+ /* Write "TF" System Use Entry. */
+ if (rr_flag & RR_USE_TF) {
+ /*
+ * "TF" Format:
+ * len ver
+ * +----+----+----+----+-----+-------------+
+ * | 'T'| 'F'| XX | 01 |FLAGS| TIME STAMPS |
+ * +----+----+----+----+-----+-------------+
+ * 0 1 2 3 4 5 XX
+ * TIME STAMPS : ISO 9660 Standard 9.1.5.
+ * If TF_LONG_FORM FLAGS is set,
+ * use ISO9660 Standard 8.4.26.1.
+ */
+#define TF_CREATION 0x01 /* Creation time recorded */
+#define TF_MODIFY 0x02 /* Modification time recorded */
+#define TF_ACCESS 0x04 /* Last Access time recorded */
+#define TF_ATTRIBUTES 0x08 /* Last Attribute Change time recorded */
+#define TF_BACKUP 0x10 /* Last Backup time recorded */
+#define TF_EXPIRATION 0x20 /* Expiration time recorded */
+#define TF_EFFECTIVE 0x40 /* Effective time recorded */
+#define TF_LONG_FORM 0x80 /* ISO 9660 17-byte time format used */
+ unsigned char tf_flags;
+
+ length = 5;
+ tf_flags = 0;
+#ifndef COMPAT_MKISOFS
+ if (archive_entry_birthtime_is_set(file->entry) &&
+ archive_entry_birthtime(file->entry) <=
+ archive_entry_mtime(file->entry)) {
+ length += 7;
+ tf_flags |= TF_CREATION;
+ }
+#endif
+ if (archive_entry_mtime_is_set(file->entry)) {
+ length += 7;
+ tf_flags |= TF_MODIFY;
+ }
+ if (archive_entry_atime_is_set(file->entry)) {
+ length += 7;
+ tf_flags |= TF_ACCESS;
+ }
+ if (archive_entry_ctime_is_set(file->entry)) {
+ length += 7;
+ tf_flags |= TF_ATTRIBUTES;
+ }
+ if (extra_space(&ctl) < length)
+ bp = extra_next_record(&ctl, length);
+ if (bp != NULL) {
+ bp[1] = 'T';
+ bp[2] = 'F';
+ bp[3] = length;
+ bp[4] = 1; /* version */
+ bp[5] = tf_flags;
+ bp += 5;
+ /* Creation time */
+ if (tf_flags & TF_CREATION) {
+ set_time_915(bp+1,
+ archive_entry_birthtime(file->entry));
+ bp += 7;
+ }
+ /* Modification time */
+ if (tf_flags & TF_MODIFY) {
+ set_time_915(bp+1,
+ archive_entry_mtime(file->entry));
+ bp += 7;
+ }
+ /* Last Access time */
+ if (tf_flags & TF_ACCESS) {
+ set_time_915(bp+1,
+ archive_entry_atime(file->entry));
+ bp += 7;
+ }
+ /* Last Attribute Change time */
+ if (tf_flags & TF_ATTRIBUTES) {
+ set_time_915(bp+1,
+ archive_entry_ctime(file->entry));
+ bp += 7;
+ }
+ }
+ extra_tell_used_size(&ctl, length);
+ }
+
+ /* Write "RE" System Use Entry. */
+ if (rr_flag & RR_USE_RE) {
+ /*
+ * "RE" Format:
+ * len ver
+ * +----+----+----+----+
+ * | 'R'| 'E'| 04 | 01 |
+ * +----+----+----+----+
+ * 0 1 2 3 4
+ */
+ length = 4;
+ if (extra_space(&ctl) < length)
+ bp = extra_next_record(&ctl, length);
+ if (bp != NULL) {
+ bp[1] = 'R';
+ bp[2] = 'E';
+ bp[3] = length;
+ bp[4] = 1; /* version */
+ bp += length;
+ }
+ extra_tell_used_size(&ctl, length);
+ }
+
+ /* Write "PL" System Use Entry. */
+ if (rr_flag & RR_USE_PL) {
+ /*
+ * "PL" Format:
+ * len ver
+ * +----+----+----+----+------------+
+ * | 'P'| 'L'| 0C | 01 | *LOCATION |
+ * +----+----+----+----+------------+
+ * 0 1 2 3 4 12
+ * *LOCATION: location of parent directory
+ */
+ length = 12;
+ if (extra_space(&ctl) < length)
+ bp = extra_next_record(&ctl, length);
+ if (bp != NULL) {
+ bp[1] = 'P';
+ bp[2] = 'L';
+ bp[3] = length;
+ bp[4] = 1; /* version */
+ set_num_733(bp + 5,
+ rr_parent->dir_location);
+ bp += length;
+ }
+ extra_tell_used_size(&ctl, length);
+ }
+
+ /* Write "CL" System Use Entry. */
+ if (rr_flag & RR_USE_CL) {
+ /*
+ * "CL" Format:
+ * len ver
+ * +----+----+----+----+------------+
+ * | 'C'| 'L'| 0C | 01 | *LOCATION |
+ * +----+----+----+----+------------+
+ * 0 1 2 3 4 12
+ * *LOCATION: location of child directory
+ */
+ length = 12;
+ if (extra_space(&ctl) < length)
+ bp = extra_next_record(&ctl, length);
+ if (bp != NULL) {
+ bp[1] = 'C';
+ bp[2] = 'L';
+ bp[3] = length;
+ bp[4] = 1; /* version */
+ set_num_733(bp + 5,
+ isoent->rr_child->dir_location);
+ bp += length;
+ }
+ extra_tell_used_size(&ctl, length);
+ }
+
+ /* Write "PN" System Use Entry. */
+ if (rr_flag & RR_USE_PN) {
+ /*
+ * "PN" Format:
+ * len ver
+ * +----+----+----+----+------------+------------+
+ * | 'P'| 'N'| 14 | 01 | dev_t high | dev_t low |
+ * +----+----+----+----+------------+------------+
+ * 0 1 2 3 4 12 20
+ */
+ length = 20;
+ if (extra_space(&ctl) < length)
+ bp = extra_next_record(&ctl, length);
+ if (bp != NULL) {
+ uint64_t dev;
+
+ bp[1] = 'P';
+ bp[2] = 'N';
+ bp[3] = length;
+ bp[4] = 1; /* version */
+ dev = (uint64_t)archive_entry_rdev(file->entry);
+ set_num_733(bp + 5, dev >> 32);
+ set_num_733(bp + 13, dev & 0xFFFFFFFF);
+ bp += length;
+ }
+ extra_tell_used_size(&ctl, length);
+ }
+
+ /* Write "ZF" System Use Entry. */
+ if (file->zisofs.header_size) {
+ /*
+ * "ZF" Format:
+ * len ver
+ * +----+----+----+----+----+----+-------------+
+ * | 'Z'| 'F'| 10 | 01 | 'p'| 'z'| Header Size |
+ * +----+----+----+----+----+----+-------------+
+ * 0 1 2 3 4 5 6 7
+ * +--------------------+-------------------+
+ * | Log2 of block Size | Uncompressed Size |
+ * +--------------------+-------------------+
+ * 7 8 16
+ */
+ length = 16;
+ if (extra_space(&ctl) < length)
+ bp = extra_next_record(&ctl, length);
+ if (bp != NULL) {
+ bp[1] = 'Z';
+ bp[2] = 'F';
+ bp[3] = length;
+ bp[4] = 1; /* version */
+ bp[5] = 'p';
+ bp[6] = 'z';
+ bp[7] = file->zisofs.header_size;
+ bp[8] = file->zisofs.log2_bs;
+ set_num_733(bp + 9, file->zisofs.uncompressed_size);
+ bp += length;
+ }
+ extra_tell_used_size(&ctl, length);
+ }
+
+ /* Write "CE" System Use Entry. */
+ if (t == DIR_REC_SELF && isoent == isoent->parent) {
+ length = RR_CE_SIZE;
+ if (bp != NULL)
+ set_SUSP_CE(bp+1, iso9660->location_rrip_er,
+ 0, RRIP_ER_SIZE);
+ extra_tell_used_size(&ctl, length);
+ }
+
+ extra_close_record(&ctl, 0);
+
+ return (ctl.dr_len);
+}
+
+/*
+ * Write data of a Directory Record or calculate writing bytes itself.
+ * If parameter `p' is NULL, calculates the size of writing data, which
+ * a Directory Record needs to write, then it saved and return
+ * the calculated size.
+ * Parameter `n' is a remaining size of buffer. when parameter `p' is
+ * not NULL, check whether that `n' is not less than the saved size.
+ * if that `n' is small, return zero.
+ *
+ * This format of the Directory Record is according to
+ * ISO9660 Standard 9.1
+ */
+static int
+set_directory_record(unsigned char *p, size_t n, struct isoent *isoent,
+ struct iso9660 *iso9660, enum dir_rec_type t,
+ enum vdd_type vdd_type)
+{
+ unsigned char *bp;
+ size_t dr_len;
+ size_t fi_len;
+
+ if (p != NULL) {
+ /*
+ * Check whether a write buffer size is less than the
+ * saved size which is needed to write this Directory
+ * Record.
+ */
+ switch (t) {
+ case DIR_REC_VD:
+ dr_len = isoent->dr_len.vd; break;
+ case DIR_REC_SELF:
+ dr_len = isoent->dr_len.self; break;
+ case DIR_REC_PARENT:
+ dr_len = isoent->dr_len.parent; break;
+ case DIR_REC_NORMAL:
+ default:
+ dr_len = isoent->dr_len.normal; break;
+ }
+ if (dr_len > n)
+ return (0);/* Needs more buffer size. */
+ }
+
+ if (t == DIR_REC_NORMAL && isoent->identifier != NULL)
+ fi_len = isoent->id_len;
+ else
+ fi_len = 1;
+
+ if (p != NULL) {
+ struct isoent *xisoent;
+ struct isofile *file;
+ unsigned char flag;
+
+ if (t == DIR_REC_PARENT)
+ xisoent = isoent->parent;
+ else
+ xisoent = isoent;
+ file = isoent->file;
+ if (file->hardlink_target != NULL)
+ file = file->hardlink_target;
+ /* Make a file flag. */
+ if (xisoent->dir)
+ flag = FILE_FLAG_DIRECTORY;
+ else {
+ if (file->cur_content->next != NULL)
+ flag = FILE_FLAG_MULTI_EXTENT;
+ else
+ flag = 0;
+ }
+
+ bp = p -1;
+ /* Extended Attribute Record Length */
+ set_num_711(bp+2, 0);
+ /* Location of Extent */
+ if (xisoent->dir)
+ set_num_733(bp+3, xisoent->dir_location);
+ else
+ set_num_733(bp+3, file->cur_content->location);
+ /* Data Length */
+ if (xisoent->dir)
+ set_num_733(bp+11,
+ xisoent->dir_block * LOGICAL_BLOCK_SIZE);
+ else
+ set_num_733(bp+11, file->cur_content->size);
+ /* Recording Date and Time */
+ /* NOTE:
+ * If a file type is symbolic link, you are seeing this
+ * field value is different from a value mkisofs makes.
+ * libarchive uses lstat to get this one, but it
+ * seems mkisofs uses stat to get.
+ */
+ set_time_915(bp+19,
+ archive_entry_mtime(xisoent->file->entry));
+ /* File Flags */
+ bp[26] = flag;
+ /* File Unit Size */
+ set_num_711(bp+27, 0);
+ /* Interleave Gap Size */
+ set_num_711(bp+28, 0);
+ /* Volume Sequence Number */
+ set_num_723(bp+29, iso9660->volume_sequence_number);
+ /* Length of File Identifier */
+ set_num_711(bp+33, fi_len);
+ /* File Identifier */
+ switch (t) {
+ case DIR_REC_VD:
+ case DIR_REC_SELF:
+ set_num_711(bp+34, 0);
+ break;
+ case DIR_REC_PARENT:
+ set_num_711(bp+34, 1);
+ break;
+ case DIR_REC_NORMAL:
+ if (isoent->identifier != NULL)
+ memcpy(bp+34, isoent->identifier, fi_len);
+ else
+ set_num_711(bp+34, 0);
+ break;
+ }
+ } else
+ bp = NULL;
+ dr_len = 33 + fi_len;
+ /* Padding Field */
+ if (dr_len & 0x01) {
+ dr_len ++;
+ if (p != NULL)
+ bp[dr_len] = 0;
+ }
+
+ /* Volume Descriptor does not record extension. */
+ if (t == DIR_REC_VD) {
+ if (p != NULL)
+ /* Length of Directory Record */
+ set_num_711(p, dr_len);
+ else
+ isoent->dr_len.vd = dr_len;
+ return (dr_len);
+ }
+
+ /* Rockridge */
+ if (iso9660->opt.rr && vdd_type != VDD_JOLIET)
+ dr_len = set_directory_record_rr(bp, dr_len,
+ isoent, iso9660, t);
+
+ if (p != NULL)
+ /* Length of Directory Record */
+ set_num_711(p, dr_len);
+ else {
+ /*
+ * Save the size which is needed to write this
+ * Directory Record.
+ */
+ switch (t) {
+ case DIR_REC_VD:
+ /* This case does not come, but compiler
+ * complains that DIR_REC_VD not handled
+ * in switch .... */
+ break;
+ case DIR_REC_SELF:
+ isoent->dr_len.self = dr_len; break;
+ case DIR_REC_PARENT:
+ isoent->dr_len.parent = dr_len; break;
+ case DIR_REC_NORMAL:
+ isoent->dr_len.normal = dr_len; break;
+ }
+ }
+
+ return (dr_len);
+}
+
+/*
+ * Calculate the size of a directory record.
+ */
+static inline int
+get_dir_rec_size(struct iso9660 *iso9660, struct isoent *isoent,
+ enum dir_rec_type t, enum vdd_type vdd_type)
+{
+
+ return (set_directory_record(NULL, SIZE_MAX,
+ isoent, iso9660, t, vdd_type));
+}
+
+/*
+ * Manage to write ISO-image data with wbuff to reduce calling
+ * __archive_write_output() for performance.
+ */
+
+
+static inline unsigned char *
+wb_buffptr(struct archive_write *a)
+{
+ struct iso9660 *iso9660 = (struct iso9660 *)a->format_data;
+
+ return (&(iso9660->wbuff[sizeof(iso9660->wbuff)
+ - iso9660->wbuff_remaining]));
+}
+
+static int
+wb_write_out(struct archive_write *a)
+{
+ struct iso9660 *iso9660 = (struct iso9660 *)a->format_data;
+ size_t wsize, nw;
+ int r;
+
+ wsize = sizeof(iso9660->wbuff) - iso9660->wbuff_remaining;
+ nw = wsize % LOGICAL_BLOCK_SIZE;
+ if (iso9660->wbuff_type == WB_TO_STREAM)
+ r = __archive_write_output(a, iso9660->wbuff, wsize - nw);
+ else
+ r = write_to_temp(a, iso9660->wbuff, wsize - nw);
+ /* Increase the offset. */
+ iso9660->wbuff_offset += wsize - nw;
+ if (iso9660->wbuff_offset > iso9660->wbuff_written)
+ iso9660->wbuff_written = iso9660->wbuff_offset;
+ iso9660->wbuff_remaining = sizeof(iso9660->wbuff);
+ if (nw) {
+ iso9660->wbuff_remaining -= nw;
+ memmove(iso9660->wbuff, iso9660->wbuff + wsize - nw, nw);
+ }
+ return (r);
+}
+
+static int
+wb_consume(struct archive_write *a, size_t size)
+{
+ struct iso9660 *iso9660 = (struct iso9660 *)a->format_data;
+
+ if (size > iso9660->wbuff_remaining ||
+ iso9660->wbuff_remaining == 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Internal Programing error: iso9660:wb_consume()"
+ " size=%jd, wbuff_remaining=%jd",
+ (intmax_t)size, (intmax_t)iso9660->wbuff_remaining);
+ return (ARCHIVE_FATAL);
+ }
+ iso9660->wbuff_remaining -= size;
+ if (iso9660->wbuff_remaining < LOGICAL_BLOCK_SIZE)
+ return (wb_write_out(a));
+ return (ARCHIVE_OK);
+}
+
+#ifdef HAVE_ZLIB_H
+
+static int
+wb_set_offset(struct archive_write *a, int64_t off)
+{
+ struct iso9660 *iso9660 = (struct iso9660 *)a->format_data;
+ int64_t used, ext_bytes;
+
+ if (iso9660->wbuff_type != WB_TO_TEMP) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Internal Programing error: iso9660:wb_set_offset()");
+ return (ARCHIVE_FATAL);
+ }
+
+ used = sizeof(iso9660->wbuff) - iso9660->wbuff_remaining;
+ if (iso9660->wbuff_offset + used > iso9660->wbuff_tail)
+ iso9660->wbuff_tail = iso9660->wbuff_offset + used;
+ if (iso9660->wbuff_offset < iso9660->wbuff_written) {
+ if (used > 0 &&
+ write_to_temp(a, iso9660->wbuff, used) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ iso9660->wbuff_offset = iso9660->wbuff_written;
+ lseek(iso9660->temp_fd, iso9660->wbuff_offset, SEEK_SET);
+ iso9660->wbuff_remaining = sizeof(iso9660->wbuff);
+ used = 0;
+ }
+ if (off < iso9660->wbuff_offset) {
+ /*
+ * Write out waiting data.
+ */
+ if (used > 0) {
+ if (wb_write_out(a) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+ lseek(iso9660->temp_fd, off, SEEK_SET);
+ iso9660->wbuff_offset = off;
+ iso9660->wbuff_remaining = sizeof(iso9660->wbuff);
+ } else if (off <= iso9660->wbuff_tail) {
+ iso9660->wbuff_remaining =
+ sizeof(iso9660->wbuff) - (off - iso9660->wbuff_offset);
+ } else {
+ ext_bytes = off - iso9660->wbuff_tail;
+ iso9660->wbuff_remaining = sizeof(iso9660->wbuff)
+ - (iso9660->wbuff_tail - iso9660->wbuff_offset);
+ while (ext_bytes >= iso9660->wbuff_remaining) {
+ if (write_null(a, (size_t)iso9660->wbuff_remaining)
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ ext_bytes -= iso9660->wbuff_remaining;
+ }
+ if (ext_bytes > 0) {
+ if (write_null(a, (size_t)ext_bytes) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+ }
+ return (ARCHIVE_OK);
+}
+
+#endif /* HAVE_ZLIB_H */
+
+static int
+write_null(struct archive_write *a, size_t size)
+{
+ size_t remaining;
+ unsigned char *p, *old;
+ int r;
+
+ remaining = wb_remaining(a);
+ p = wb_buffptr(a);
+ if (size <= remaining) {
+ memset(p, 0, size);
+ return (wb_consume(a, size));
+ }
+ memset(p, 0, remaining);
+ r = wb_consume(a, remaining);
+ if (r != ARCHIVE_OK)
+ return (r);
+ size -= remaining;
+ old = p;
+ p = wb_buffptr(a);
+ memset(p, 0, old - p);
+ remaining = wb_remaining(a);
+ while (size) {
+ size_t wsize = size;
+
+ if (wsize > remaining)
+ wsize = remaining;
+ r = wb_consume(a, wsize);
+ if (r != ARCHIVE_OK)
+ return (r);
+ size -= wsize;
+ }
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Write Volume Descriptor Set Terminator
+ */
+static int
+write_VD_terminator(struct archive_write *a)
+{
+ unsigned char *bp;
+
+ bp = wb_buffptr(a) -1;
+ set_VD_bp(bp, VDT_TERMINATOR, 1);
+ set_unused_field_bp(bp, 8, LOGICAL_BLOCK_SIZE);
+
+ return (wb_consume(a, LOGICAL_BLOCK_SIZE));
+}
+
+static int
+set_file_identifier(unsigned char *bp, int from, int to, enum vdc vdc,
+ struct archive_write *a, struct vdd *vdd, struct archive_string *id,
+ const char *label, int leading_under, enum char_type char_type)
+{
+ char identifier[256];
+ struct isoent *isoent;
+ const char *ids;
+ size_t len;
+ int r;
+
+ if (id->length > 0 && leading_under && id->s[0] != '_') {
+ if (char_type == A_CHAR)
+ r = set_str_a_characters_bp(a, bp, from, to, id->s, vdc);
+ else
+ r = set_str_d_characters_bp(a, bp, from, to, id->s, vdc);
+ } else if (id->length > 0) {
+ ids = id->s;
+ if (leading_under)
+ ids++;
+ isoent = isoent_find_entry(vdd->rootent, ids);
+ if (isoent == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Not Found %s `%s'.",
+ label, ids);
+ return (ARCHIVE_FATAL);
+ }
+ len = isoent->ext_off + isoent->ext_len;
+ if (vdd->vdd_type == VDD_JOLIET) {
+ if (len > sizeof(identifier)-2)
+ len = sizeof(identifier)-2;
+ } else {
+ if (len > sizeof(identifier)-1)
+ len = sizeof(identifier)-1;
+ }
+ memcpy(identifier, isoent->identifier, len);
+ identifier[len] = '\0';
+ if (vdd->vdd_type == VDD_JOLIET) {
+ identifier[len+1] = 0;
+ vdc = VDC_UCS2_DIRECT;
+ }
+ if (char_type == A_CHAR)
+ r = set_str_a_characters_bp(a, bp, from, to,
+ identifier, vdc);
+ else
+ r = set_str_d_characters_bp(a, bp, from, to,
+ identifier, vdc);
+ } else {
+ if (char_type == A_CHAR)
+ r = set_str_a_characters_bp(a, bp, from, to, NULL, vdc);
+ else
+ r = set_str_d_characters_bp(a, bp, from, to, NULL, vdc);
+ }
+ return (r);
+}
+
+/*
+ * Write Primary/Supplementary Volume Descriptor
+ */
+static int
+write_VD(struct archive_write *a, struct vdd *vdd)
+{
+ struct iso9660 *iso9660;
+ unsigned char *bp;
+ uint16_t volume_set_size = 1;
+ char identifier[256];
+ enum VD_type vdt;
+ enum vdc vdc;
+ unsigned char vd_ver, fst_ver;
+ int r;
+
+ iso9660 = a->format_data;
+ switch (vdd->vdd_type) {
+ case VDD_JOLIET:
+ vdt = VDT_SUPPLEMENTARY;
+ vd_ver = fst_ver = 1;
+ vdc = VDC_UCS2;
+ break;
+ case VDD_ENHANCED:
+ vdt = VDT_SUPPLEMENTARY;
+ vd_ver = fst_ver = 2;
+ vdc = VDC_LOWERCASE;
+ break;
+ case VDD_PRIMARY:
+ default:
+ vdt = VDT_PRIMARY;
+ vd_ver = fst_ver = 1;
+#ifdef COMPAT_MKISOFS
+ vdc = VDC_LOWERCASE;
+#else
+ vdc = VDC_STD;
+#endif
+ break;
+ }
+
+ bp = wb_buffptr(a) -1;
+ /* Volume Descriptor Type */
+ set_VD_bp(bp, vdt, vd_ver);
+ /* Unused Field */
+ set_unused_field_bp(bp, 8, 8);
+ /* System Identifier */
+ get_system_identitier(identifier, sizeof(identifier));
+ r = set_str_a_characters_bp(a, bp, 9, 40, identifier, vdc);
+ if (r != ARCHIVE_OK)
+ return (r);
+ /* Volume Identifier */
+ r = set_str_d_characters_bp(a, bp, 41, 72,
+ iso9660->volume_identifier.s, vdc);
+ if (r != ARCHIVE_OK)
+ return (r);
+ /* Unused Field */
+ set_unused_field_bp(bp, 73, 80);
+ /* Volume Space Size */
+ set_num_733(bp+81, iso9660->volume_space_size);
+ if (vdd->vdd_type == VDD_JOLIET) {
+ /* Escape Sequences */
+ bp[89] = 0x25;/* UCS-2 Level 3 */
+ bp[90] = 0x2F;
+ bp[91] = 0x45;
+ memset(bp + 92, 0, 120 - 92 + 1);
+ } else {
+ /* Unused Field */
+ set_unused_field_bp(bp, 89, 120);
+ }
+ /* Volume Set Size */
+ set_num_723(bp+121, volume_set_size);
+ /* Volume Sequence Number */
+ set_num_723(bp+125, iso9660->volume_sequence_number);
+ /* Logical Block Size */
+ set_num_723(bp+129, LOGICAL_BLOCK_SIZE);
+ /* Path Table Size */
+ set_num_733(bp+133, vdd->path_table_size);
+ /* Location of Occurrence of Type L Path Table */
+ set_num_731(bp+141, vdd->location_type_L_path_table);
+ /* Location of Optional Occurrence of Type L Path Table */
+ set_num_731(bp+145, 0);
+ /* Location of Occurrence of Type M Path Table */
+ set_num_732(bp+149, vdd->location_type_M_path_table);
+ /* Location of Optional Occurrence of Type M Path Table */
+ set_num_732(bp+153, 0);
+ /* Directory Record for Root Directory(BP 157 to 190) */
+ set_directory_record(bp+157, 190-157+1, vdd->rootent,
+ iso9660, DIR_REC_VD, vdd->vdd_type);
+ /* Volume Set Identifier */
+ r = set_str_d_characters_bp(a, bp, 191, 318, "", vdc);
+ if (r != ARCHIVE_OK)
+ return (r);
+ /* Publisher Identifier */
+ r = set_file_identifier(bp, 319, 446, vdc, a, vdd,
+ &(iso9660->publisher_identifier),
+ "Publisher File", 1, A_CHAR);
+ if (r != ARCHIVE_OK)
+ return (r);
+ /* Data Preparer Identifier */
+ r = set_file_identifier(bp, 447, 574, vdc, a, vdd,
+ &(iso9660->data_preparer_identifier),
+ "Data Preparer File", 1, A_CHAR);
+ if (r != ARCHIVE_OK)
+ return (r);
+ /* Application Identifier */
+ r = set_file_identifier(bp, 575, 702, vdc, a, vdd,
+ &(iso9660->application_identifier),
+ "Application File", 1, A_CHAR);
+ if (r != ARCHIVE_OK)
+ return (r);
+ /* Copyright File Identifier */
+ r = set_file_identifier(bp, 703, 739, vdc, a, vdd,
+ &(iso9660->copyright_file_identifier),
+ "Copyright File", 0, D_CHAR);
+ if (r != ARCHIVE_OK)
+ return (r);
+ /* Abstract File Identifier */
+ r = set_file_identifier(bp, 740, 776, vdc, a, vdd,
+ &(iso9660->abstract_file_identifier),
+ "Abstract File", 0, D_CHAR);
+ if (r != ARCHIVE_OK)
+ return (r);
+ /* Bibliongraphic File Identifier */
+ r = set_file_identifier(bp, 777, 813, vdc, a, vdd,
+ &(iso9660->bibliographic_file_identifier),
+ "Bibliongraphic File", 0, D_CHAR);
+ if (r != ARCHIVE_OK)
+ return (r);
+ /* Volume Creation Date and Time */
+ set_date_time(bp+814, iso9660->birth_time);
+ /* Volume Modification Date and Time */
+ set_date_time(bp+831, iso9660->birth_time);
+ /* Volume Expiration Date and Time(obsolete) */
+ set_date_time_null(bp+848);
+ /* Volume Effective Date and Time */
+ set_date_time(bp+865, iso9660->birth_time);
+ /* File Structure Version */
+ bp[882] = fst_ver;
+ /* Reserved */
+ bp[883] = 0;
+ /* Application Use */
+ memset(bp + 884, 0x20, 1395 - 884 + 1);
+ /* Reserved */
+ set_unused_field_bp(bp, 1396, LOGICAL_BLOCK_SIZE);
+
+ return (wb_consume(a, LOGICAL_BLOCK_SIZE));
+}
+
+/*
+ * Write Boot Record Volume Descriptor
+ */
+static int
+write_VD_boot_record(struct archive_write *a)
+{
+ struct iso9660 *iso9660;
+ unsigned char *bp;
+
+ iso9660 = a->format_data;
+ bp = wb_buffptr(a) -1;
+ /* Volume Descriptor Type */
+ set_VD_bp(bp, VDT_BOOT_RECORD, 1);
+ /* Boot System Identifier */
+ memcpy(bp+8, "EL TORITO SPECIFICATION", 23);
+ set_unused_field_bp(bp, 8+23, 39);
+ /* Unused */
+ set_unused_field_bp(bp, 40, 71);
+ /* Absolute pointer to first sector of Boot Catalog */
+ set_num_731(bp+72,
+ iso9660->el_torito.catalog->file->content.location);
+ /* Unused */
+ set_unused_field_bp(bp, 76, LOGICAL_BLOCK_SIZE);
+
+ return (wb_consume(a, LOGICAL_BLOCK_SIZE));
+}
+
+enum keytype {
+ KEY_FLG,
+ KEY_STR,
+ KEY_INT,
+ KEY_HEX,
+};
+static void
+set_option_info(struct archive_string *info, int *opt, const char *key,
+ enum keytype type, ...)
+{
+ va_list ap;
+ char prefix;
+ const char *s;
+ int d;
+
+ prefix = (*opt==0)? ' ':',';
+ va_start(ap, type);
+ switch (type) {
+ case KEY_FLG:
+ d = va_arg(ap, int);
+ archive_string_sprintf(info, "%c%s%s",
+ prefix, (d == 0)?"!":"", key);
+ break;
+ case KEY_STR:
+ s = va_arg(ap, const char *);
+ archive_string_sprintf(info, "%c%s=%s",
+ prefix, key, s);
+ break;
+ case KEY_INT:
+ d = va_arg(ap, int);
+ archive_string_sprintf(info, "%c%s=%d",
+ prefix, key, d);
+ break;
+ case KEY_HEX:
+ d = va_arg(ap, int);
+ archive_string_sprintf(info, "%c%s=%x",
+ prefix, key, d);
+ break;
+ }
+ va_end(ap);
+
+ *opt = 1;
+}
+
+/*
+ * Make Non-ISO File System Information
+ */
+static int
+write_information_block(struct archive_write *a)
+{
+ struct iso9660 *iso9660;
+ char buf[128];
+ const char *v;
+ int opt, r;
+ struct archive_string info;
+ size_t info_size = LOGICAL_BLOCK_SIZE *
+ NON_ISO_FILE_SYSTEM_INFORMATION_BLOCK;
+
+ iso9660 = (struct iso9660 *)a->format_data;
+ if (info_size > wb_remaining(a)) {
+ r = wb_write_out(a);
+ if (r != ARCHIVE_OK)
+ return (r);
+ }
+ archive_string_init(&info);
+ if (archive_string_ensure(&info, info_size) == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ memset(info.s, 0, info_size);
+ opt = 0;
+#if defined(HAVE__CTIME64_S)
+ _ctime64_s(buf, sizeof(buf), &(iso9660->birth_time));
+#elif defined(HAVE_CTIME_R)
+ ctime_r(&(iso9660->birth_time), buf);
+#else
+ strncpy(buf, ctime(&(iso9660->birth_time)), sizeof(buf)-1);
+ buf[sizeof(buf)-1] = '\0';
+#endif
+ archive_string_sprintf(&info,
+ "INFO %s%s", buf, archive_version_string());
+ if (iso9660->opt.abstract_file != OPT_ABSTRACT_FILE_DEFAULT)
+ set_option_info(&info, &opt, "abstract-file",
+ KEY_STR, iso9660->abstract_file_identifier.s);
+ if (iso9660->opt.application_id != OPT_APPLICATION_ID_DEFAULT)
+ set_option_info(&info, &opt, "application-id",
+ KEY_STR, iso9660->application_identifier.s);
+ if (iso9660->opt.allow_vernum != OPT_ALLOW_VERNUM_DEFAULT)
+ set_option_info(&info, &opt, "allow-vernum",
+ KEY_FLG, iso9660->opt.allow_vernum);
+ if (iso9660->opt.biblio_file != OPT_BIBLIO_FILE_DEFAULT)
+ set_option_info(&info, &opt, "biblio-file",
+ KEY_STR, iso9660->bibliographic_file_identifier.s);
+ if (iso9660->opt.boot != OPT_BOOT_DEFAULT)
+ set_option_info(&info, &opt, "boot",
+ KEY_STR, iso9660->el_torito.boot_filename.s);
+ if (iso9660->opt.boot_catalog != OPT_BOOT_CATALOG_DEFAULT)
+ set_option_info(&info, &opt, "boot-catalog",
+ KEY_STR, iso9660->el_torito.catalog_filename.s);
+ if (iso9660->opt.boot_info_table != OPT_BOOT_INFO_TABLE_DEFAULT)
+ set_option_info(&info, &opt, "boot-info-table",
+ KEY_FLG, iso9660->opt.boot_info_table);
+ if (iso9660->opt.boot_load_seg != OPT_BOOT_LOAD_SEG_DEFAULT)
+ set_option_info(&info, &opt, "boot-load-seg",
+ KEY_HEX, iso9660->el_torito.boot_load_seg);
+ if (iso9660->opt.boot_load_size != OPT_BOOT_LOAD_SIZE_DEFAULT)
+ set_option_info(&info, &opt, "boot-load-size",
+ KEY_INT, iso9660->el_torito.boot_load_size);
+ if (iso9660->opt.boot_type != OPT_BOOT_TYPE_DEFAULT) {
+ v = "no-emulation";
+ if (iso9660->opt.boot_type == OPT_BOOT_TYPE_FD)
+ v = "fd";
+ if (iso9660->opt.boot_type == OPT_BOOT_TYPE_HARD_DISK)
+ v = "hard-disk";
+ set_option_info(&info, &opt, "boot-type",
+ KEY_STR, v);
+ }
+#ifdef HAVE_ZLIB_H
+ if (iso9660->opt.compression_level != OPT_COMPRESSION_LEVEL_DEFAULT)
+ set_option_info(&info, &opt, "compression-level",
+ KEY_INT, iso9660->zisofs.compression_level);
+#endif
+ if (iso9660->opt.copyright_file != OPT_COPYRIGHT_FILE_DEFAULT)
+ set_option_info(&info, &opt, "copyright-file",
+ KEY_STR, iso9660->copyright_file_identifier.s);
+ if (iso9660->opt.iso_level != OPT_ISO_LEVEL_DEFAULT)
+ set_option_info(&info, &opt, "iso-level",
+ KEY_INT, iso9660->opt.iso_level);
+ if (iso9660->opt.joliet != OPT_JOLIET_DEFAULT) {
+ if (iso9660->opt.joliet == OPT_JOLIET_LONGNAME)
+ set_option_info(&info, &opt, "joliet",
+ KEY_STR, "long");
+ else
+ set_option_info(&info, &opt, "joliet",
+ KEY_FLG, iso9660->opt.joliet);
+ }
+ if (iso9660->opt.limit_depth != OPT_LIMIT_DEPTH_DEFAULT)
+ set_option_info(&info, &opt, "limit-depth",
+ KEY_FLG, iso9660->opt.limit_depth);
+ if (iso9660->opt.limit_dirs != OPT_LIMIT_DIRS_DEFAULT)
+ set_option_info(&info, &opt, "limit-dirs",
+ KEY_FLG, iso9660->opt.limit_dirs);
+ if (iso9660->opt.pad != OPT_PAD_DEFAULT)
+ set_option_info(&info, &opt, "pad",
+ KEY_FLG, iso9660->opt.pad);
+ if (iso9660->opt.publisher != OPT_PUBLISHER_DEFAULT)
+ set_option_info(&info, &opt, "publisher",
+ KEY_STR, iso9660->publisher_identifier.s);
+ if (iso9660->opt.rr != OPT_RR_DEFAULT) {
+ if (iso9660->opt.rr == OPT_RR_DISABLED)
+ set_option_info(&info, &opt, "rockridge",
+ KEY_FLG, iso9660->opt.rr);
+ else if (iso9660->opt.rr == OPT_RR_STRICT)
+ set_option_info(&info, &opt, "rockridge",
+ KEY_STR, "strict");
+ else if (iso9660->opt.rr == OPT_RR_USEFUL)
+ set_option_info(&info, &opt, "rockridge",
+ KEY_STR, "useful");
+ }
+ if (iso9660->opt.volume_id != OPT_VOLUME_ID_DEFAULT)
+ set_option_info(&info, &opt, "volume-id",
+ KEY_STR, iso9660->volume_identifier.s);
+ if (iso9660->opt.zisofs != OPT_ZISOFS_DEFAULT)
+ set_option_info(&info, &opt, "zisofs",
+ KEY_FLG, iso9660->opt.zisofs);
+
+ memcpy(wb_buffptr(a), info.s, info_size);
+ archive_string_free(&info);
+ return (wb_consume(a, info_size));
+}
+
+static int
+write_rr_ER(struct archive_write *a)
+{
+ unsigned char *p;
+
+ p = wb_buffptr(a);
+
+ memset(p, 0, LOGICAL_BLOCK_SIZE);
+ p[0] = 'E';
+ p[1] = 'R';
+ p[3] = 0x01;
+ p[2] = RRIP_ER_SIZE;
+ p[4] = RRIP_ER_ID_SIZE;
+ p[5] = RRIP_ER_DSC_SIZE;
+ p[6] = RRIP_ER_SRC_SIZE;
+ p[7] = 0x01;
+ memcpy(&p[8], rrip_identifier, p[4]);
+ memcpy(&p[8+p[4]], rrip_descriptor, p[5]);
+ memcpy(&p[8+p[4]+p[5]], rrip_source, p[6]);
+
+ return (wb_consume(a, LOGICAL_BLOCK_SIZE));
+}
+
+static void
+calculate_path_table_size(struct vdd *vdd)
+{
+ int depth, size;
+ struct path_table *pt;
+
+ pt = vdd->pathtbl;
+ size = 0;
+ for (depth = 0; depth < vdd->max_depth; depth++) {
+ struct isoent **ptbl;
+ int i, cnt;
+
+ if ((cnt = pt[depth].cnt) == 0)
+ break;
+
+ ptbl = pt[depth].sorted;
+ for (i = 0; i < cnt; i++) {
+ int len;
+
+ if (ptbl[i]->identifier == NULL)
+ len = 1; /* root directory */
+ else
+ len = ptbl[i]->id_len;
+ if (len & 0x01)
+ len++; /* Padding Field */
+ size += 8 + len;
+ }
+ }
+ vdd->path_table_size = size;
+ vdd->path_table_block =
+ ((size + PATH_TABLE_BLOCK_SIZE -1) /
+ PATH_TABLE_BLOCK_SIZE) *
+ (PATH_TABLE_BLOCK_SIZE / LOGICAL_BLOCK_SIZE);
+}
+
+static int
+_write_path_table(struct archive_write *a, int type_m, int depth,
+ struct vdd *vdd)
+{
+ unsigned char *bp, *wb;
+ struct isoent **ptbl;
+ size_t wbremaining;
+ int i, r, wsize;
+
+ if (vdd->pathtbl[depth].cnt == 0)
+ return (0);
+
+ wsize = 0;
+ wb = wb_buffptr(a);
+ wbremaining = wb_remaining(a);
+ bp = wb - 1;
+ ptbl = vdd->pathtbl[depth].sorted;
+ for (i = 0; i < vdd->pathtbl[depth].cnt; i++) {
+ struct isoent *np;
+ size_t len;
+
+ np = ptbl[i];
+ if (np->identifier == NULL)
+ len = 1; /* root directory */
+ else
+ len = np->id_len;
+ if (wbremaining - ((bp+1) - wb) < (len + 1 + 8)) {
+ r = wb_consume(a, (bp+1) - wb);
+ if (r < 0)
+ return (r);
+ wb = wb_buffptr(a);
+ wbremaining = wb_remaining(a);
+ bp = wb -1;
+ }
+ /* Length of Directory Identifier */
+ set_num_711(bp+1, len);
+ /* Extended Attribute Record Length */
+ set_num_711(bp+2, 0);
+ /* Location of Extent */
+ if (type_m)
+ set_num_732(bp+3, np->dir_location);
+ else
+ set_num_731(bp+3, np->dir_location);
+ /* Parent Directory Number */
+ if (type_m)
+ set_num_722(bp+7, np->parent->dir_number);
+ else
+ set_num_721(bp+7, np->parent->dir_number);
+ /* Directory Identifier */
+ if (np->identifier == NULL)
+ bp[9] = 0;
+ else
+ memcpy(&bp[9], np->identifier, len);
+ if (len & 0x01) {
+ /* Padding Field */
+ bp[9+len] = 0;
+ len++;
+ }
+ wsize += 8 + len;
+ bp += 8 + len;
+ }
+ if ((bp + 1) > wb) {
+ r = wb_consume(a, (bp+1)-wb);
+ if (r < 0)
+ return (r);
+ }
+ return (wsize);
+}
+
+static int
+write_path_table(struct archive_write *a, int type_m, struct vdd *vdd)
+{
+ int depth, r;
+ size_t path_table_size;
+
+ r = ARCHIVE_OK;
+ path_table_size = 0;
+ for (depth = 0; depth < vdd->max_depth; depth++) {
+ r = _write_path_table(a, type_m, depth, vdd);
+ if (r < 0)
+ return (r);
+ path_table_size += r;
+ }
+
+ /* Write padding data. */
+ path_table_size = path_table_size % PATH_TABLE_BLOCK_SIZE;
+ if (path_table_size > 0)
+ r = write_null(a, PATH_TABLE_BLOCK_SIZE - path_table_size);
+ return (r);
+}
+
+static int
+calculate_directory_descriptors(struct iso9660 *iso9660, struct vdd *vdd,
+ struct isoent *isoent, int depth)
+{
+ struct isoent **enttbl;
+ int bs, block, i;
+
+ block = 1;
+ bs = get_dir_rec_size(iso9660, isoent, DIR_REC_SELF, vdd->vdd_type);
+ bs += get_dir_rec_size(iso9660, isoent, DIR_REC_PARENT, vdd->vdd_type);
+
+ if (isoent->children.cnt <= 0 || (vdd->vdd_type != VDD_JOLIET &&
+ !iso9660->opt.rr && depth + 1 >= vdd->max_depth))
+ return (block);
+
+ enttbl = isoent->children_sorted;
+ for (i = 0; i < isoent->children.cnt; i++) {
+ struct isoent *np = enttbl[i];
+ struct isofile *file;
+
+ file = np->file;
+ if (file->hardlink_target != NULL)
+ file = file->hardlink_target;
+ file->cur_content = &(file->content);
+ do {
+ int dr_l;
+
+ dr_l = get_dir_rec_size(iso9660, np, DIR_REC_NORMAL,
+ vdd->vdd_type);
+ if ((bs + dr_l) > LOGICAL_BLOCK_SIZE) {
+ block ++;
+ bs = dr_l;
+ } else
+ bs += dr_l;
+ file->cur_content = file->cur_content->next;
+ } while (file->cur_content != NULL);
+ }
+ return (block);
+}
+
+static int
+_write_directory_descriptors(struct archive_write *a, struct vdd *vdd,
+ struct isoent *isoent, int depth)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ struct isoent **enttbl;
+ unsigned char *p, *wb;
+ int i, r;
+ int dr_l;
+
+ p = wb = wb_buffptr(a);
+#define WD_REMAINING (LOGICAL_BLOCK_SIZE - (p - wb))
+ p += set_directory_record(p, WD_REMAINING, isoent,
+ iso9660, DIR_REC_SELF, vdd->vdd_type);
+ p += set_directory_record(p, WD_REMAINING, isoent,
+ iso9660, DIR_REC_PARENT, vdd->vdd_type);
+
+ if (isoent->children.cnt <= 0 || (vdd->vdd_type != VDD_JOLIET &&
+ !iso9660->opt.rr && depth + 1 >= vdd->max_depth)) {
+ memset(p, 0, WD_REMAINING);
+ return (wb_consume(a, LOGICAL_BLOCK_SIZE));
+ }
+
+ enttbl = isoent->children_sorted;
+ for (i = 0; i < isoent->children.cnt; i++) {
+ struct isoent *np = enttbl[i];
+ struct isofile *file = np->file;
+
+ if (file->hardlink_target != NULL)
+ file = file->hardlink_target;
+ file->cur_content = &(file->content);
+ do {
+ dr_l = set_directory_record(p, WD_REMAINING,
+ np, iso9660, DIR_REC_NORMAL,
+ vdd->vdd_type);
+ if (dr_l == 0) {
+ memset(p, 0, WD_REMAINING);
+ r = wb_consume(a, LOGICAL_BLOCK_SIZE);
+ if (r < 0)
+ return (r);
+ p = wb = wb_buffptr(a);
+ dr_l = set_directory_record(p,
+ WD_REMAINING, np, iso9660,
+ DIR_REC_NORMAL, vdd->vdd_type);
+ }
+ p += dr_l;
+ file->cur_content = file->cur_content->next;
+ } while (file->cur_content != NULL);
+ }
+ memset(p, 0, WD_REMAINING);
+ return (wb_consume(a, LOGICAL_BLOCK_SIZE));
+}
+
+static int
+write_directory_descriptors(struct archive_write *a, struct vdd *vdd)
+{
+ struct isoent *np;
+ int depth, r;
+
+ depth = 0;
+ np = vdd->rootent;
+ do {
+ struct extr_rec *extr;
+
+ r = _write_directory_descriptors(a, vdd, np, depth);
+ if (r < 0)
+ return (r);
+ if (vdd->vdd_type != VDD_JOLIET) {
+ /*
+ * This extract record is used by SUSP,RRIP.
+ * Not for joliet.
+ */
+ for (extr = np->extr_rec_list.first;
+ extr != NULL;
+ extr = extr->next) {
+ unsigned char *wb;
+
+ wb = wb_buffptr(a);
+ memcpy(wb, extr->buf, extr->offset);
+ memset(wb + extr->offset, 0,
+ LOGICAL_BLOCK_SIZE - extr->offset);
+ r = wb_consume(a, LOGICAL_BLOCK_SIZE);
+ if (r < 0)
+ return (r);
+ }
+ }
+
+ if (np->subdirs.first != NULL && depth + 1 < vdd->max_depth) {
+ /* Enter to sub directories. */
+ np = np->subdirs.first;
+ depth++;
+ continue;
+ }
+ while (np != np->parent) {
+ if (np->drnext == NULL) {
+ /* Return to the parent directory. */
+ np = np->parent;
+ depth--;
+ } else {
+ np = np->drnext;
+ break;
+ }
+ }
+ } while (np != np->parent);
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Read file contents from the temporary file, and write it.
+ */
+static int
+write_file_contents(struct archive_write *a, int64_t offset, int64_t size)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ int r;
+
+ lseek(iso9660->temp_fd, offset, SEEK_SET);
+
+ while (size) {
+ size_t rsize;
+ ssize_t rs;
+ unsigned char *wb;
+
+ wb = wb_buffptr(a);
+ rsize = wb_remaining(a);
+ if (rsize > (size_t)size)
+ rsize = (size_t)size;
+ rs = read(iso9660->temp_fd, wb, rsize);
+ if (rs <= 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't read temporary file(%jd)", (intmax_t)rs);
+ return (ARCHIVE_FATAL);
+ }
+ size -= rs;
+ r = wb_consume(a, rs);
+ if (r < 0)
+ return (r);
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+write_file_descriptors(struct archive_write *a)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ struct isofile *file;
+ int64_t blocks, offset;
+ int r;
+
+ blocks = 0;
+ offset = 0;
+
+ /* Make the boot catalog contents, and write it. */
+ if (iso9660->el_torito.catalog != NULL) {
+ r = make_boot_catalog(a);
+ if (r < 0)
+ return (r);
+ }
+
+ /* Write the boot file contents. */
+ if (iso9660->el_torito.boot != NULL) {
+ struct isofile *file = iso9660->el_torito.boot->file;
+
+ blocks = file->content.blocks;
+ offset = file->content.offset_of_temp;
+ if (offset != 0) {
+ r = write_file_contents(a, offset,
+ blocks << LOGICAL_BLOCK_BITS);
+ if (r < 0)
+ return (r);
+ blocks = 0;
+ offset = 0;
+ }
+ }
+
+ /* Write out all file contents. */
+ for (file = iso9660->data_file_list.first;
+ file != NULL; file = file->datanext) {
+
+ if (!file->write_content)
+ continue;
+
+ if ((offset + (blocks << LOGICAL_BLOCK_BITS)) <
+ file->content.offset_of_temp) {
+ if (blocks > 0) {
+ r = write_file_contents(a, offset,
+ blocks << LOGICAL_BLOCK_BITS);
+ if (r < 0)
+ return (r);
+ }
+ blocks = 0;
+ offset = file->content.offset_of_temp;
+ }
+
+ file->cur_content = &(file->content);
+ do {
+ blocks += file->cur_content->blocks;
+ /* Next fragument */
+ file->cur_content = file->cur_content->next;
+ } while (file->cur_content != NULL);
+ }
+
+ /* Flush out remaining blocks. */
+ if (blocks > 0) {
+ r = write_file_contents(a, offset,
+ blocks << LOGICAL_BLOCK_BITS);
+ if (r < 0)
+ return (r);
+ }
+
+ return (ARCHIVE_OK);
+}
+
+static void
+isofile_init_entry_list(struct iso9660 *iso9660)
+{
+ iso9660->all_file_list.first = NULL;
+ iso9660->all_file_list.last = &(iso9660->all_file_list.first);
+}
+
+static void
+isofile_add_entry(struct iso9660 *iso9660, struct isofile *file)
+{
+ file->allnext = NULL;
+ *iso9660->all_file_list.last = file;
+ iso9660->all_file_list.last = &(file->allnext);
+}
+
+static void
+isofile_free_all_entries(struct iso9660 *iso9660)
+{
+ struct isofile *file, *file_next;
+
+ file = iso9660->all_file_list.first;
+ while (file != NULL) {
+ file_next = file->allnext;
+ isofile_free(file);
+ file = file_next;
+ }
+}
+
+static void
+isofile_init_entry_data_file_list(struct iso9660 *iso9660)
+{
+ iso9660->data_file_list.first = NULL;
+ iso9660->data_file_list.last = &(iso9660->data_file_list.first);
+}
+
+static void
+isofile_add_data_file(struct iso9660 *iso9660, struct isofile *file)
+{
+ file->datanext = NULL;
+ *iso9660->data_file_list.last = file;
+ iso9660->data_file_list.last = &(file->datanext);
+}
+
+
+static struct isofile *
+isofile_new(struct archive_write *a, struct archive_entry *entry)
+{
+ struct isofile *file;
+
+ file = calloc(1, sizeof(*file));
+ if (file == NULL)
+ return (NULL);
+
+ if (entry != NULL)
+ file->entry = archive_entry_clone(entry);
+ else
+ file->entry = archive_entry_new2(&a->archive);
+ if (file->entry == NULL) {
+ free(file);
+ return (NULL);
+ }
+ archive_string_init(&(file->parentdir));
+ archive_string_init(&(file->basename));
+ archive_string_init(&(file->basename_utf16));
+ archive_string_init(&(file->symlink));
+ file->cur_content = &(file->content);
+
+ return (file);
+}
+
+static void
+isofile_free(struct isofile *file)
+{
+ struct content *con, *tmp;
+
+ con = file->content.next;
+ while (con != NULL) {
+ tmp = con;
+ con = con->next;
+ free(tmp);
+ }
+ archive_entry_free(file->entry);
+ archive_string_free(&(file->parentdir));
+ archive_string_free(&(file->basename));
+ archive_string_free(&(file->basename_utf16));
+ archive_string_free(&(file->symlink));
+ free(file);
+}
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+static int
+cleanup_backslash_1(char *p)
+{
+ int mb, dos;
+
+ mb = dos = 0;
+ while (*p) {
+ if (*(unsigned char *)p > 127)
+ mb = 1;
+ if (*p == '\\') {
+ /* If we have not met any multi-byte characters,
+ * we can replace '\' with '/'. */
+ if (!mb)
+ *p = '/';
+ dos = 1;
+ }
+ p++;
+ }
+ if (!mb || !dos)
+ return (0);
+ return (-1);
+}
+
+static void
+cleanup_backslash_2(wchar_t *p)
+{
+
+ /* Convert a path-separator from '\' to '/' */
+ while (*p != L'\0') {
+ if (*p == L'\\')
+ *p = L'/';
+ p++;
+ }
+}
+#endif
+
+/*
+ * Generate a parent directory name and a base name from a pathname.
+ */
+static int
+isofile_gen_utility_names(struct archive_write *a, struct isofile *file)
+{
+ struct iso9660 *iso9660;
+ const char *pathname;
+ char *p, *dirname, *slash;
+ size_t len;
+ int ret = ARCHIVE_OK;
+
+ iso9660 = a->format_data;
+
+ archive_string_empty(&(file->parentdir));
+ archive_string_empty(&(file->basename));
+ archive_string_empty(&(file->basename_utf16));
+ archive_string_empty(&(file->symlink));
+
+ pathname = archive_entry_pathname(file->entry);
+ if (pathname == NULL || pathname[0] == '\0') {/* virtual root */
+ file->dircnt = 0;
+ return (ret);
+ }
+
+ /*
+ * Make a UTF-16BE basename if Joliet extension enabled.
+ */
+ if (iso9660->opt.joliet) {
+ const char *u16, *ulast;
+ size_t u16len, ulen_last;
+
+ if (iso9660->sconv_to_utf16be == NULL) {
+ iso9660->sconv_to_utf16be =
+ archive_string_conversion_to_charset(
+ &(a->archive), "UTF-16BE", 1);
+ if (iso9660->sconv_to_utf16be == NULL)
+ /* Couldn't allocate memory */
+ return (ARCHIVE_FATAL);
+ iso9660->sconv_from_utf16be =
+ archive_string_conversion_from_charset(
+ &(a->archive), "UTF-16BE", 1);
+ if (iso9660->sconv_from_utf16be == NULL)
+ /* Couldn't allocate memory */
+ return (ARCHIVE_FATAL);
+ }
+
+ /*
+ * Converte a filename to UTF-16BE.
+ */
+ if (0 > archive_entry_pathname_l(file->entry, &u16, &u16len,
+ iso9660->sconv_to_utf16be)) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for UTF-16BE");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "A filename cannot be converted to UTF-16BE;"
+ "You should disable making Joliet extension");
+ ret = ARCHIVE_WARN;
+ }
+
+ /*
+ * Make sure a path separator is not in the last;
+ * Remove trailing '/'.
+ */
+ while (u16len >= 2) {
+#if defined(_WIN32) || defined(__CYGWIN__)
+ if (u16[u16len-2] == 0 &&
+ (u16[u16len-1] == '/' || u16[u16len-1] == '\\'))
+#else
+ if (u16[u16len-2] == 0 && u16[u16len-1] == '/')
+#endif
+ {
+ u16len -= 2;
+ } else
+ break;
+ }
+
+ /*
+ * Find a basename in UTF-16BE.
+ */
+ ulast = u16;
+ u16len >>= 1;
+ ulen_last = u16len;
+ while (u16len > 0) {
+#if defined(_WIN32) || defined(__CYGWIN__)
+ if (u16[0] == 0 && (u16[1] == '/' || u16[1] == '\\'))
+#else
+ if (u16[0] == 0 && u16[1] == '/')
+#endif
+ {
+ ulast = u16 + 2;
+ ulen_last = u16len -1;
+ }
+ u16 += 2;
+ u16len --;
+ }
+ ulen_last <<= 1;
+ if (archive_string_ensure(&(file->basename_utf16),
+ ulen_last) == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for UTF-16BE");
+ return (ARCHIVE_FATAL);
+ }
+
+ /*
+ * Set UTF-16BE basename.
+ */
+ memcpy(file->basename_utf16.s, ulast, ulen_last);
+ file->basename_utf16.length = ulen_last;
+ }
+
+ archive_strcpy(&(file->parentdir), pathname);
+#if defined(_WIN32) || defined(__CYGWIN__)
+ /*
+ * Convert a path-separator from '\' to '/'
+ */
+ if (cleanup_backslash_1(file->parentdir.s) != 0) {
+ const wchar_t *wp = archive_entry_pathname_w(file->entry);
+ struct archive_wstring ws;
+
+ if (wp != NULL) {
+ archive_string_init(&ws);
+ archive_wstrcpy(&ws, wp);
+ cleanup_backslash_2(ws.s);
+ archive_string_empty(&(file->parentdir));
+ archive_string_append_from_wcs(&(file->parentdir),
+ ws.s, ws.length);
+ archive_wstring_free(&ws);
+ }
+ }
+#endif
+
+ len = file->parentdir.length;
+ p = dirname = file->parentdir.s;
+
+ /*
+ * Remove leading '/', '../' and './' elements
+ */
+ while (*p) {
+ if (p[0] == '/') {
+ p++;
+ len--;
+ } else if (p[0] != '.')
+ break;
+ else if (p[1] == '.' && p[2] == '/') {
+ p += 3;
+ len -= 3;
+ } else if (p[1] == '/' || (p[1] == '.' && p[2] == '\0')) {
+ p += 2;
+ len -= 2;
+ } else if (p[1] == '\0') {
+ p++;
+ len--;
+ } else
+ break;
+ }
+ if (p != dirname) {
+ memmove(dirname, p, len+1);
+ p = dirname;
+ }
+ /*
+ * Remove "/","/." and "/.." elements from tail.
+ */
+ while (len > 0) {
+ size_t ll = len;
+
+ if (len > 0 && p[len-1] == '/') {
+ p[len-1] = '\0';
+ len--;
+ }
+ if (len > 1 && p[len-2] == '/' && p[len-1] == '.') {
+ p[len-2] = '\0';
+ len -= 2;
+ }
+ if (len > 2 && p[len-3] == '/' && p[len-2] == '.' &&
+ p[len-1] == '.') {
+ p[len-3] = '\0';
+ len -= 3;
+ }
+ if (ll == len)
+ break;
+ }
+ while (*p) {
+ if (p[0] == '/') {
+ if (p[1] == '/')
+ /* Convert '//' --> '/' */
+ strcpy(p, p+1);
+ else if (p[1] == '.' && p[2] == '/')
+ /* Convert '/./' --> '/' */
+ strcpy(p, p+2);
+ else if (p[1] == '.' && p[2] == '.' && p[3] == '/') {
+ /* Convert 'dir/dir1/../dir2/'
+ * --> 'dir/dir2/'
+ */
+ char *rp = p -1;
+ while (rp >= dirname) {
+ if (*rp == '/')
+ break;
+ --rp;
+ }
+ if (rp > dirname) {
+ strcpy(rp, p+3);
+ p = rp;
+ } else {
+ strcpy(dirname, p+4);
+ p = dirname;
+ }
+ } else
+ p++;
+ } else
+ p++;
+ }
+ p = dirname;
+ len = strlen(p);
+
+ if (archive_entry_filetype(file->entry) == AE_IFLNK) {
+ /* Convert symlink name too. */
+ pathname = archive_entry_symlink(file->entry);
+ archive_strcpy(&(file->symlink), pathname);
+#if defined(_WIN32) || defined(__CYGWIN__)
+ /*
+ * Convert a path-separator from '\' to '/'
+ */
+ if (archive_strlen(&(file->symlink)) > 0 &&
+ cleanup_backslash_1(file->symlink.s) != 0) {
+ const wchar_t *wp =
+ archive_entry_symlink_w(file->entry);
+ struct archive_wstring ws;
+
+ if (wp != NULL) {
+ archive_string_init(&ws);
+ archive_wstrcpy(&ws, wp);
+ cleanup_backslash_2(ws.s);
+ archive_string_empty(&(file->symlink));
+ archive_string_append_from_wcs(
+ &(file->symlink),
+ ws.s, ws.length);
+ archive_wstring_free(&ws);
+ }
+ }
+#endif
+ }
+ /*
+ * - Count up directory elements.
+ * - Find out the position which points the last position of
+ * path separator('/').
+ */
+ slash = NULL;
+ file->dircnt = 0;
+ for (; *p != '\0'; p++)
+ if (*p == '/') {
+ slash = p;
+ file->dircnt++;
+ }
+ if (slash == NULL) {
+ /* The pathname doesn't have a parent directory. */
+ file->parentdir.length = len;
+ archive_string_copy(&(file->basename), &(file->parentdir));
+ archive_string_empty(&(file->parentdir));
+ *file->parentdir.s = '\0';
+ return (ret);
+ }
+
+ /* Make a basename from dirname and slash */
+ *slash = '\0';
+ file->parentdir.length = slash - dirname;
+ archive_strcpy(&(file->basename), slash + 1);
+ if (archive_entry_filetype(file->entry) == AE_IFDIR)
+ file->dircnt ++;
+ return (ret);
+}
+
+/*
+ * Register a entry to get a hardlink target.
+ */
+static int
+isofile_register_hardlink(struct archive_write *a, struct isofile *file)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ struct hardlink *hl;
+ const char *pathname;
+
+ archive_entry_set_nlink(file->entry, 1);
+ pathname = archive_entry_hardlink(file->entry);
+ if (pathname == NULL) {
+ /* This `file` is a hardlink target. */
+ hl = malloc(sizeof(*hl));
+ if (hl == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ hl->nlink = 1;
+ /* A hardlink target must be the first position. */
+ file->hlnext = NULL;
+ hl->file_list.first = file;
+ hl->file_list.last = &(file->hlnext);
+ __archive_rb_tree_insert_node(&(iso9660->hardlink_rbtree),
+ (struct archive_rb_node *)hl);
+ } else {
+ hl = (struct hardlink *)__archive_rb_tree_find_node(
+ &(iso9660->hardlink_rbtree), pathname);
+ if (hl != NULL) {
+ /* Insert `file` entry into the tail. */
+ file->hlnext = NULL;
+ *hl->file_list.last = file;
+ hl->file_list.last = &(file->hlnext);
+ hl->nlink++;
+ }
+ archive_entry_unset_size(file->entry);
+ }
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Hardlinked files have to have the same location of extent.
+ * We have to find out hardlink target entries for the entries
+ * which have a hardlink target name.
+ */
+static void
+isofile_connect_hardlink_files(struct iso9660 *iso9660)
+{
+ struct archive_rb_node *n;
+ struct hardlink *hl;
+ struct isofile *target, *nf;
+
+ ARCHIVE_RB_TREE_FOREACH(n, &(iso9660->hardlink_rbtree)) {
+ hl = (struct hardlink *)n;
+
+ /* The first entry must be a hardlink target. */
+ target = hl->file_list.first;
+ archive_entry_set_nlink(target->entry, hl->nlink);
+ /* Set a hardlink target to reference entries. */
+ for (nf = target->hlnext;
+ nf != NULL; nf = nf->hlnext) {
+ nf->hardlink_target = target;
+ archive_entry_set_nlink(nf->entry, hl->nlink);
+ }
+ }
+}
+
+static int
+isofile_hd_cmp_node(const struct archive_rb_node *n1,
+ const struct archive_rb_node *n2)
+{
+ const struct hardlink *h1 = (const struct hardlink *)n1;
+ const struct hardlink *h2 = (const struct hardlink *)n2;
+
+ return (strcmp(archive_entry_pathname(h1->file_list.first->entry),
+ archive_entry_pathname(h2->file_list.first->entry)));
+}
+
+static int
+isofile_hd_cmp_key(const struct archive_rb_node *n, const void *key)
+{
+ const struct hardlink *h = (const struct hardlink *)n;
+
+ return (strcmp(archive_entry_pathname(h->file_list.first->entry),
+ (const char *)key));
+}
+
+static void
+isofile_init_hardlinks(struct iso9660 *iso9660)
+{
+ static const struct archive_rb_tree_ops rb_ops = {
+ isofile_hd_cmp_node, isofile_hd_cmp_key,
+ };
+
+ __archive_rb_tree_init(&(iso9660->hardlink_rbtree), &rb_ops);
+}
+
+static void
+isofile_free_hardlinks(struct iso9660 *iso9660)
+{
+ struct archive_rb_node *n, *next;
+
+ for (n = ARCHIVE_RB_TREE_MIN(&(iso9660->hardlink_rbtree)); n;) {
+ next = __archive_rb_tree_iterate(&(iso9660->hardlink_rbtree),
+ n, ARCHIVE_RB_DIR_RIGHT);
+ free(n);
+ n = next;
+ }
+}
+
+static struct isoent *
+isoent_new(struct isofile *file)
+{
+ struct isoent *isoent;
+ static const struct archive_rb_tree_ops rb_ops = {
+ isoent_cmp_node, isoent_cmp_key,
+ };
+
+ isoent = calloc(1, sizeof(*isoent));
+ if (isoent == NULL)
+ return (NULL);
+ isoent->file = file;
+ isoent->children.first = NULL;
+ isoent->children.last = &(isoent->children.first);
+ __archive_rb_tree_init(&(isoent->rbtree), &rb_ops);
+ isoent->subdirs.first = NULL;
+ isoent->subdirs.last = &(isoent->subdirs.first);
+ isoent->extr_rec_list.first = NULL;
+ isoent->extr_rec_list.last = &(isoent->extr_rec_list.first);
+ isoent->extr_rec_list.current = NULL;
+ if (archive_entry_filetype(file->entry) == AE_IFDIR)
+ isoent->dir = 1;
+
+ return (isoent);
+}
+
+static inline struct isoent *
+isoent_clone(struct isoent *src)
+{
+ return (isoent_new(src->file));
+}
+
+static void
+_isoent_free(struct isoent *isoent)
+{
+ struct extr_rec *er, *er_next;
+
+ free(isoent->children_sorted);
+ free(isoent->identifier);
+ er = isoent->extr_rec_list.first;
+ while (er != NULL) {
+ er_next = er->next;
+ free(er);
+ er = er_next;
+ }
+ free(isoent);
+}
+
+static void
+isoent_free_all(struct isoent *isoent)
+{
+ struct isoent *np, *np_temp;
+
+ if (isoent == NULL)
+ return;
+ np = isoent;
+ for (;;) {
+ if (np->dir) {
+ if (np->children.first != NULL) {
+ /* Enter to sub directories. */
+ np = np->children.first;
+ continue;
+ }
+ }
+ for (;;) {
+ np_temp = np;
+ if (np->chnext == NULL) {
+ /* Return to the parent directory. */
+ np = np->parent;
+ _isoent_free(np_temp);
+ if (np == np_temp)
+ return;
+ } else {
+ np = np->chnext;
+ _isoent_free(np_temp);
+ break;
+ }
+ }
+ }
+}
+
+static struct isoent *
+isoent_create_virtual_dir(struct archive_write *a, struct iso9660 *iso9660, const char *pathname)
+{
+ struct isofile *file;
+ struct isoent *isoent;
+
+ file = isofile_new(a, NULL);
+ if (file == NULL)
+ return (NULL);
+ archive_entry_set_pathname(file->entry, pathname);
+ archive_entry_unset_mtime(file->entry);
+ archive_entry_unset_atime(file->entry);
+ archive_entry_unset_ctime(file->entry);
+ archive_entry_set_uid(file->entry, getuid());
+ archive_entry_set_gid(file->entry, getgid());
+ archive_entry_set_mode(file->entry, 0555 | AE_IFDIR);
+ archive_entry_set_nlink(file->entry, 2);
+ if (isofile_gen_utility_names(a, file) < ARCHIVE_WARN) {
+ isofile_free(file);
+ return (NULL);
+ }
+ isofile_add_entry(iso9660, file);
+
+ isoent = isoent_new(file);
+ if (isoent == NULL)
+ return (NULL);
+ isoent->dir = 1;
+ isoent->virtual = 1;
+
+ return (isoent);
+}
+
+static int
+isoent_cmp_node(const struct archive_rb_node *n1,
+ const struct archive_rb_node *n2)
+{
+ const struct isoent *e1 = (const struct isoent *)n1;
+ const struct isoent *e2 = (const struct isoent *)n2;
+
+ return (strcmp(e1->file->basename.s, e2->file->basename.s));
+}
+
+static int
+isoent_cmp_key(const struct archive_rb_node *n, const void *key)
+{
+ const struct isoent *e = (const struct isoent *)n;
+
+ return (strcmp(e->file->basename.s, (const char *)key));
+}
+
+static int
+isoent_add_child_head(struct isoent *parent, struct isoent *child)
+{
+
+ if (!__archive_rb_tree_insert_node(
+ &(parent->rbtree), (struct archive_rb_node *)child))
+ return (0);
+ if ((child->chnext = parent->children.first) == NULL)
+ parent->children.last = &(child->chnext);
+ parent->children.first = child;
+ parent->children.cnt++;
+ child->parent = parent;
+
+ /* Add a child to a sub-directory chain */
+ if (child->dir) {
+ if ((child->drnext = parent->subdirs.first) == NULL)
+ parent->subdirs.last = &(child->drnext);
+ parent->subdirs.first = child;
+ parent->subdirs.cnt++;
+ child->parent = parent;
+ } else
+ child->drnext = NULL;
+ return (1);
+}
+
+static int
+isoent_add_child_tail(struct isoent *parent, struct isoent *child)
+{
+
+ if (!__archive_rb_tree_insert_node(
+ &(parent->rbtree), (struct archive_rb_node *)child))
+ return (0);
+ child->chnext = NULL;
+ *parent->children.last = child;
+ parent->children.last = &(child->chnext);
+ parent->children.cnt++;
+ child->parent = parent;
+
+ /* Add a child to a sub-directory chain */
+ child->drnext = NULL;
+ if (child->dir) {
+ *parent->subdirs.last = child;
+ parent->subdirs.last = &(child->drnext);
+ parent->subdirs.cnt++;
+ child->parent = parent;
+ }
+ return (1);
+}
+
+static void
+isoent_remove_child(struct isoent *parent, struct isoent *child)
+{
+ struct isoent *ent;
+
+ /* Remove a child entry from children chain. */
+ ent = parent->children.first;
+ while (ent->chnext != child)
+ ent = ent->chnext;
+ if ((ent->chnext = ent->chnext->chnext) == NULL)
+ parent->children.last = &(ent->chnext);
+ parent->children.cnt--;
+
+ if (child->dir) {
+ /* Remove a child entry from sub-directory chain. */
+ ent = parent->subdirs.first;
+ while (ent->drnext != child)
+ ent = ent->drnext;
+ if ((ent->drnext = ent->drnext->drnext) == NULL)
+ parent->subdirs.last = &(ent->drnext);
+ parent->subdirs.cnt--;
+ }
+
+ __archive_rb_tree_remove_node(&(parent->rbtree),
+ (struct archive_rb_node *)child);
+}
+
+static int
+isoent_clone_tree(struct archive_write *a, struct isoent **nroot,
+ struct isoent *root)
+{
+ struct isoent *np, *xroot, *newent;
+
+ np = root;
+ xroot = NULL;
+ do {
+ newent = isoent_clone(np);
+ if (newent == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ if (xroot == NULL) {
+ *nroot = xroot = newent;
+ newent->parent = xroot;
+ } else
+ isoent_add_child_tail(xroot, newent);
+ if (np->dir && np->children.first != NULL) {
+ /* Enter to sub directories. */
+ np = np->children.first;
+ xroot = newent;
+ continue;
+ }
+ while (np != np->parent) {
+ if (np->chnext == NULL) {
+ /* Return to the parent directory. */
+ np = np->parent;
+ xroot = xroot->parent;
+ } else {
+ np = np->chnext;
+ break;
+ }
+ }
+ } while (np != np->parent);
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Setup directory locations.
+ */
+static void
+isoent_setup_directory_location(struct iso9660 *iso9660, int location,
+ struct vdd *vdd)
+{
+ struct isoent *np;
+ int depth;
+
+ vdd->total_dir_block = 0;
+ depth = 0;
+ np = vdd->rootent;
+ do {
+ int block;
+
+ np->dir_block = calculate_directory_descriptors(
+ iso9660, vdd, np, depth);
+ vdd->total_dir_block += np->dir_block;
+ np->dir_location = location;
+ location += np->dir_block;
+ block = extra_setup_location(np, location);
+ vdd->total_dir_block += block;
+ location += block;
+
+ if (np->subdirs.first != NULL && depth + 1 < vdd->max_depth) {
+ /* Enter to sub directories. */
+ np = np->subdirs.first;
+ depth++;
+ continue;
+ }
+ while (np != np->parent) {
+ if (np->drnext == NULL) {
+ /* Return to the parent directory. */
+ np = np->parent;
+ depth--;
+ } else {
+ np = np->drnext;
+ break;
+ }
+ }
+ } while (np != np->parent);
+}
+
+static void
+_isoent_file_location(struct iso9660 *iso9660, struct isoent *isoent,
+ int *symlocation)
+{
+ struct isoent **children;
+ int n;
+
+ if (isoent->children.cnt == 0)
+ return;
+
+ children = isoent->children_sorted;
+ for (n = 0; n < isoent->children.cnt; n++) {
+ struct isoent *np;
+ struct isofile *file;
+
+ np = children[n];
+ if (np->dir)
+ continue;
+ if (np == iso9660->el_torito.boot)
+ continue;
+ file = np->file;
+ if (file->boot || file->hardlink_target != NULL)
+ continue;
+ if (archive_entry_filetype(file->entry) == AE_IFLNK ||
+ file->content.size == 0) {
+ /*
+ * Do not point a valid location.
+ * Make sure entry is not hardlink file.
+ */
+ file->content.location = (*symlocation)--;
+ continue;
+ }
+
+ file->write_content = 1;
+ }
+}
+
+/*
+ * Setup file locations.
+ */
+static void
+isoent_setup_file_location(struct iso9660 *iso9660, int location)
+{
+ struct isoent *isoent;
+ struct isoent *np;
+ struct isofile *file;
+ size_t size;
+ int block;
+ int depth;
+ int joliet;
+ int symlocation;
+ int total_block;
+
+ iso9660->total_file_block = 0;
+ if ((isoent = iso9660->el_torito.catalog) != NULL) {
+ isoent->file->content.location = location;
+ block = (archive_entry_size(isoent->file->entry) +
+ LOGICAL_BLOCK_SIZE -1) >> LOGICAL_BLOCK_BITS;
+ location += block;
+ iso9660->total_file_block += block;
+ }
+ if ((isoent = iso9660->el_torito.boot) != NULL) {
+ isoent->file->content.location = location;
+ size = fd_boot_image_size(iso9660->el_torito.media_type);
+ if (size == 0)
+ size = archive_entry_size(isoent->file->entry);
+ block = (size + LOGICAL_BLOCK_SIZE -1) >> LOGICAL_BLOCK_BITS;
+ location += block;
+ iso9660->total_file_block += block;
+ isoent->file->content.blocks = block;
+ }
+
+ depth = 0;
+ symlocation = -16;
+ if (!iso9660->opt.rr && iso9660->opt.joliet) {
+ joliet = 1;
+ np = iso9660->joliet.rootent;
+ } else {
+ joliet = 0;
+ np = iso9660->primary.rootent;
+ }
+ do {
+ _isoent_file_location(iso9660, np, &symlocation);
+
+ if (np->subdirs.first != NULL &&
+ (joliet ||
+ ((iso9660->opt.rr == OPT_RR_DISABLED &&
+ depth + 2 < iso9660->primary.max_depth) ||
+ (iso9660->opt.rr &&
+ depth + 1 < iso9660->primary.max_depth)))) {
+ /* Enter to sub directories. */
+ np = np->subdirs.first;
+ depth++;
+ continue;
+ }
+ while (np != np->parent) {
+ if (np->drnext == NULL) {
+ /* Return to the parent directory. */
+ np = np->parent;
+ depth--;
+ } else {
+ np = np->drnext;
+ break;
+ }
+ }
+ } while (np != np->parent);
+
+ total_block = 0;
+ for (file = iso9660->data_file_list.first;
+ file != NULL; file = file->datanext) {
+
+ if (!file->write_content)
+ continue;
+
+ file->cur_content = &(file->content);
+ do {
+ file->cur_content->location = location;
+ location += file->cur_content->blocks;
+ total_block += file->cur_content->blocks;
+ /* Next fragument */
+ file->cur_content = file->cur_content->next;
+ } while (file->cur_content != NULL);
+ }
+ iso9660->total_file_block += total_block;
+}
+
+static int
+get_path_component(char *name, int n, const char *fn)
+{
+ char *p;
+ int l;
+
+ p = strchr(fn, '/');
+ if (p == NULL) {
+ if ((l = strlen(fn)) == 0)
+ return (0);
+ } else
+ l = p - fn;
+ if (l > n -1)
+ return (-1);
+ memcpy(name, fn, l);
+ name[l] = '\0';
+
+ return (l);
+}
+
+/*
+ * Add a new entry into the tree.
+ */
+static int
+isoent_tree(struct archive_write *a, struct isoent **isoentpp)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ char name[_MAX_FNAME];/* Included null terminator size. */
+#elif defined(NAME_MAX) && NAME_MAX >= 255
+ char name[NAME_MAX+1];
+#else
+ char name[256];
+#endif
+ struct iso9660 *iso9660 = a->format_data;
+ struct isoent *dent, *isoent, *np;
+ struct isofile *f1, *f2;
+ const char *fn, *p;
+ int l;
+
+ isoent = *isoentpp;
+ dent = iso9660->primary.rootent;
+ if (isoent->file->parentdir.length > 0)
+ fn = p = isoent->file->parentdir.s;
+ else
+ fn = p = "";
+
+ /*
+ * If the path of the parent directory of `isoent' entry is
+ * the same as the path of `cur_dirent', add isoent to
+ * `cur_dirent'.
+ */
+ if (archive_strlen(&(iso9660->cur_dirstr))
+ == archive_strlen(&(isoent->file->parentdir)) &&
+ strcmp(iso9660->cur_dirstr.s, fn) == 0) {
+ if (!isoent_add_child_tail(iso9660->cur_dirent, isoent)) {
+ np = (struct isoent *)__archive_rb_tree_find_node(
+ &(iso9660->cur_dirent->rbtree),
+ isoent->file->basename.s);
+ goto same_entry;
+ }
+ return (ARCHIVE_OK);
+ }
+
+ for (;;) {
+ l = get_path_component(name, sizeof(name), fn);
+ if (l == 0) {
+ np = NULL;
+ break;
+ }
+ if (l < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "A name buffer is too small");
+ _isoent_free(isoent);
+ return (ARCHIVE_FATAL);
+ }
+
+ np = isoent_find_child(dent, name);
+ if (np == NULL || fn[0] == '\0')
+ break;
+
+ /* Find next subdirectory. */
+ if (!np->dir) {
+ /* NOT Directory! */
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "`%s' is not directory, we cannot insert `%s' ",
+ archive_entry_pathname(np->file->entry),
+ archive_entry_pathname(isoent->file->entry));
+ _isoent_free(isoent);
+ *isoentpp = NULL;
+ return (ARCHIVE_FAILED);
+ }
+ fn += l;
+ if (fn[0] == '/')
+ fn++;
+ dent = np;
+ }
+ if (np == NULL) {
+ /*
+ * Create virtual parent directories.
+ */
+ while (fn[0] != '\0') {
+ struct isoent *vp;
+ struct archive_string as;
+
+ archive_string_init(&as);
+ archive_strncat(&as, p, fn - p + l);
+ if (as.s[as.length-1] == '/') {
+ as.s[as.length-1] = '\0';
+ as.length--;
+ }
+ vp = isoent_create_virtual_dir(a, iso9660, as.s);
+ if (vp == NULL) {
+ archive_string_free(&as);
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ _isoent_free(isoent);
+ *isoentpp = NULL;
+ return (ARCHIVE_FATAL);
+ }
+ archive_string_free(&as);
+
+ if (vp->file->dircnt > iso9660->dircnt_max)
+ iso9660->dircnt_max = vp->file->dircnt;
+ isoent_add_child_tail(dent, vp);
+ np = vp;
+
+ fn += l;
+ if (fn[0] == '/')
+ fn++;
+ l = get_path_component(name, sizeof(name), fn);
+ if (l < 0) {
+ archive_string_free(&as);
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "A name buffer is too small");
+ _isoent_free(isoent);
+ *isoentpp = NULL;
+ return (ARCHIVE_FATAL);
+ }
+ dent = np;
+ }
+
+ /* Found out the parent directory where isoent can be
+ * inserted. */
+ iso9660->cur_dirent = dent;
+ archive_string_empty(&(iso9660->cur_dirstr));
+ archive_string_ensure(&(iso9660->cur_dirstr),
+ archive_strlen(&(dent->file->parentdir)) +
+ archive_strlen(&(dent->file->basename)) + 2);
+ if (archive_strlen(&(dent->file->parentdir)) +
+ archive_strlen(&(dent->file->basename)) == 0)
+ iso9660->cur_dirstr.s[0] = 0;
+ else {
+ if (archive_strlen(&(dent->file->parentdir)) > 0) {
+ archive_string_copy(&(iso9660->cur_dirstr),
+ &(dent->file->parentdir));
+ archive_strappend_char(&(iso9660->cur_dirstr), '/');
+ }
+ archive_string_concat(&(iso9660->cur_dirstr),
+ &(dent->file->basename));
+ }
+
+ if (!isoent_add_child_tail(dent, isoent)) {
+ np = (struct isoent *)__archive_rb_tree_find_node(
+ &(dent->rbtree), isoent->file->basename.s);
+ goto same_entry;
+ }
+ return (ARCHIVE_OK);
+ }
+
+same_entry:
+ /*
+ * We have already has the entry the filename of which is
+ * the same.
+ */
+ f1 = np->file;
+ f2 = isoent->file;
+
+ /* If the file type of entries is different,
+ * we cannot handle it. */
+ if (archive_entry_filetype(f1->entry) !=
+ archive_entry_filetype(f2->entry)) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Found duplicate entries `%s' and its file type is "
+ "different",
+ archive_entry_pathname(f1->entry));
+ _isoent_free(isoent);
+ *isoentpp = NULL;
+ return (ARCHIVE_FAILED);
+ }
+
+ /* Swap file entries. */
+ np->file = f2;
+ isoent->file = f1;
+ np->virtual = 0;
+
+ _isoent_free(isoent);
+ *isoentpp = np;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Find a entry from `isoent'
+ */
+static struct isoent *
+isoent_find_child(struct isoent *isoent, const char *child_name)
+{
+ struct isoent *np;
+
+ np = (struct isoent *)__archive_rb_tree_find_node(
+ &(isoent->rbtree), child_name);
+ return (np);
+}
+
+/*
+ * Find a entry full-path of which is specified by `fn' parameter,
+ * in the tree.
+ */
+static struct isoent *
+isoent_find_entry(struct isoent *rootent, const char *fn)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ char name[_MAX_FNAME];/* Included null terminator size. */
+#elif defined(NAME_MAX) && NAME_MAX >= 255
+ char name[NAME_MAX+1];
+#else
+ char name[256];
+#endif
+ struct isoent *isoent, *np;
+ int l;
+
+ isoent = rootent;
+ np = NULL;
+ for (;;) {
+ l = get_path_component(name, sizeof(name), fn);
+ if (l == 0)
+ break;
+ fn += l;
+ if (fn[0] == '/')
+ fn++;
+
+ np = isoent_find_child(isoent, name);
+ if (np == NULL)
+ break;
+ if (fn[0] == '\0')
+ break;/* We found out the entry */
+
+ /* Try sub directory. */
+ isoent = np;
+ np = NULL;
+ if (!isoent->dir)
+ break;/* Not directory */
+ }
+
+ return (np);
+}
+
+/*
+ * Following idr_* functions are used for resolving duplicated filenames
+ * and unreceivable filenames to generate ISO9660/Joliet Identifiers.
+ */
+
+static void
+idr_relaxed_filenames(char *map)
+{
+ int i;
+
+ for (i = 0x21; i <= 0x2F; i++)
+ map[i] = 1;
+ for (i = 0x3A; i <= 0x41; i++)
+ map[i] = 1;
+ for (i = 0x5B; i <= 0x5E; i++)
+ map[i] = 1;
+ map[0x60] = 1;
+ for (i = 0x7B; i <= 0x7E; i++)
+ map[i] = 1;
+}
+
+static void
+idr_init(struct iso9660 *iso9660, struct vdd *vdd, struct idr *idr)
+{
+
+ idr->idrent_pool = NULL;
+ idr->pool_size = 0;
+ if (vdd->vdd_type != VDD_JOLIET) {
+ if (iso9660->opt.iso_level <= 3) {
+ memcpy(idr->char_map, d_characters_map,
+ sizeof(idr->char_map));
+ } else {
+ memcpy(idr->char_map, d1_characters_map,
+ sizeof(idr->char_map));
+ idr_relaxed_filenames(idr->char_map);
+ }
+ }
+}
+
+static void
+idr_cleanup(struct idr *idr)
+{
+ free(idr->idrent_pool);
+}
+
+static int
+idr_ensure_poolsize(struct archive_write *a, struct idr *idr,
+ int cnt)
+{
+
+ if (idr->pool_size < cnt) {
+ const int bk = (1 << 7) - 1;
+ int psize;
+
+ psize = (cnt + bk) & ~bk;
+ idr->idrent_pool = realloc(idr->idrent_pool,
+ sizeof(struct idrent) * psize);
+ if (idr->idrent_pool == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ idr->pool_size = psize;
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+idr_start(struct archive_write *a, struct idr *idr, int cnt, int ffmax,
+ int num_size, int null_size, const struct archive_rb_tree_ops *rbt_ops)
+{
+ int r;
+
+ (void)ffmax; /* UNUSED */
+
+ r = idr_ensure_poolsize(a, idr, cnt);
+ if (r != ARCHIVE_OK)
+ return (r);
+ __archive_rb_tree_init(&(idr->rbtree), rbt_ops);
+ idr->wait_list.first = NULL;
+ idr->wait_list.last = &(idr->wait_list.first);
+ idr->pool_idx = 0;
+ idr->num_size = num_size;
+ idr->null_size = null_size;
+ return (ARCHIVE_OK);
+}
+
+static void
+idr_register(struct idr *idr, struct isoent *isoent, int weight, int noff)
+{
+ struct idrent *idrent, *n;
+
+ idrent = &(idr->idrent_pool[idr->pool_idx++]);
+ idrent->wnext = idrent->avail = NULL;
+ idrent->isoent = isoent;
+ idrent->weight = weight;
+ idrent->noff = noff;
+ idrent->rename_num = 0;
+
+ if (!__archive_rb_tree_insert_node(&(idr->rbtree), &(idrent->rbnode))) {
+ n = (struct idrent *)__archive_rb_tree_find_node(
+ &(idr->rbtree), idrent->isoent);
+ if (n != NULL) {
+ /* this `idrent' needs to rename. */
+ idrent->avail = n;
+ *idr->wait_list.last = idrent;
+ idr->wait_list.last = &(idrent->wnext);
+ }
+ }
+}
+
+static void
+idr_extend_identifier(struct idrent *wnp, int numsize, int nullsize)
+{
+ unsigned char *p;
+ int wnp_ext_off;
+
+ wnp_ext_off = wnp->isoent->ext_off;
+ if (wnp->noff + numsize != wnp_ext_off) {
+ p = (unsigned char *)wnp->isoent->identifier;
+ /* Extend the filename; foo.c --> foo___.c */
+ memmove(p + wnp->noff + numsize, p + wnp_ext_off,
+ wnp->isoent->ext_len + nullsize);
+ wnp->isoent->ext_off = wnp_ext_off = wnp->noff + numsize;
+ wnp->isoent->id_len = wnp_ext_off + wnp->isoent->ext_len;
+ }
+}
+
+static void
+idr_resolve(struct idr *idr, void (*fsetnum)(unsigned char *p, int num))
+{
+ struct idrent *n;
+ unsigned char *p;
+
+ for (n = idr->wait_list.first; n != NULL; n = n->wnext) {
+ idr_extend_identifier(n, idr->num_size, idr->null_size);
+ p = (unsigned char *)n->isoent->identifier + n->noff;
+ do {
+ fsetnum(p, n->avail->rename_num++);
+ } while (!__archive_rb_tree_insert_node(
+ &(idr->rbtree), &(n->rbnode)));
+ }
+}
+
+static void
+idr_set_num(unsigned char *p, int num)
+{
+ static const char xdig[] = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
+ 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
+ 'U', 'V', 'W', 'X', 'Y', 'Z'
+ };
+
+ num %= sizeof(xdig) * sizeof(xdig) * sizeof(xdig);
+ p[0] = xdig[(num / (sizeof(xdig) * sizeof(xdig)))];
+ num %= sizeof(xdig) * sizeof(xdig);
+ p[1] = xdig[ (num / sizeof(xdig))];
+ num %= sizeof(xdig);
+ p[2] = xdig[num];
+}
+
+static void
+idr_set_num_beutf16(unsigned char *p, int num)
+{
+ static const uint16_t xdig[] = {
+ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035,
+ 0x0036, 0x0037, 0x0038, 0x0039,
+ 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046,
+ 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C,
+ 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052,
+ 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+ 0x0059, 0x005A
+ };
+#define XDIG_CNT (sizeof(xdig)/sizeof(xdig[0]))
+
+ num %= XDIG_CNT * XDIG_CNT * XDIG_CNT;
+ archive_be16enc(p, xdig[(num / (XDIG_CNT * XDIG_CNT))]);
+ num %= XDIG_CNT * XDIG_CNT;
+ archive_be16enc(p+2, xdig[ (num / XDIG_CNT)]);
+ num %= XDIG_CNT;
+ archive_be16enc(p+4, xdig[num]);
+}
+
+/*
+ * Generate ISO9660 Identifier.
+ */
+static int
+isoent_gen_iso9660_identifier(struct archive_write *a, struct isoent *isoent,
+ struct idr *idr)
+{
+ struct iso9660 *iso9660;
+ struct isoent *np;
+ char *p;
+ int l, r;
+ const char *char_map;
+ char allow_ldots, allow_multidot, allow_period, allow_vernum;
+ int fnmax, ffmax, dnmax;
+ static const struct archive_rb_tree_ops rb_ops = {
+ isoent_cmp_node_iso9660, isoent_cmp_key_iso9660
+ };
+
+ if (isoent->children.cnt == 0)
+ return (0);
+
+ iso9660 = a->format_data;
+ char_map = idr->char_map;
+ if (iso9660->opt.iso_level <= 3) {
+ allow_ldots = 0;
+ allow_multidot = 0;
+ allow_period = 1;
+ allow_vernum = iso9660->opt.allow_vernum;
+ if (iso9660->opt.iso_level == 1) {
+ fnmax = 8;
+ ffmax = 12;/* fnmax + '.' + 3 */
+ dnmax = 8;
+ } else {
+ fnmax = 30;
+ ffmax = 31;
+ dnmax = 31;
+ }
+ } else {
+ allow_ldots = allow_multidot = 1;
+ allow_period = allow_vernum = 0;
+ if (iso9660->opt.rr)
+ /*
+ * MDR : The maximum size of Directory Record(254).
+ * DRL : A Directory Record Length(33).
+ * CE : A size of SUSP CE System Use Entry(28).
+ * MDR - DRL - CE = 254 - 33 - 28 = 193.
+ */
+ fnmax = ffmax = dnmax = 193;
+ else
+ /*
+ * XA : CD-ROM XA System Use Extension
+ * Information(14).
+ * MDR - DRL - XA = 254 - 33 -14 = 207.
+ */
+ fnmax = ffmax = dnmax = 207;
+ }
+
+ r = idr_start(a, idr, isoent->children.cnt, ffmax, 3, 1, &rb_ops);
+ if (r < 0)
+ return (r);
+
+ for (np = isoent->children.first; np != NULL; np = np->chnext) {
+ char *dot, *xdot;
+ int ext_off, noff, weight;
+
+ l = np->file->basename.length;
+ p = malloc(l+31+2+1);
+ if (p == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ memcpy(p, np->file->basename.s, l);
+ p[l] = '\0';
+ np->identifier = p;
+
+ dot = xdot = NULL;
+ if (!allow_ldots) {
+ /*
+ * If there is a '.' character at the first byte,
+ * it has to be replaced by '_' character.
+ */
+ if (*p == '.')
+ *p++ = '_';
+ }
+ for (;*p; p++) {
+ if (*p & 0x80) {
+ *p = '_';
+ continue;
+ }
+ if (char_map[(unsigned char)*p]) {
+ /* if iso-level is '4', a character '.' is
+ * allowed by char_map. */
+ if (*p == '.') {
+ xdot = dot;
+ dot = p;
+ }
+ continue;
+ }
+ if (*p >= 'a' && *p <= 'z') {
+ *p -= 'a' - 'A';
+ continue;
+ }
+ if (*p == '.') {
+ xdot = dot;
+ dot = p;
+ if (allow_multidot)
+ continue;
+ }
+ *p = '_';
+ }
+ p = np->identifier;
+ weight = -1;
+ if (dot == NULL) {
+ int nammax;
+
+ if (np->dir)
+ nammax = dnmax;
+ else
+ nammax = fnmax;
+
+ if (l > nammax) {
+ p[nammax] = '\0';
+ weight = nammax;
+ ext_off = nammax;
+ } else
+ ext_off = l;
+ } else {
+ *dot = '.';
+ ext_off = dot - p;
+
+ if (iso9660->opt.iso_level == 1) {
+ if (dot - p <= 8) {
+ if (strlen(dot) > 4) {
+ /* A length of a file extension
+ * must be less than 4 */
+ dot[4] = '\0';
+ weight = 0;
+ }
+ } else {
+ p[8] = dot[0];
+ p[9] = dot[1];
+ p[10] = dot[2];
+ p[11] = dot[3];
+ p[12] = '\0';
+ weight = 8;
+ ext_off = 8;
+ }
+ } else if (np->dir) {
+ if (l > dnmax) {
+ p[dnmax] = '\0';
+ weight = dnmax;
+ if (ext_off > dnmax)
+ ext_off = dnmax;
+ }
+ } else if (l > ffmax) {
+ int extlen = strlen(dot);
+ int xdoff;
+
+ if (xdot != NULL)
+ xdoff = xdot - p;
+ else
+ xdoff = 0;
+
+ if (extlen > 1 && xdoff < fnmax-1) {
+ int off;
+
+ if (extlen > ffmax)
+ extlen = ffmax;
+ off = ffmax - extlen;
+ if (off == 0) {
+ /* A dot('.') character
+ * does't place to the first
+ * byte of identifier. */
+ off ++;
+ extlen --;
+ }
+ memmove(p+off, dot, extlen);
+ p[ffmax] = '\0';
+ ext_off = off;
+ weight = off;
+#ifdef COMPAT_MKISOFS
+ } else if (xdoff >= fnmax-1) {
+ /* Simulate a bug(?) of mkisofs. */
+ p[fnmax-1] = '\0';
+ ext_off = fnmax-1;
+ weight = fnmax-1;
+#endif
+ } else {
+ p[fnmax] = '\0';
+ ext_off = fnmax;
+ weight = fnmax;
+ }
+ }
+ }
+ /* Save an offset of a file name extension to sort files. */
+ np->ext_off = ext_off;
+ np->ext_len = strlen(&p[ext_off]);
+ np->id_len = l = ext_off + np->ext_len;
+
+ /* Make an offset of the number which is used to be set
+ * hexadecimal number to avoid duplicate identififier. */
+ if (iso9660->opt.iso_level == 1) {
+ if (ext_off >= 5)
+ noff = 5;
+ else
+ noff = ext_off;
+ } else {
+ if (l == ffmax)
+ noff = ext_off - 3;
+ else if (l == ffmax-1)
+ noff = ext_off - 2;
+ else if (l == ffmax-2)
+ noff = ext_off - 1;
+ else
+ noff = ext_off;
+ }
+ /* Register entry to the identifier resolver. */
+ idr_register(idr, np, weight, noff);
+ }
+
+ /* Resolve duplicate identifier. */
+ idr_resolve(idr, idr_set_num);
+
+ /* Add a period and a version number to identifiers. */
+ for (np = isoent->children.first; np != NULL; np = np->chnext) {
+ if (!np->dir && np->rr_child == NULL) {
+ p = np->identifier + np->ext_off + np->ext_len;
+ if (np->ext_len == 0 && allow_period) {
+ *p++ = '.';
+ np->ext_len = 1;
+ }
+ if (np->ext_len == 1 && !allow_period) {
+ *--p = '\0';
+ np->ext_len = 0;
+ }
+ np->id_len = np->ext_off + np->ext_len;
+ if (allow_vernum) {
+ *p++ = ';';
+ *p++ = '1';
+ np->id_len += 2;
+ }
+ *p = '\0';
+ } else
+ np->id_len = np->ext_off + np->ext_len;
+ np->mb_len = np->id_len;
+ }
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Generate Joliet Identifier.
+ */
+static int
+isoent_gen_joliet_identifier(struct archive_write *a, struct isoent *isoent,
+ struct idr *idr)
+{
+ struct iso9660 *iso9660;
+ struct isoent *np;
+ unsigned char *p;
+ size_t l;
+ int r;
+ int ffmax, parent_len;
+ static const struct archive_rb_tree_ops rb_ops = {
+ isoent_cmp_node_joliet, isoent_cmp_key_joliet
+ };
+
+ if (isoent->children.cnt == 0)
+ return (0);
+
+ iso9660 = a->format_data;
+ if (iso9660->opt.joliet == OPT_JOLIET_LONGNAME)
+ ffmax = 206;
+ else
+ ffmax = 128;
+
+ r = idr_start(a, idr, isoent->children.cnt, ffmax, 6, 2, &rb_ops);
+ if (r < 0)
+ return (r);
+
+ parent_len = 1;
+ for (np = isoent; np->parent != np; np = np->parent)
+ parent_len += np->mb_len + 1;
+
+ for (np = isoent->children.first; np != NULL; np = np->chnext) {
+ unsigned char *dot;
+ int ext_off, noff, weight;
+ size_t lt;
+
+ if ((int)(l = np->file->basename_utf16.length) > ffmax)
+ l = ffmax;
+
+ p = malloc((l+1)*2);
+ if (p == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ memcpy(p, np->file->basename_utf16.s, l);
+ p[l] = 0;
+ p[l+1] = 0;
+
+ np->identifier = (char *)p;
+ lt = l;
+ dot = p + l;
+ weight = 0;
+ while (lt > 0) {
+ if (!joliet_allowed_char(p[0], p[1]))
+ archive_be16enc(p, 0x005F); /* '_' */
+ else if (p[0] == 0 && p[1] == 0x2E) /* '.' */
+ dot = p;
+ p += 2;
+ lt -= 2;
+ }
+ ext_off = dot - (unsigned char *)np->identifier;
+ np->ext_off = ext_off;
+ np->ext_len = l - ext_off;
+ np->id_len = l;
+
+ /*
+ * Get a length of MBS of a full-pathname.
+ */
+ if ((int)np->file->basename_utf16.length > ffmax) {
+ archive_strncpy_in_locale(&iso9660->mbs,
+ (const char *)np->identifier, l,
+ iso9660->sconv_from_utf16be);
+ np->mb_len = iso9660->mbs.length;
+ if (np->mb_len != (int)np->file->basename.length)
+ weight = np->mb_len;
+ } else
+ np->mb_len = np->file->basename.length;
+
+ /* If a length of full-pathname is longer than 240 bytes,
+ * it violates Joliet extensions regulation. */
+ if (parent_len + np->mb_len > 240) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "The regulation of Joliet extensions;"
+ " A length of a full-pathname of `%s' is "
+ "longer than 240 bytes, (p=%d, b=%d)",
+ archive_entry_pathname(np->file->entry),
+ (int)parent_len, (int)np->mb_len);
+ return (ARCHIVE_FATAL);
+ }
+
+ /* Make an offset of the number which is used to be set
+ * hexadecimal number to avoid duplicate identifier. */
+ if ((int)l == ffmax)
+ noff = ext_off - 6;
+ else if ((int)l == ffmax-2)
+ noff = ext_off - 4;
+ else if ((int)l == ffmax-4)
+ noff = ext_off - 2;
+ else
+ noff = ext_off;
+ /* Register entry to the identifier resolver. */
+ idr_register(idr, np, weight, noff);
+ }
+
+ /* Resolve duplicate identifier with Joliet Volume. */
+ idr_resolve(idr, idr_set_num_beutf16);
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * This comparing rule is according to ISO9660 Standard 9.3
+ */
+static int
+isoent_cmp_iso9660_identifier(const struct isoent *p1, const struct isoent *p2)
+{
+ const char *s1, *s2;
+ int cmp;
+ int l;
+
+ s1 = p1->identifier;
+ s2 = p2->identifier;
+
+ /* Compare File Name */
+ l = p1->ext_off;
+ if (l > p2->ext_off)
+ l = p2->ext_off;
+ cmp = memcmp(s1, s2, l);
+ if (cmp != 0)
+ return (cmp);
+ if (p1->ext_off < p2->ext_off) {
+ s2 += l;
+ l = p2->ext_off - p1->ext_off;
+ while (l--)
+ if (0x20 != *s2++)
+ return (0x20
+ - *(const unsigned char *)(s2 - 1));
+ } else if (p1->ext_off > p2->ext_off) {
+ s1 += l;
+ l = p1->ext_off - p2->ext_off;
+ while (l--)
+ if (0x20 != *s1++)
+ return (*(const unsigned char *)(s1 - 1)
+ - 0x20);
+ }
+ /* Compare File Name Extension */
+ if (p1->ext_len == 0 && p2->ext_len == 0)
+ return (0);
+ if (p1->ext_len == 1 && p2->ext_len == 1)
+ return (0);
+ if (p1->ext_len <= 1)
+ return (-1);
+ if (p2->ext_len <= 1)
+ return (1);
+ l = p1->ext_len;
+ if (l > p2->ext_len)
+ l = p2->ext_len;
+ s1 = p1->identifier + p1->ext_off;
+ s2 = p2->identifier + p2->ext_off;
+ if (l > 1) {
+ cmp = memcmp(s1, s2, l);
+ if (cmp != 0)
+ return (cmp);
+ }
+ if (p1->ext_len < p2->ext_len) {
+ s2 += l;
+ l = p2->ext_len - p1->ext_len;
+ while (l--)
+ if (0x20 != *s2++)
+ return (0x20
+ - *(const unsigned char *)(s2 - 1));
+ } else if (p1->ext_len < p2->ext_len) {
+ s1 += l;
+ l = p1->ext_len - p2->ext_len;
+ while (l--)
+ if (0x20 != *s1++)
+ return (*(const unsigned char *)(s1 - 1)
+ - 0x20);
+ }
+ /* Compare File Version Number */
+ /* No operation. The File Version Number is always one. */
+
+ return (cmp);
+}
+
+static int
+isoent_cmp_node_iso9660(const struct archive_rb_node *n1,
+ const struct archive_rb_node *n2)
+{
+ const struct idrent *e1 = (const struct idrent *)n1;
+ const struct idrent *e2 = (const struct idrent *)n2;
+
+ return (isoent_cmp_iso9660_identifier(e2->isoent, e1->isoent));
+}
+
+static int
+isoent_cmp_key_iso9660(const struct archive_rb_node *node, const void *key)
+{
+ const struct isoent *isoent = (const struct isoent *)key;
+ const struct idrent *idrent = (const struct idrent *)node;
+
+ return (isoent_cmp_iso9660_identifier(isoent, idrent->isoent));
+}
+
+static int
+isoent_cmp_joliet_identifier(const struct isoent *p1, const struct isoent *p2)
+{
+ const unsigned char *s1, *s2;
+ int cmp;
+ int l;
+
+ s1 = (const unsigned char *)p1->identifier;
+ s2 = (const unsigned char *)p2->identifier;
+
+ /* Compare File Name */
+ l = p1->ext_off;
+ if (l > p2->ext_off)
+ l = p2->ext_off;
+ cmp = memcmp(s1, s2, l);
+ if (cmp != 0)
+ return (cmp);
+ if (p1->ext_off < p2->ext_off) {
+ s2 += l;
+ l = p2->ext_off - p1->ext_off;
+ while (l--)
+ if (0 != *s2++)
+ return (- *(const unsigned char *)(s2 - 1));
+ } else if (p1->ext_off > p2->ext_off) {
+ s1 += l;
+ l = p1->ext_off - p2->ext_off;
+ while (l--)
+ if (0 != *s1++)
+ return (*(const unsigned char *)(s1 - 1));
+ }
+ /* Compare File Name Extension */
+ if (p1->ext_len == 0 && p2->ext_len == 0)
+ return (0);
+ if (p1->ext_len == 2 && p2->ext_len == 2)
+ return (0);
+ if (p1->ext_len <= 2)
+ return (-1);
+ if (p2->ext_len <= 2)
+ return (1);
+ l = p1->ext_len;
+ if (l > p2->ext_len)
+ l = p2->ext_len;
+ s1 = (unsigned char *)(p1->identifier + p1->ext_off);
+ s2 = (unsigned char *)(p2->identifier + p2->ext_off);
+ if (l > 1) {
+ cmp = memcmp(s1, s2, l);
+ if (cmp != 0)
+ return (cmp);
+ }
+ if (p1->ext_len < p2->ext_len) {
+ s2 += l;
+ l = p2->ext_len - p1->ext_len;
+ while (l--)
+ if (0 != *s2++)
+ return (- *(const unsigned char *)(s2 - 1));
+ } else if (p1->ext_len < p2->ext_len) {
+ s1 += l;
+ l = p1->ext_len - p2->ext_len;
+ while (l--)
+ if (0 != *s1++)
+ return (*(const unsigned char *)(s1 - 1));
+ }
+ /* Compare File Version Number */
+ /* No operation. The File Version Number is always one. */
+
+ return (cmp);
+}
+
+static int
+isoent_cmp_node_joliet(const struct archive_rb_node *n1,
+ const struct archive_rb_node *n2)
+{
+ const struct idrent *e1 = (const struct idrent *)n1;
+ const struct idrent *e2 = (const struct idrent *)n2;
+
+ return (isoent_cmp_joliet_identifier(e2->isoent, e1->isoent));
+}
+
+static int
+isoent_cmp_key_joliet(const struct archive_rb_node *node, const void *key)
+{
+ const struct isoent *isoent = (const struct isoent *)key;
+ const struct idrent *idrent = (const struct idrent *)node;
+
+ return (isoent_cmp_joliet_identifier(isoent, idrent->isoent));
+}
+
+static int
+isoent_make_sorted_files(struct archive_write *a, struct isoent *isoent,
+ struct idr *idr)
+{
+ struct archive_rb_node *rn;
+ struct isoent **children;
+
+ children = malloc(isoent->children.cnt * sizeof(struct isoent *));
+ if (children == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ isoent->children_sorted = children;
+
+ ARCHIVE_RB_TREE_FOREACH(rn, &(idr->rbtree)) {
+ struct idrent *idrent = (struct idrent *)rn;
+ *children ++ = idrent->isoent;
+ }
+ return (ARCHIVE_OK);
+}
+
+/*
+ * - Generate ISO9660 and Joliet identifiers from basenames.
+ * - Sort files by each directory.
+ */
+static int
+isoent_traverse_tree(struct archive_write *a, struct vdd* vdd)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ struct isoent *np;
+ struct idr idr;
+ int depth;
+ int r;
+ int (*genid)(struct archive_write *a, struct isoent *isoent,
+ struct idr *idr);
+
+ idr_init(iso9660, vdd, &idr);
+ np = vdd->rootent;
+ depth = 0;
+ if (vdd->vdd_type == VDD_JOLIET)
+ genid = isoent_gen_joliet_identifier;
+ else
+ genid = isoent_gen_iso9660_identifier;
+ do {
+ if (np->virtual &&
+ !archive_entry_mtime_is_set(np->file->entry)) {
+ /* Set properly times to virtual directory */
+ archive_entry_set_mtime(np->file->entry,
+ iso9660->birth_time, 0);
+ archive_entry_set_atime(np->file->entry,
+ iso9660->birth_time, 0);
+ archive_entry_set_ctime(np->file->entry,
+ iso9660->birth_time, 0);
+ }
+ if (np->children.first != NULL) {
+ if (vdd->vdd_type != VDD_JOLIET &&
+ !iso9660->opt.rr && depth + 1 >= vdd->max_depth) {
+ if (np->children.cnt > 0)
+ iso9660->directories_too_deep = np;
+ } else {
+ /* Generate Identifier */
+ r = genid(a, np, &idr);
+ if (r < 0)
+ goto exit_traverse_tree;
+ r = isoent_make_sorted_files(a, np, &idr);
+ if (r < 0)
+ goto exit_traverse_tree;
+
+ if (np->subdirs.first != NULL &&
+ depth + 1 < vdd->max_depth) {
+ /* Enter to sub directories. */
+ np = np->subdirs.first;
+ depth++;
+ continue;
+ }
+ }
+ }
+ while (np != np->parent) {
+ if (np->drnext == NULL) {
+ /* Return to the parent directory. */
+ np = np->parent;
+ depth--;
+ } else {
+ np = np->drnext;
+ break;
+ }
+ }
+ } while (np != np->parent);
+
+ r = ARCHIVE_OK;
+exit_traverse_tree:
+ idr_cleanup(&idr);
+
+ return (r);
+}
+
+/*
+ * Collect directory entries into path_table by a directory depth.
+ */
+static int
+isoent_collect_dirs(struct vdd *vdd, struct isoent *rootent, int depth)
+{
+ struct isoent *np;
+
+ if (rootent == NULL)
+ rootent = vdd->rootent;
+ np = rootent;
+ do {
+ /* Register current directory to pathtable. */
+ path_table_add_entry(&(vdd->pathtbl[depth]), np);
+
+ if (np->subdirs.first != NULL && depth + 1 < vdd->max_depth) {
+ /* Enter to sub directories. */
+ np = np->subdirs.first;
+ depth++;
+ continue;
+ }
+ while (np != rootent) {
+ if (np->drnext == NULL) {
+ /* Return to the parent directory. */
+ np = np->parent;
+ depth--;
+ } else {
+ np = np->drnext;
+ break;
+ }
+ }
+ } while (np != rootent);
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * The entry whose number of levels in a directory hierarchy is
+ * large than eight relocate to rr_move directory.
+ */
+static int
+isoent_rr_move_dir(struct archive_write *a, struct isoent **rr_moved,
+ struct isoent *isoent, struct isoent **newent)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ struct isoent *rrmoved, *mvent, *np;
+
+ if ((rrmoved = *rr_moved) == NULL) {
+ struct isoent *rootent = iso9660->primary.rootent;
+ /* There isn't rr_move entry.
+ * Create rr_move entry and insert it into the root entry.
+ */
+ rrmoved = isoent_create_virtual_dir(a, iso9660, "rr_moved");
+ if (rrmoved == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ /* Add "rr_moved" entry to the root entry. */
+ isoent_add_child_head(rootent, rrmoved);
+ archive_entry_set_nlink(rootent->file->entry,
+ archive_entry_nlink(rootent->file->entry) + 1);
+ /* Register "rr_moved" entry to second level pathtable. */
+ path_table_add_entry(&(iso9660->primary.pathtbl[1]), rrmoved);
+ /* Save rr_moved. */
+ *rr_moved = rrmoved;
+ }
+ /*
+ * Make a clone of isoent which is going to be relocated
+ * to rr_moved.
+ */
+ mvent = isoent_clone(isoent);
+ if (mvent == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ /* linking.. and use for creating "CL", "PL" and "RE" */
+ mvent->rr_parent = isoent->parent;
+ isoent->rr_child = mvent;
+ /*
+ * Move subdirectories from the isoent to mvent
+ */
+ if (isoent->children.first != NULL) {
+ *mvent->children.last = isoent->children.first;
+ mvent->children.last = isoent->children.last;
+ }
+ for (np = mvent->children.first; np != NULL; np = np->chnext)
+ np->parent = mvent;
+ mvent->children.cnt = isoent->children.cnt;
+ isoent->children.cnt = 0;
+ isoent->children.first = NULL;
+ isoent->children.last = &isoent->children.first;
+
+ if (isoent->subdirs.first != NULL) {
+ *mvent->subdirs.last = isoent->subdirs.first;
+ mvent->subdirs.last = isoent->subdirs.last;
+ }
+ mvent->subdirs.cnt = isoent->subdirs.cnt;
+ isoent->subdirs.cnt = 0;
+ isoent->subdirs.first = NULL;
+ isoent->subdirs.last = &isoent->subdirs.first;
+
+ /*
+ * The mvent becomes a child of the rr_moved entry.
+ */
+ isoent_add_child_tail(rrmoved, mvent);
+ archive_entry_set_nlink(rrmoved->file->entry,
+ archive_entry_nlink(rrmoved->file->entry) + 1);
+ /*
+ * This entry which relocated to the rr_moved directory
+ * has to set the flag as a file.
+ * See also RRIP 4.1.5.1 Description of the "CL" System Use Entry.
+ */
+ isoent->dir = 0;
+
+ *newent = mvent;
+
+ return (ARCHIVE_OK);
+}
+
+static int
+isoent_rr_move(struct archive_write *a)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ struct path_table *pt;
+ struct isoent *rootent, *rr_moved;
+ struct isoent *np, *last;
+ int r;
+
+ pt = &(iso9660->primary.pathtbl[MAX_DEPTH-1]);
+ /* Theare aren't level 8 directories reaching a deepr level. */
+ if (pt->cnt == 0)
+ return (ARCHIVE_OK);
+
+ rootent = iso9660->primary.rootent;
+ /* If "rr_moved" directory is already existing,
+ * we have to use it. */
+ rr_moved = isoent_find_child(rootent, "rr_moved");
+ if (rr_moved != NULL &&
+ rr_moved != rootent->children.first) {
+ /*
+ * It's necessary that rr_move is the first entry
+ * of the root.
+ */
+ /* Remove "rr_moved" entry from children chain. */
+ isoent_remove_child(rootent, rr_moved);
+
+ /* Add "rr_moved" entry into the head of children chain. */
+ isoent_add_child_head(rootent, rr_moved);
+ }
+
+ /*
+ * Check level 8 path_table.
+ * If find out sub directory entries, that entries move to rr_move.
+ */
+ np = pt->first;
+ while (np != NULL) {
+ last = path_table_last_entry(pt);
+ for (; np != NULL; np = np->ptnext) {
+ struct isoent *mvent;
+ struct isoent *newent;
+
+ if (!np->dir)
+ continue;
+ for (mvent = np->subdirs.first;
+ mvent != NULL; mvent = mvent->drnext) {
+ r = isoent_rr_move_dir(a, &rr_moved,
+ mvent, &newent);
+ if (r < 0)
+ return (r);
+ isoent_collect_dirs(&(iso9660->primary),
+ newent, 2);
+ }
+ }
+ /* If new entries are added to level 8 path_talbe,
+ * its sub directory entries move to rr_move too.
+ */
+ np = last->ptnext;
+ }
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * This comparing rule is according to ISO9660 Standard 6.9.1
+ */
+static int
+_compare_path_table(const void *v1, const void *v2)
+{
+ const struct isoent *p1, *p2;
+ const char *s1, *s2;
+ int cmp, l;
+
+ p1 = *((const struct isoent **)(uintptr_t)v1);
+ p2 = *((const struct isoent **)(uintptr_t)v2);
+
+ /* Compare parent directory number */
+ cmp = p1->parent->dir_number - p2->parent->dir_number;
+ if (cmp != 0)
+ return (cmp);
+
+ /* Compare indetifier */
+ s1 = p1->identifier;
+ s2 = p2->identifier;
+ l = p1->ext_off;
+ if (l > p2->ext_off)
+ l = p2->ext_off;
+ cmp = strncmp(s1, s2, l);
+ if (cmp != 0)
+ return (cmp);
+ if (p1->ext_off < p2->ext_off) {
+ s2 += l;
+ l = p2->ext_off - p1->ext_off;
+ while (l--)
+ if (0x20 != *s2++)
+ return (0x20
+ - *(const unsigned char *)(s2 - 1));
+ } else if (p1->ext_off > p2->ext_off) {
+ s1 += l;
+ l = p1->ext_off - p2->ext_off;
+ while (l--)
+ if (0x20 != *s1++)
+ return (*(const unsigned char *)(s1 - 1)
+ - 0x20);
+ }
+ return (0);
+}
+
+static int
+_compare_path_table_joliet(const void *v1, const void *v2)
+{
+ const struct isoent *p1, *p2;
+ const unsigned char *s1, *s2;
+ int cmp, l;
+
+ p1 = *((const struct isoent **)(uintptr_t)v1);
+ p2 = *((const struct isoent **)(uintptr_t)v2);
+
+ /* Compare parent directory number */
+ cmp = p1->parent->dir_number - p2->parent->dir_number;
+ if (cmp != 0)
+ return (cmp);
+
+ /* Compare indetifier */
+ s1 = (const unsigned char *)p1->identifier;
+ s2 = (const unsigned char *)p2->identifier;
+ l = p1->ext_off;
+ if (l > p2->ext_off)
+ l = p2->ext_off;
+ cmp = memcmp(s1, s2, l);
+ if (cmp != 0)
+ return (cmp);
+ if (p1->ext_off < p2->ext_off) {
+ s2 += l;
+ l = p2->ext_off - p1->ext_off;
+ while (l--)
+ if (0 != *s2++)
+ return (- *(const unsigned char *)(s2 - 1));
+ } else if (p1->ext_off > p2->ext_off) {
+ s1 += l;
+ l = p1->ext_off - p2->ext_off;
+ while (l--)
+ if (0 != *s1++)
+ return (*(const unsigned char *)(s1 - 1));
+ }
+ return (0);
+}
+
+static inline void
+path_table_add_entry(struct path_table *pathtbl, struct isoent *ent)
+{
+ ent->ptnext = NULL;
+ *pathtbl->last = ent;
+ pathtbl->last = &(ent->ptnext);
+ pathtbl->cnt ++;
+}
+
+static inline struct isoent *
+path_table_last_entry(struct path_table *pathtbl)
+{
+ if (pathtbl->first == NULL)
+ return (NULL);
+ return (((struct isoent *)(void *)
+ ((char *)(pathtbl->last) - offsetof(struct isoent, ptnext))));
+}
+
+/*
+ * Sort directory entries in path_table
+ * and assign directory number to each entries.
+ */
+static int
+isoent_make_path_table_2(struct archive_write *a, struct vdd *vdd,
+ int depth, int *dir_number)
+{
+ struct isoent *np;
+ struct isoent **enttbl;
+ struct path_table *pt;
+ int i;
+
+ pt = &vdd->pathtbl[depth];
+ if (pt->cnt == 0) {
+ pt->sorted = NULL;
+ return (ARCHIVE_OK);
+ }
+ enttbl = malloc(pt->cnt * sizeof(struct isoent *));
+ if (enttbl == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ pt->sorted = enttbl;
+ for (np = pt->first; np != NULL; np = np->ptnext)
+ *enttbl ++ = np;
+ enttbl = pt->sorted;
+
+ switch (vdd->vdd_type) {
+ case VDD_PRIMARY:
+ case VDD_ENHANCED:
+ qsort(enttbl, pt->cnt, sizeof(struct isoent *),
+ _compare_path_table);
+ break;
+ case VDD_JOLIET:
+ qsort(enttbl, pt->cnt, sizeof(struct isoent *),
+ _compare_path_table_joliet);
+ break;
+ }
+ for (i = 0; i < pt->cnt; i++)
+ enttbl[i]->dir_number = (*dir_number)++;
+
+ return (ARCHIVE_OK);
+}
+
+static int
+isoent_alloc_path_table(struct archive_write *a, struct vdd *vdd,
+ int max_depth)
+{
+ int i;
+
+ vdd->max_depth = max_depth;
+ vdd->pathtbl = malloc(sizeof(*vdd->pathtbl) * vdd->max_depth);
+ if (vdd->pathtbl == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ for (i = 0; i < vdd->max_depth; i++) {
+ vdd->pathtbl[i].first = NULL;
+ vdd->pathtbl[i].last = &(vdd->pathtbl[i].first);
+ vdd->pathtbl[i].sorted = NULL;
+ vdd->pathtbl[i].cnt = 0;
+ }
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Make Path Tables
+ */
+static int
+isoent_make_path_table(struct archive_write *a)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ int depth, r;
+ int dir_number;
+
+ /*
+ * Init Path Table.
+ */
+ if (iso9660->dircnt_max >= MAX_DEPTH &&
+ (!iso9660->opt.limit_depth || iso9660->opt.iso_level == 4))
+ r = isoent_alloc_path_table(a, &(iso9660->primary),
+ iso9660->dircnt_max + 1);
+ else
+ /* The number of levels in the hierarchy cannot exceed
+ * eight. */
+ r = isoent_alloc_path_table(a, &(iso9660->primary),
+ MAX_DEPTH);
+ if (r < 0)
+ return (r);
+ if (iso9660->opt.joliet) {
+ r = isoent_alloc_path_table(a, &(iso9660->joliet),
+ iso9660->dircnt_max + 1);
+ if (r < 0)
+ return (r);
+ }
+
+ /* Step 0.
+ * - Collect directories for primary and joliet.
+ */
+ isoent_collect_dirs(&(iso9660->primary), NULL, 0);
+ if (iso9660->opt.joliet)
+ isoent_collect_dirs(&(iso9660->joliet), NULL, 0);
+ /*
+ * Rockridge; move deeper depth directories to rr_moved.
+ */
+ if (iso9660->opt.rr) {
+ r = isoent_rr_move(a);
+ if (r < 0)
+ return (r);
+ }
+
+ /* Update nlink. */
+ isofile_connect_hardlink_files(iso9660);
+
+ /* Step 1.
+ * - Renew a value of the depth of that directories.
+ * - Resolve hardlinks.
+ * - Convert pathnames to ISO9660 name or UCS2(joliet).
+ * - Sort files by each directory.
+ */
+ r = isoent_traverse_tree(a, &(iso9660->primary));
+ if (r < 0)
+ return (r);
+ if (iso9660->opt.joliet) {
+ r = isoent_traverse_tree(a, &(iso9660->joliet));
+ if (r < 0)
+ return (r);
+ }
+
+ /* Step 2.
+ * - Sort directories.
+ * - Assign all directory number.
+ */
+ dir_number = 1;
+ for (depth = 0; depth < iso9660->primary.max_depth; depth++) {
+ r = isoent_make_path_table_2(a, &(iso9660->primary),
+ depth, &dir_number);
+ if (r < 0)
+ return (r);
+ }
+ if (iso9660->opt.joliet) {
+ dir_number = 1;
+ for (depth = 0; depth < iso9660->joliet.max_depth; depth++) {
+ r = isoent_make_path_table_2(a, &(iso9660->joliet),
+ depth, &dir_number);
+ if (r < 0)
+ return (r);
+ }
+ }
+ if (iso9660->opt.limit_dirs && dir_number > 0xffff) {
+ /*
+ * Maximum number of directories is 65535(0xffff)
+ * doe to size(16bit) of Parent Directory Number of
+ * the Path Table.
+ * See also ISO9660 Standard 9.4.
+ */
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Too many directories(%d) over 65535.", dir_number);
+ return (ARCHIVE_FATAL);
+ }
+
+ /* Get the size of the Path Table. */
+ calculate_path_table_size(&(iso9660->primary));
+ if (iso9660->opt.joliet)
+ calculate_path_table_size(&(iso9660->joliet));
+
+ return (ARCHIVE_OK);
+}
+
+static int
+isoent_find_out_boot_file(struct archive_write *a, struct isoent *rootent)
+{
+ struct iso9660 *iso9660 = a->format_data;
+
+ /* Find a isoent of the boot file. */
+ iso9660->el_torito.boot = isoent_find_entry(rootent,
+ iso9660->el_torito.boot_filename.s);
+ if (iso9660->el_torito.boot == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Can't find the boot image file ``%s''",
+ iso9660->el_torito.boot_filename.s);
+ return (ARCHIVE_FATAL);
+ }
+ iso9660->el_torito.boot->file->boot = BOOT_IMAGE;
+ return (ARCHIVE_OK);
+}
+
+static int
+isoent_create_boot_catalog(struct archive_write *a, struct isoent *rootent)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ struct isofile *file;
+ struct isoent *isoent;
+ struct archive_entry *entry;
+
+ (void)rootent; /* UNUSED */
+ /*
+ * Create the entry which is the "boot.catalog" file.
+ */
+ file = isofile_new(a, NULL);
+ if (file == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ archive_entry_set_pathname(file->entry,
+ iso9660->el_torito.catalog_filename.s);
+ archive_entry_set_size(file->entry, LOGICAL_BLOCK_SIZE);
+ archive_entry_set_mtime(file->entry, iso9660->birth_time, 0);
+ archive_entry_set_atime(file->entry, iso9660->birth_time, 0);
+ archive_entry_set_ctime(file->entry, iso9660->birth_time, 0);
+ archive_entry_set_uid(file->entry, getuid());
+ archive_entry_set_gid(file->entry, getgid());
+ archive_entry_set_mode(file->entry, AE_IFREG | 0444);
+ archive_entry_set_nlink(file->entry, 1);
+
+ if (isofile_gen_utility_names(a, file) < ARCHIVE_WARN) {
+ isofile_free(file);
+ return (ARCHIVE_FATAL);
+ }
+ file->boot = BOOT_CATALOG;
+ file->content.size = LOGICAL_BLOCK_SIZE;
+ isofile_add_entry(iso9660, file);
+
+ isoent = isoent_new(file);
+ if (isoent == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ isoent->virtual = 1;
+
+ /* Add the "boot.catalog" entry into tree */
+ if (isoent_tree(a, &isoent) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ iso9660->el_torito.catalog = isoent;
+ /*
+ * Get a boot medai type.
+ */
+ switch (iso9660->opt.boot_type) {
+ default:
+ case OPT_BOOT_TYPE_AUTO:
+ /* Try detecting a media type of the boot image. */
+ entry = iso9660->el_torito.boot->file->entry;
+ if (archive_entry_size(entry) == FD_1_2M_SIZE)
+ iso9660->el_torito.media_type =
+ BOOT_MEDIA_1_2M_DISKETTE;
+ else if (archive_entry_size(entry) == FD_1_44M_SIZE)
+ iso9660->el_torito.media_type =
+ BOOT_MEDIA_1_44M_DISKETTE;
+ else if (archive_entry_size(entry) == FD_2_88M_SIZE)
+ iso9660->el_torito.media_type =
+ BOOT_MEDIA_2_88M_DISKETTE;
+ else
+ /* We cannot decide whether the boot image is
+ * hard-disk. */
+ iso9660->el_torito.media_type =
+ BOOT_MEDIA_NO_EMULATION;
+ break;
+ case OPT_BOOT_TYPE_NO_EMU:
+ iso9660->el_torito.media_type = BOOT_MEDIA_NO_EMULATION;
+ break;
+ case OPT_BOOT_TYPE_HARD_DISK:
+ iso9660->el_torito.media_type = BOOT_MEDIA_HARD_DISK;
+ break;
+ case OPT_BOOT_TYPE_FD:
+ entry = iso9660->el_torito.boot->file->entry;
+ if (archive_entry_size(entry) <= FD_1_2M_SIZE)
+ iso9660->el_torito.media_type =
+ BOOT_MEDIA_1_2M_DISKETTE;
+ else if (archive_entry_size(entry) <= FD_1_44M_SIZE)
+ iso9660->el_torito.media_type =
+ BOOT_MEDIA_1_44M_DISKETTE;
+ else if (archive_entry_size(entry) <= FD_2_88M_SIZE)
+ iso9660->el_torito.media_type =
+ BOOT_MEDIA_2_88M_DISKETTE;
+ else {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Boot image file(``%s'') size is too big "
+ "for fd type.",
+ iso9660->el_torito.boot_filename.s);
+ return (ARCHIVE_FATAL);
+ }
+ break;
+ }
+
+ /*
+ * Get a system type.
+ * TODO: `El Torito' specification says "A copy of byte 5 from the
+ * Partition Table found in the boot image".
+ */
+ iso9660->el_torito.system_type = 0;
+
+ /*
+ * Get an ID.
+ */
+ if (iso9660->opt.publisher)
+ archive_string_copy(&(iso9660->el_torito.id),
+ &(iso9660->publisher_identifier));
+
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * If a media type is floppy, return its image size.
+ * otherwise return 0.
+ */
+static size_t
+fd_boot_image_size(int media_type)
+{
+ switch (media_type) {
+ case BOOT_MEDIA_1_2M_DISKETTE:
+ return (FD_1_2M_SIZE);
+ case BOOT_MEDIA_1_44M_DISKETTE:
+ return (FD_1_44M_SIZE);
+ case BOOT_MEDIA_2_88M_DISKETTE:
+ return (FD_2_88M_SIZE);
+ default:
+ return (0);
+ }
+}
+
+/*
+ * Make a boot catalog image data.
+ */
+static int
+make_boot_catalog(struct archive_write *a)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ unsigned char *block;
+ unsigned char *p;
+ uint16_t sum, *wp;
+
+ block = wb_buffptr(a);
+ memset(block, 0, LOGICAL_BLOCK_SIZE);
+ p = block;
+ /*
+ * Validation Entry
+ */
+ /* Header ID */
+ p[0] = 1;
+ /* Platform ID */
+ p[1] = iso9660->el_torito.platform_id;
+ /* Reserved */
+ p[2] = p[3] = 0;
+ /* ID */
+ if (archive_strlen(&(iso9660->el_torito.id)) > 0)
+ strncpy((char *)p+4, iso9660->el_torito.id.s, 23);
+ p[27] = 0;
+ /* Checksum */
+ p[28] = p[29] = 0;
+ /* Key */
+ p[30] = 0x55;
+ p[31] = 0xAA;
+
+ sum = 0;
+ wp = (uint16_t *)block;
+ while (wp < (uint16_t *)&block[32])
+ sum += archive_le16dec(wp++);
+ set_num_721(&block[28], (~sum) + 1);
+
+ /*
+ * Initial/Default Entry
+ */
+ p = &block[32];
+ /* Boot Indicator */
+ p[0] = 0x88;
+ /* Boot media type */
+ p[1] = iso9660->el_torito.media_type;
+ /* Load Segment */
+ if (iso9660->el_torito.media_type == BOOT_MEDIA_NO_EMULATION)
+ set_num_721(&p[2], iso9660->el_torito.boot_load_seg);
+ else
+ set_num_721(&p[2], 0);
+ /* System Type */
+ p[4] = iso9660->el_torito.system_type;
+ /* Unused */
+ p[5] = 0;
+ /* Sector Count */
+ if (iso9660->el_torito.media_type == BOOT_MEDIA_NO_EMULATION)
+ set_num_721(&p[6], iso9660->el_torito.boot_load_size);
+ else
+ set_num_721(&p[6], 1);
+ /* Load RBA */
+ set_num_731(&p[8],
+ iso9660->el_torito.boot->file->content.location);
+ /* Unused */
+ memset(&p[12], 0, 20);
+
+ return (wb_consume(a, LOGICAL_BLOCK_SIZE));
+}
+
+static int
+setup_boot_information(struct archive_write *a)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ struct isoent *np;
+ int64_t size;
+ uint32_t sum;
+ unsigned char buff[4096];
+
+ np = iso9660->el_torito.boot;
+ lseek(iso9660->temp_fd,
+ np->file->content.offset_of_temp + 64, SEEK_SET);
+ size = archive_entry_size(np->file->entry) - 64;
+ if (size <= 0) {
+ archive_set_error(&a->archive, errno,
+ "Boot file(%jd) is too small", (intmax_t)size + 64);
+ return (ARCHIVE_FATAL);
+ }
+ sum = 0;
+ while (size > 0) {
+ size_t rsize;
+ ssize_t i, rs;
+
+ if (size > sizeof(buff))
+ rsize = sizeof(buff);
+ else
+ rsize = (size_t)size;
+
+ rs = read(iso9660->temp_fd, buff, rsize);
+ if (rs <= 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't read temporary file(%jd)",
+ (intmax_t)rs);
+ return (ARCHIVE_FATAL);
+ }
+ for (i = 0; i < rs; i += 4)
+ sum += archive_le32dec(buff + i);
+ size -= rs;
+ }
+ /* Set the location of Primary Volume Descriptor. */
+ set_num_731(buff, SYSTEM_AREA_BLOCK);
+ /* Set the location of the boot file. */
+ set_num_731(buff+4, np->file->content.location);
+ /* Set the size of the boot file. */
+ size = fd_boot_image_size(iso9660->el_torito.media_type);
+ if (size == 0)
+ size = archive_entry_size(np->file->entry);
+ set_num_731(buff+8, (uint32_t)size);
+ /* Set the sum of the boot file. */
+ set_num_731(buff+12, sum);
+ /* Clear reserved bytes. */
+ memset(buff+16, 0, 40);
+
+ /* Overwrite the boot file. */
+ lseek(iso9660->temp_fd,
+ np->file->content.offset_of_temp + 8, SEEK_SET);
+ return (write_to_temp(a, buff, 56));
+}
+
+#ifdef HAVE_ZLIB_H
+
+static int
+zisofs_init_zstream(struct archive_write *a)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ int r;
+
+ iso9660->zisofs.stream.next_in = NULL;
+ iso9660->zisofs.stream.avail_in = 0;
+ iso9660->zisofs.stream.total_in = 0;
+ iso9660->zisofs.stream.total_out = 0;
+ if (iso9660->zisofs.stream_valid)
+ r = deflateReset(&(iso9660->zisofs.stream));
+ else {
+ r = deflateInit(&(iso9660->zisofs.stream),
+ iso9660->zisofs.compression_level);
+ iso9660->zisofs.stream_valid = 1;
+ }
+ switch (r) {
+ case Z_OK:
+ break;
+ default:
+ case Z_STREAM_ERROR:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Internal error initializing "
+ "compression library: invalid setup parameter");
+ return (ARCHIVE_FATAL);
+ case Z_MEM_ERROR:
+ archive_set_error(&a->archive, ENOMEM,
+ "Internal error initializing "
+ "compression library");
+ return (ARCHIVE_FATAL);
+ case Z_VERSION_ERROR:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Internal error initializing "
+ "compression library: invalid library version");
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_OK);
+}
+
+#endif /* HAVE_ZLIB_H */
+
+static int
+zisofs_init(struct archive_write *a, struct isofile *file)
+{
+ struct iso9660 *iso9660 = a->format_data;
+#ifdef HAVE_ZLIB_H
+ uint64_t tsize;
+ size_t ceil, bpsize;
+ int r;
+#endif
+
+ iso9660->zisofs.detect_magic = 0;
+ iso9660->zisofs.making = 0;
+
+ if (!iso9660->opt.rr || !iso9660->opt.zisofs)
+ return (ARCHIVE_OK);
+
+ if (archive_entry_size(file->entry) >= 24 &&
+ archive_entry_size(file->entry) < MULTI_EXTENT_SIZE) {
+ /* Acceptable file size for zisofs. */
+ iso9660->zisofs.detect_magic = 1;
+ iso9660->zisofs.magic_cnt = 0;
+ }
+ if (!iso9660->zisofs.detect_magic)
+ return (ARCHIVE_OK);
+
+#ifdef HAVE_ZLIB_H
+ /* The number of Logical Blocks which uncompressed data
+ * will use in iso-image file is the same as the number of
+ * Logical Blocks which zisofs(compressed) data will use
+ * in ISO-image file. It won't reduce iso-image file size. */
+ if (archive_entry_size(file->entry) <= LOGICAL_BLOCK_SIZE)
+ return (ARCHIVE_OK);
+
+ /* Initialize compression library */
+ r = zisofs_init_zstream(a);
+ if (r != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /* Mark file->zisofs to create RRIP 'ZF' Use Entry. */
+ file->zisofs.header_size = ZF_HEADER_SIZE >> 2;
+ file->zisofs.log2_bs = ZF_LOG2_BS;
+ file->zisofs.uncompressed_size = archive_entry_size(file->entry);
+
+ /* Calculate a size of Block Pointers of zisofs. */
+ ceil = (file->zisofs.uncompressed_size + ZF_BLOCK_SIZE -1)
+ >> file->zisofs.log2_bs;
+ iso9660->zisofs.block_pointers_cnt = ceil + 1;
+ iso9660->zisofs.block_pointers_idx = 0;
+
+ /* Ensure a buffer size used for Block Pointers */
+ bpsize = iso9660->zisofs.block_pointers_cnt *
+ sizeof(iso9660->zisofs.block_pointers[0]);
+ if (iso9660->zisofs.block_pointers_allocated < bpsize) {
+ free(iso9660->zisofs.block_pointers);
+ iso9660->zisofs.block_pointers = malloc(bpsize);
+ if (iso9660->zisofs.block_pointers == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate data");
+ return (ARCHIVE_FATAL);
+ }
+ iso9660->zisofs.block_pointers_allocated = bpsize;
+ }
+
+ /*
+ * Skip zisofs header and Block Pointers, which we will write
+ * after all compressed data of a file written to the temporary
+ * file.
+ */
+ tsize = ZF_HEADER_SIZE + bpsize;
+ if (write_null(a, tsize) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /*
+ * Initialize some variables to make zisofs.
+ */
+ archive_le32enc(&(iso9660->zisofs.block_pointers[0]), tsize);
+ iso9660->zisofs.remaining = file->zisofs.uncompressed_size;
+ iso9660->zisofs.making = 1;
+ iso9660->zisofs.allzero = 1;
+ iso9660->zisofs.block_offset = tsize;
+ iso9660->zisofs.total_size = tsize;
+ iso9660->cur_file->cur_content->size = tsize;
+#endif
+
+ return (ARCHIVE_OK);
+}
+
+static void
+zisofs_detect_magic(struct archive_write *a, const void *buff, size_t s)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ struct isofile *file = iso9660->cur_file;
+ const unsigned char *p, *endp;
+ const unsigned char *magic_buff;
+ uint32_t uncompressed_size;
+ unsigned char header_size;
+ unsigned char log2_bs;
+ size_t ceil, doff;
+ uint32_t bst, bed;
+ int magic_max;
+ int64_t entry_size;
+
+ entry_size = archive_entry_size(file->entry);
+ if (sizeof(iso9660->zisofs.magic_buffer) > entry_size)
+ magic_max = entry_size;
+ else
+ magic_max = sizeof(iso9660->zisofs.magic_buffer);
+
+ if (iso9660->zisofs.magic_cnt == 0 && s >= (size_t)magic_max)
+ /* It's unnecessary we copy buffer. */
+ magic_buff = buff;
+ else {
+ if (iso9660->zisofs.magic_cnt < magic_max) {
+ size_t l;
+
+ l = sizeof(iso9660->zisofs.magic_buffer)
+ - iso9660->zisofs.magic_cnt;
+ if (l > s)
+ l = s;
+ memcpy(iso9660->zisofs.magic_buffer
+ + iso9660->zisofs.magic_cnt, buff, l);
+ iso9660->zisofs.magic_cnt += l;
+ if (iso9660->zisofs.magic_cnt < magic_max)
+ return;
+ }
+ magic_buff = iso9660->zisofs.magic_buffer;
+ }
+ iso9660->zisofs.detect_magic = 0;
+ p = magic_buff;
+
+ /* Check the magic code of zisofs. */
+ if (memcmp(p, zisofs_magic, sizeof(zisofs_magic)) != 0)
+ /* This is not zisofs file which made by mkzftree. */
+ return;
+ p += sizeof(zisofs_magic);
+
+ /* Read a zisofs header. */
+ uncompressed_size = archive_le32dec(p);
+ header_size = p[4];
+ log2_bs = p[5];
+ if (uncompressed_size < 24 || header_size != 4 ||
+ log2_bs > 30 || log2_bs < 7)
+ return;/* Invalid or not supported header. */
+
+ /* Calculate a size of Block Pointers of zisofs. */
+ ceil = (uncompressed_size +
+ (ARCHIVE_LITERAL_LL(1) << log2_bs) -1) >> log2_bs;
+ doff = (ceil + 1) * 4 + 16;
+ if (entry_size < doff)
+ return;/* Invalid data. */
+
+ /* Check every Block Pointer has valid value. */
+ p = magic_buff + 16;
+ endp = magic_buff + magic_max;
+ while (ceil && p + 8 <= endp) {
+ bst = archive_le32dec(p);
+ if (bst != doff)
+ return;/* Invalid data. */
+ p += 4;
+ bed = archive_le32dec(p);
+ if (bed < bst || bed > entry_size)
+ return;/* Invalid data. */
+ doff += bed - bst;
+ ceil--;
+ }
+
+ file->zisofs.uncompressed_size = uncompressed_size;
+ file->zisofs.header_size = header_size;
+ file->zisofs.log2_bs = log2_bs;
+
+ /* Disable making a zisofs image. */
+ iso9660->zisofs.making = 0;
+}
+
+#ifdef HAVE_ZLIB_H
+
+/*
+ * Compress data and write it to a temporary file.
+ */
+static int
+zisofs_write_to_temp(struct archive_write *a, const void *buff, size_t s)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ struct isofile *file = iso9660->cur_file;
+ const unsigned char *b;
+ z_stream *zstrm;
+ size_t avail, csize;
+ int flush, r;
+
+ zstrm = &(iso9660->zisofs.stream);
+ zstrm->next_out = wb_buffptr(a);
+ zstrm->avail_out = wb_remaining(a);
+ b = (const unsigned char *)buff;
+ do {
+ avail = ZF_BLOCK_SIZE - zstrm->total_in;
+ if (s < avail) {
+ avail = s;
+ flush = Z_NO_FLUSH;
+ } else
+ flush = Z_FINISH;
+ iso9660->zisofs.remaining -= avail;
+ if (iso9660->zisofs.remaining <= 0)
+ flush = Z_FINISH;
+
+ zstrm->next_in = (Bytef *)(uintptr_t)(const void *)b;
+ zstrm->avail_in = avail;
+
+ /*
+ * Check if current data block are all zero.
+ */
+ if (iso9660->zisofs.allzero) {
+ const unsigned char *nonzero = b;
+ const unsigned char *nonzeroend = b + avail;
+
+ while (nonzero < nonzeroend)
+ if (*nonzero++) {
+ iso9660->zisofs.allzero = 0;
+ break;
+ }
+ }
+ b += avail;
+ s -= avail;
+
+ /*
+ * If current data block are all zero, we do not use
+ * compressed data.
+ */
+ if (flush == Z_FINISH && iso9660->zisofs.allzero &&
+ avail + zstrm->total_in == ZF_BLOCK_SIZE) {
+ if (iso9660->zisofs.block_offset !=
+ file->cur_content->size) {
+ int64_t diff;
+
+ r = wb_set_offset(a,
+ file->cur_content->offset_of_temp +
+ iso9660->zisofs.block_offset);
+ if (r != ARCHIVE_OK)
+ return (r);
+ diff = file->cur_content->size -
+ iso9660->zisofs.block_offset;
+ file->cur_content->size -= diff;
+ iso9660->zisofs.total_size -= diff;
+ }
+ zstrm->avail_in = 0;
+ }
+
+ /*
+ * Compress file data.
+ */
+ while (zstrm->avail_in > 0) {
+ csize = zstrm->total_out;
+ r = deflate(zstrm, flush);
+ switch (r) {
+ case Z_OK:
+ case Z_STREAM_END:
+ csize = zstrm->total_out - csize;
+ if (wb_consume(a, csize) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ iso9660->zisofs.total_size += csize;
+ iso9660->cur_file->cur_content->size += csize;
+ zstrm->next_out = wb_buffptr(a);
+ zstrm->avail_out = wb_remaining(a);
+ break;
+ default:
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Compression failed:"
+ " deflate() call returned status %d",
+ r);
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ if (flush == Z_FINISH) {
+ /*
+ * Save the information of one zisofs block.
+ */
+ iso9660->zisofs.block_pointers_idx ++;
+ archive_le32enc(&(iso9660->zisofs.block_pointers[
+ iso9660->zisofs.block_pointers_idx]),
+ iso9660->zisofs.total_size);
+ r = zisofs_init_zstream(a);
+ if (r != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ iso9660->zisofs.allzero = 1;
+ iso9660->zisofs.block_offset = file->cur_content->size;
+ }
+ } while (s);
+
+ return (ARCHIVE_OK);
+}
+
+static int
+zisofs_finish_entry(struct archive_write *a)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ struct isofile *file = iso9660->cur_file;
+ unsigned char buff[16];
+ size_t s;
+ int64_t tail;
+
+ /* Direct temp file stream to zisofs temp file stream. */
+ archive_entry_set_size(file->entry, iso9660->zisofs.total_size);
+
+ /*
+ * Save a file pointer which points the end of current zisofs data.
+ */
+ tail = wb_offset(a);
+
+ /*
+ * Make a header.
+ *
+ * +-----------------+----------------+-----------------+
+ * | Header 16 bytes | Block Pointers | Compressed data |
+ * +-----------------+----------------+-----------------+
+ * 0 16 +X
+ * Block Pointers :
+ * 4 * (((Uncompressed file size + block_size -1) / block_size) + 1)
+ *
+ * Write zisofs header.
+ * Magic number
+ * +----+----+----+----+----+----+----+----+
+ * | 37 | E4 | 53 | 96 | C9 | DB | D6 | 07 |
+ * +----+----+----+----+----+----+----+----+
+ * 0 1 2 3 4 5 6 7 8
+ *
+ * +------------------------+------------------+
+ * | Uncompressed file size | header_size >> 2 |
+ * +------------------------+------------------+
+ * 8 12 13
+ *
+ * +-----------------+----------------+
+ * | log2 block_size | Reserved(0000) |
+ * +-----------------+----------------+
+ * 13 14 16
+ */
+ memcpy(buff, zisofs_magic, 8);
+ set_num_731(buff+8, file->zisofs.uncompressed_size);
+ buff[12] = file->zisofs.header_size;
+ buff[13] = file->zisofs.log2_bs;
+ buff[14] = buff[15] = 0;/* Reserved */
+
+ /* Move to the right position to write the header. */
+ wb_set_offset(a, file->content.offset_of_temp);
+
+ /* Write the header. */
+ if (wb_write_to_temp(a, buff, 16) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /*
+ * Write zisofs Block Pointers.
+ */
+ s = iso9660->zisofs.block_pointers_cnt *
+ sizeof(iso9660->zisofs.block_pointers[0]);
+ if (wb_write_to_temp(a, iso9660->zisofs.block_pointers, s)
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /* Set a file pointer back to the end of the temporary file. */
+ wb_set_offset(a, tail);
+
+ return (ARCHIVE_OK);
+}
+
+static int
+zisofs_free(struct archive_write *a)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ int ret = ARCHIVE_OK;
+
+ free(iso9660->zisofs.block_pointers);
+ if (iso9660->zisofs.stream_valid &&
+ deflateEnd(&(iso9660->zisofs.stream)) != Z_OK) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Failed to clean up compressor");
+ ret = ARCHIVE_FATAL;
+ }
+ iso9660->zisofs.block_pointers = NULL;
+ iso9660->zisofs.stream_valid = 0;
+ return (ret);
+}
+
+struct zisofs_extract {
+ int pz_log2_bs; /* Log2 of block size */
+ uint64_t pz_uncompressed_size;
+ size_t uncompressed_buffer_size;
+
+ int initialized:1;
+ int header_passed:1;
+
+ uint32_t pz_offset;
+ unsigned char *block_pointers;
+ size_t block_pointers_size;
+ size_t block_pointers_avail;
+ size_t block_off;
+ uint32_t block_avail;
+
+ z_stream stream;
+ int stream_valid;
+};
+
+static ssize_t
+zisofs_extract_init(struct archive_write *a, struct zisofs_extract *zisofs,
+ const unsigned char *p, size_t bytes)
+{
+ size_t avail = bytes;
+ size_t ceil, xsize;
+
+ /* Allocate block pointers buffer. */
+ ceil = (zisofs->pz_uncompressed_size +
+ (1LL << zisofs->pz_log2_bs) - 1)
+ >> zisofs->pz_log2_bs;
+ xsize = (ceil + 1) * 4;
+ if (zisofs->block_pointers == NULL) {
+ size_t alloc = ((xsize >> 10) + 1) << 10;
+ zisofs->block_pointers = malloc(alloc);
+ if (zisofs->block_pointers == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory for zisofs decompression");
+ return (ARCHIVE_FATAL);
+ }
+ }
+ zisofs->block_pointers_size = xsize;
+
+ /* Allocate uncompressed data buffer. */
+ zisofs->uncompressed_buffer_size = 1UL << zisofs->pz_log2_bs;
+
+ /*
+ * Read the file header, and check the magic code of zisofs.
+ */
+ if (!zisofs->header_passed) {
+ int err = 0;
+ if (avail < 16) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Illegal zisofs file body");
+ return (ARCHIVE_FATAL);
+ }
+
+ if (memcmp(p, zisofs_magic, sizeof(zisofs_magic)) != 0)
+ err = 1;
+ else if (archive_le32dec(p + 8) != zisofs->pz_uncompressed_size)
+ err = 1;
+ else if (p[12] != 4 || p[13] != zisofs->pz_log2_bs)
+ err = 1;
+ if (err) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Illegal zisofs file body");
+ return (ARCHIVE_FATAL);
+ }
+ avail -= 16;
+ p += 16;
+ zisofs->header_passed = 1;
+ }
+
+ /*
+ * Read block pointers.
+ */
+ if (zisofs->header_passed &&
+ zisofs->block_pointers_avail < zisofs->block_pointers_size) {
+ xsize = zisofs->block_pointers_size
+ - zisofs->block_pointers_avail;
+ if (avail < xsize)
+ xsize = avail;
+ memcpy(zisofs->block_pointers
+ + zisofs->block_pointers_avail, p, xsize);
+ zisofs->block_pointers_avail += xsize;
+ avail -= xsize;
+ if (zisofs->block_pointers_avail
+ == zisofs->block_pointers_size) {
+ /* We've got all block pointers and initialize
+ * related variables. */
+ zisofs->block_off = 0;
+ zisofs->block_avail = 0;
+ /* Complete a initialization */
+ zisofs->initialized = 1;
+ }
+ }
+ return ((ssize_t)avail);
+}
+
+static ssize_t
+zisofs_extract(struct archive_write *a, struct zisofs_extract *zisofs,
+ const unsigned char *p, size_t bytes)
+{
+ size_t avail;
+ int r;
+
+ if (!zisofs->initialized) {
+ ssize_t rs = zisofs_extract_init(a, zisofs, p, bytes);
+ if (rs < 0)
+ return (rs);
+ if (!zisofs->initialized) {
+ /* We need more data. */
+ zisofs->pz_offset += bytes;
+ return (bytes);
+ }
+ avail = rs;
+ p += bytes - avail;
+ } else
+ avail = bytes;
+
+ /*
+ * Get block offsets from block pointers.
+ */
+ if (zisofs->block_avail == 0) {
+ uint32_t bst, bed;
+
+ if (zisofs->block_off + 4 >= zisofs->block_pointers_size) {
+ /* There isn't a pair of offsets. */
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Illegal zisofs block pointers");
+ return (ARCHIVE_FATAL);
+ }
+ bst = archive_le32dec(
+ zisofs->block_pointers + zisofs->block_off);
+ if (bst != zisofs->pz_offset + (bytes - avail)) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Illegal zisofs block pointers(cannot seek)");
+ return (ARCHIVE_FATAL);
+ }
+ bed = archive_le32dec(
+ zisofs->block_pointers + zisofs->block_off + 4);
+ if (bed < bst) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Illegal zisofs block pointers");
+ return (ARCHIVE_FATAL);
+ }
+ zisofs->block_avail = bed - bst;
+ zisofs->block_off += 4;
+
+ /* Initialize compression library for new block. */
+ if (zisofs->stream_valid)
+ r = inflateReset(&zisofs->stream);
+ else
+ r = inflateInit(&zisofs->stream);
+ if (r != Z_OK) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Can't initialize zisofs decompression.");
+ return (ARCHIVE_FATAL);
+ }
+ zisofs->stream_valid = 1;
+ zisofs->stream.total_in = 0;
+ zisofs->stream.total_out = 0;
+ }
+
+ /*
+ * Make uncompressed data.
+ */
+ if (zisofs->block_avail == 0) {
+ /*
+ * It's basically 32K bytes NUL data.
+ */
+ unsigned char *wb;
+ size_t size, wsize;
+
+ size = zisofs->uncompressed_buffer_size;
+ while (size) {
+ wb = wb_buffptr(a);
+ if (size > wb_remaining(a))
+ wsize = wb_remaining(a);
+ else
+ wsize = size;
+ memset(wb, 0, wsize);
+ r = wb_consume(a, wsize);
+ if (r < 0)
+ return (r);
+ size -= wsize;
+ }
+ } else {
+ zisofs->stream.next_in = (Bytef *)(uintptr_t)(const void *)p;
+ if (avail > zisofs->block_avail)
+ zisofs->stream.avail_in = zisofs->block_avail;
+ else
+ zisofs->stream.avail_in = avail;
+ zisofs->stream.next_out = wb_buffptr(a);
+ zisofs->stream.avail_out = wb_remaining(a);
+
+ r = inflate(&zisofs->stream, 0);
+ switch (r) {
+ case Z_OK: /* Decompressor made some progress.*/
+ case Z_STREAM_END: /* Found end of stream. */
+ break;
+ default:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "zisofs decompression failed (%d)", r);
+ return (ARCHIVE_FATAL);
+ }
+ avail -= zisofs->stream.next_in - p;
+ zisofs->block_avail -= zisofs->stream.next_in - p;
+ r = wb_consume(a, wb_remaining(a) - zisofs->stream.avail_out);
+ if (r < 0)
+ return (r);
+ }
+ zisofs->pz_offset += bytes;
+ return (bytes - avail);
+}
+
+static int
+zisofs_rewind_boot_file(struct archive_write *a)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ struct isofile *file;
+ unsigned char *rbuff;
+ ssize_t r;
+ size_t remaining, rbuff_size;
+ struct zisofs_extract zext;
+ int64_t read_offset, write_offset, new_offset;
+ int fd, ret = ARCHIVE_OK;
+
+ file = iso9660->el_torito.boot->file;
+ /*
+ * There is nothing to do if this boot file does not have
+ * zisofs header.
+ */
+ if (file->zisofs.header_size == 0)
+ return (ARCHIVE_OK);
+
+ /*
+ * Uncompress the zisofs'ed file contents.
+ */
+ memset(&zext, 0, sizeof(zext));
+ zext.pz_uncompressed_size = file->zisofs.uncompressed_size;
+ zext.pz_log2_bs = file->zisofs.log2_bs;
+
+ fd = iso9660->temp_fd;
+ new_offset = wb_offset(a);
+ read_offset = file->content.offset_of_temp;
+ remaining = file->content.size;
+ if (remaining > 1024 * 32)
+ rbuff_size = 1024 * 32;
+ else
+ rbuff_size = remaining;
+
+ rbuff = malloc(rbuff_size);
+ if (rbuff == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ while (remaining) {
+ size_t rsize;
+ ssize_t rs;
+
+ /* Get the current file pointer. */
+ write_offset = lseek(fd, 0, SEEK_CUR);
+
+ /* Change the file pointer to read. */
+ lseek(fd, read_offset, SEEK_SET);
+
+ rsize = rbuff_size;
+ if (rsize > remaining)
+ rsize = remaining;
+ rs = read(iso9660->temp_fd, rbuff, rsize);
+ if (rs <= 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't read temporary file(%jd)", (intmax_t)rs);
+ ret = ARCHIVE_FATAL;
+ break;
+ }
+ remaining -= rs;
+ read_offset += rs;
+
+ /* Put the file pointer back to write. */
+ lseek(fd, write_offset, SEEK_SET);
+
+ r = zisofs_extract(a, &zext, rbuff, rs);
+ if (r < 0) {
+ ret = (int)r;
+ break;
+ }
+ }
+
+ if (ret == ARCHIVE_OK) {
+ /*
+ * Change the boot file content from zisofs'ed data
+ * to plain data.
+ */
+ file->content.offset_of_temp = new_offset;
+ file->content.size = file->zisofs.uncompressed_size;
+ archive_entry_set_size(file->entry, file->content.size);
+ /* Set to be no zisofs. */
+ file->zisofs.header_size = 0;
+ file->zisofs.log2_bs = 0;
+ file->zisofs.uncompressed_size = 0;
+ r = wb_write_padding_to_temp(a, file->content.size);
+ if (r < 0)
+ ret = ARCHIVE_FATAL;
+ }
+
+ /*
+ * Free the resource we used in this function only.
+ */
+ free(rbuff);
+ free(zext.block_pointers);
+ if (zext.stream_valid && inflateEnd(&(zext.stream)) != Z_OK) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Failed to clean up compressor");
+ ret = ARCHIVE_FATAL;
+ }
+
+ return (ret);
+}
+
+#else
+
+static int
+zisofs_write_to_temp(struct archive_write *a, const void *buff, size_t s)
+{
+ (void)buff; /* UNUSED */
+ (void)s; /* UNUSED */
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Programing error");
+ return (ARCHIVE_FATAL);
+}
+
+static int
+zisofs_rewind_boot_file(struct archive_write *a)
+{
+ struct iso9660 *iso9660 = a->format_data;
+
+ if (iso9660->el_torito.boot->file->zisofs.header_size != 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "We cannot extract the zisofs imaged boot file;"
+ " this may not boot in being zisofs imaged");
+ return (ARCHIVE_FAILED);
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+zisofs_finish_entry(struct archive_write *a)
+{
+ (void)a; /* UNUSED */
+ return (ARCHIVE_OK);
+}
+
+static int
+zisofs_free(struct archive_write *a)
+{
+ (void)a; /* UNUSED */
+ return (ARCHIVE_OK);
+}
+
+#endif /* HAVE_ZLIB_H */
+
diff --git a/libarchive/archive_write_set_format_mtree.c b/libarchive/archive_write_set_format_mtree.c
index 7feeca92e621..3802a25f3d08 100644
--- a/libarchive/archive_write_set_format_mtree.c
+++ b/libarchive/archive_write_set_format_mtree.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2009 Michihiro NAKAJIMA
+ * Copyright (c) 2009,2011 Michihiro NAKAJIMA
* Copyright (c) 2008 Joerg Sonnenberger
* All rights reserved.
*
@@ -35,17 +35,68 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_mtree.c 201171
#include <string.h>
#include "archive.h"
+#include "archive_crypto_private.h"
#include "archive_entry.h"
#include "archive_private.h"
#include "archive_write_private.h"
-#include "archive_hash.h"
-
#define INDENTNAMELEN 15
#define MAXLINELEN 80
+#define SET_KEYS \
+ (F_FLAGS | F_GID | F_GNAME | F_MODE | F_TYPE | F_UID | F_UNAME)
+
+struct mtree_entry {
+ struct mtree_entry *next;
+
+ char *pathname;
+ char *symlink;
+ unsigned int nlink;
+ mode_t filetype;
+ mode_t mode;
+ int64_t uid;
+ int64_t gid;
+ char *uname;
+ char *gname;
+ char *fflags_text;
+ unsigned long fflags_set;
+ unsigned long fflags_clear;
+ time_t mtime;
+ long mtime_nsec;
+ dev_t rdevmajor;
+ dev_t rdevminor;
+ int64_t size;
+
+ int compute_sum;
+ uint32_t crc;
+#ifdef ARCHIVE_HAS_MD5
+ unsigned char buf_md5[16];
+#endif
+#ifdef ARCHIVE_HAS_RMD160
+ unsigned char buf_rmd160[20];
+#endif
+#ifdef ARCHIVE_HAS_SHA1
+ unsigned char buf_sha1[20];
+#endif
+#ifdef ARCHIVE_HAS_SHA256
+ unsigned char buf_sha256[32];
+#endif
+#ifdef ARCHIVE_HAS_SHA384
+ unsigned char buf_sha384[48];
+#endif
+#ifdef ARCHIVE_HAS_SHA512
+ unsigned char buf_sha512[64];
+#endif
+};
+
+struct attr_counter {
+ struct attr_counter *prev;
+ struct attr_counter *next;
+ int count;
+ struct mtree_entry *m_entry;
+};
struct mtree_writer {
- struct archive_entry *entry;
+ struct mtree_entry *mtree_entry;
struct archive_string ebuf;
struct archive_string buf;
int first;
@@ -56,13 +107,20 @@ struct mtree_writer {
struct archive_string parent;
mode_t type;
int keys;
- uid_t uid;
- gid_t gid;
+ int64_t uid;
+ int64_t gid;
mode_t mode;
unsigned long fflags_set;
unsigned long fflags_clear;
+
+ struct attr_counter *uid_list;
+ struct attr_counter *gid_list;
+ struct attr_counter *mode_list;
+ struct attr_counter *flags_list;
+ struct mtree_entry *me_first;
+ struct mtree_entry **me_last;
} set;
- /* chekc sum */
+ /* check sum */
int compute_sum;
uint32_t crc;
uint64_t crc_len;
@@ -125,6 +183,18 @@ struct mtree_writer {
| F_NLINK | F_SIZE | F_TIME | F_TYPE | F_UID\
| F_UNAME)
+static struct attr_counter * new_attr_count(struct mtree_entry *,
+ struct attr_counter *);
+static void free_attr_count(struct attr_counter **);
+static int inc_attr_count(struct attr_counter **, struct attr_counter *,
+ struct attr_counter *, struct mtree_entry *);
+static int collect_set_values(struct mtree_writer *, struct mtree_entry *);
+static int get_keys(struct mtree_writer *, struct mtree_entry *);
+static void sum_init(struct mtree_writer *);
+static void sum_update(struct mtree_writer *, const void *, size_t);
+static void sum_final(struct mtree_writer *, struct mtree_entry *);
+static void sum_write(struct archive_string *, struct mtree_entry *);
+
#define COMPUTE_CRC(var, ch) (var) = (var) << 8 ^ crctab[(var) >> 24 ^ (ch)]
static const uint32_t crctab[] = {
0x0,
@@ -227,6 +297,9 @@ mtree_quote(struct archive_string *s, const char *str)
archive_strncat(s, start, str - start);
}
+/*
+ * Indent a line as mtree utility to be readable for people.
+ */
static void
mtree_indent(struct mtree_writer *mtree)
{
@@ -281,11 +354,11 @@ mtree_indent(struct mtree_writer *mtree)
#if !defined(_WIN32) || defined(__CYGWIN__)
static size_t
-dir_len(struct archive_entry *entry)
+dir_len(struct mtree_entry *me)
{
const char *path, *r;
- path = archive_entry_pathname(entry);
+ path = me->pathname;
r = strrchr(path, '/');
if (r == NULL)
return (0);
@@ -301,14 +374,14 @@ dir_len(struct archive_entry *entry)
* code.
*/
static size_t
-dir_len(struct archive_entry *entry)
+dir_len(struct mtree_entry *me)
{
wchar_t wc;
const char *path;
const char *p, *rp;
size_t al, l, size;
- path = archive_entry_pathname(entry);
+ path = me->pathname;
al = l = -1;
for (p = path; *p != '\0'; ++p) {
if (*p == '\\')
@@ -337,14 +410,17 @@ alen:
}
#endif /* _WIN32 && !__CYGWIN__ */
+/*
+ * Test if a parent directory of the current entry is changed.
+ */
static int
-parent_dir_changed(struct archive_string *dir, struct archive_entry *entry)
+parent_dir_changed(struct archive_string *dir, struct mtree_entry *me)
{
const char *path;
size_t l;
- l = dir_len(entry);
- path = archive_entry_pathname(entry);
+ l = dir_len(me);
+ path = me->pathname;
if (archive_strlen(dir) > 0) {
if (l == 0) {
archive_string_empty(dir);
@@ -359,129 +435,141 @@ parent_dir_changed(struct archive_string *dir, struct archive_entry *entry)
}
/*
- * Write /set keyword. It means set global datas.
- * [directory-only mode]
- * - It is only once to write /set keyword. It is using values of the
- * first entry.
- * [normal mode]
- * - Write /set keyword. It is using values of the first entry whose
- * filetype is a regular file.
- * - When a parent directory of the entry whose filetype is the regular
- * file is changed, check the global datas and write it again if its
- * values are different from the entry's.
+ * Write /set keyword.
+ * Set most used value of uid,gid,mode and fflags, which are
+ * collected by collect_set_values() function.
*/
static void
-set_global(struct mtree_writer *mtree, struct archive_entry *entry)
+write_global(struct mtree_writer *mtree)
{
struct archive_string setstr;
struct archive_string unsetstr;
const char *name;
int keys, oldkeys, effkeys;
- mode_t set_type = 0;
-
- switch (archive_entry_filetype(entry)) {
- case AE_IFLNK: case AE_IFSOCK: case AE_IFCHR:
- case AE_IFBLK: case AE_IFIFO:
- break;
- case AE_IFDIR:
- if (mtree->dironly)
- set_type = AE_IFDIR;
- break;
- case AE_IFREG:
- default: /* Handle unknown file types as regular files. */
- if (!mtree->dironly)
- set_type = AE_IFREG;
- break;
- }
- if (set_type == 0)
- return;
- if (mtree->set.processed &&
- !parent_dir_changed(&mtree->set.parent, entry))
- return;
- /* At first, save a parent directory of the entry for following
- * entries. */
- if (!mtree->set.processed && set_type == AE_IFREG)
- parent_dir_changed(&mtree->set.parent, entry);
+ struct attr_counter *ac;
archive_string_init(&setstr);
archive_string_init(&unsetstr);
- keys = mtree->keys & (F_FLAGS | F_GID | F_GNAME | F_NLINK | F_MODE
- | F_TYPE | F_UID | F_UNAME);
+ keys = mtree->keys & SET_KEYS;
oldkeys = mtree->set.keys;
effkeys = keys;
if (mtree->set.processed) {
/*
- * Check the global datas for whether it needs updating.
+ * Check if the global data needs updating.
*/
effkeys &= ~F_TYPE;
- if ((oldkeys & (F_UNAME | F_UID)) != 0 &&
- mtree->set.uid == archive_entry_uid(entry))
- effkeys &= ~(F_UNAME | F_UID);
- if ((oldkeys & (F_GNAME | F_GID)) != 0 &&
- mtree->set.gid == archive_entry_gid(entry))
- effkeys &= ~(F_GNAME | F_GID);
- if ((oldkeys & F_MODE) != 0 &&
- mtree->set.mode == (archive_entry_mode(entry) & 07777))
- effkeys &= ~F_MODE;
+ if (oldkeys & (F_UNAME | F_UID)) {
+ ac = mtree->set.uid_list;
+ do {
+ if (mtree->set.uid == ac->m_entry->uid) {
+ effkeys &= ~(F_UNAME | F_UID);
+ break;
+ }
+ if (ac->next != NULL &&
+ ac->next->count == ac->count)
+ continue;
+ } while (0);
+ }
+ if (oldkeys & (F_GNAME | F_GID)) {
+ ac = mtree->set.gid_list;
+ do {
+ if (mtree->set.gid == ac->m_entry->gid) {
+ effkeys &= ~(F_GNAME | F_GID);
+ break;
+ }
+ if (ac->next != NULL &&
+ ac->next->count == ac->count)
+ continue;
+ } while (0);
+ }
+ if (oldkeys & F_MODE) {
+ ac = mtree->set.mode_list;
+ do {
+ if (mtree->set.mode == ac->m_entry->mode) {
+ effkeys &= ~F_MODE;
+ break;
+ }
+ if (ac->next != NULL &&
+ ac->next->count == ac->count)
+ continue;
+ } while (0);
+ }
if ((oldkeys & F_FLAGS) != 0) {
- unsigned long fflags_set;
- unsigned long fflags_clear;
-
- archive_entry_fflags(entry, &fflags_set, &fflags_clear);
- if (fflags_set == mtree->set.fflags_set &&
- fflags_clear == mtree->set.fflags_clear)
- effkeys &= ~F_FLAGS;
+ ac = mtree->set.flags_list;
+ do {
+ if (ac->m_entry->fflags_set ==
+ mtree->set.fflags_set &&
+ ac->m_entry->fflags_clear ==
+ mtree->set.fflags_clear) {
+ effkeys &= ~F_FLAGS;
+ break;
+ }
+ if (ac->next != NULL &&
+ ac->next->count == ac->count)
+ continue;
+ } while (0);
}
}
if ((keys & effkeys & F_TYPE) != 0) {
- mtree->set.type = set_type;
- if (set_type == AE_IFDIR)
+ if (mtree->dironly) {
archive_strcat(&setstr, " type=dir");
- else
+ mtree->set.type = AE_IFDIR;
+ } else {
archive_strcat(&setstr, " type=file");
+ mtree->set.type = AE_IFREG;
+ }
}
if ((keys & effkeys & F_UNAME) != 0) {
- if ((name = archive_entry_uname(entry)) != NULL) {
+ name = mtree->set.uid_list->m_entry->uname;
+ if (name != NULL) {
archive_strcat(&setstr, " uname=");
mtree_quote(&setstr, name);
- } else if ((oldkeys & F_UNAME) != 0)
- archive_strcat(&unsetstr, " uname");
- else
+ } else {
keys &= ~F_UNAME;
+ if ((oldkeys & F_UNAME) != 0)
+ archive_strcat(&unsetstr, " uname");
+ }
}
if ((keys & effkeys & F_UID) != 0) {
- mtree->set.uid = archive_entry_uid(entry);
+ mtree->set.uid = mtree->set.uid_list->m_entry->uid;
archive_string_sprintf(&setstr, " uid=%jd",
(intmax_t)mtree->set.uid);
}
if ((keys & effkeys & F_GNAME) != 0) {
- if ((name = archive_entry_gname(entry)) != NULL) {
+ name = mtree->set.gid_list->m_entry->gname;
+ if (name != NULL) {
archive_strcat(&setstr, " gname=");
mtree_quote(&setstr, name);
- } else if ((oldkeys & F_GNAME) != 0)
- archive_strcat(&unsetstr, " gname");
- else
+ } else {
keys &= ~F_GNAME;
+ if ((oldkeys & F_GNAME) != 0)
+ archive_strcat(&unsetstr, " gname");
+ }
}
if ((keys & effkeys & F_GID) != 0) {
- mtree->set.gid = archive_entry_gid(entry);
+ mtree->set.gid = mtree->set.gid_list->m_entry->gid;
archive_string_sprintf(&setstr, " gid=%jd",
(intmax_t)mtree->set.gid);
}
if ((keys & effkeys & F_MODE) != 0) {
- mtree->set.mode = archive_entry_mode(entry) & 07777;
- archive_string_sprintf(&setstr, " mode=%o", mtree->set.mode);
+ mtree->set.mode = mtree->set.mode_list->m_entry->mode;
+ archive_string_sprintf(&setstr, " mode=%o",
+ (unsigned int)mtree->set.mode);
}
if ((keys & effkeys & F_FLAGS) != 0) {
- if ((name = archive_entry_fflags_text(entry)) != NULL) {
+ name = mtree->set.flags_list->m_entry->fflags_text;
+ if (name != NULL) {
archive_strcat(&setstr, " flags=");
mtree_quote(&setstr, name);
- archive_entry_fflags(entry, &mtree->set.fflags_set,
- &mtree->set.fflags_clear);
- } else if ((oldkeys & F_FLAGS) != 0)
- archive_strcat(&unsetstr, " flags");
- else
+ mtree->set.fflags_set =
+ mtree->set.flags_list->m_entry->fflags_set;
+ mtree->set.fflags_clear =
+ mtree->set.flags_list->m_entry->fflags_clear;
+ } else {
keys &= ~F_FLAGS;
+ if ((oldkeys & F_FLAGS) != 0)
+ archive_strcat(&unsetstr, " flags");
+ }
}
if (unsetstr.length > 0)
archive_string_sprintf(&mtree->buf, "/unset%s\n", unsetstr.s);
@@ -491,38 +579,196 @@ set_global(struct mtree_writer *mtree, struct archive_entry *entry)
archive_string_free(&setstr);
mtree->set.keys = keys;
mtree->set.processed = 1;
- /* On directory-only mode, it is only once to write /set keyword. */
- if (mtree->dironly)
- mtree->set.output = 0;
+
+ free_attr_count(&mtree->set.uid_list);
+ free_attr_count(&mtree->set.gid_list);
+ free_attr_count(&mtree->set.mode_list);
+ free_attr_count(&mtree->set.flags_list);
+}
+
+static struct attr_counter *
+new_attr_count(struct mtree_entry *me, struct attr_counter *prev)
+{
+ struct attr_counter *ac;
+
+ ac = malloc(sizeof(*ac));
+ if (ac != NULL) {
+ ac->prev = prev;
+ ac->next = NULL;
+ ac->count = 1;
+ ac->m_entry = me;
+ }
+ return (ac);
+}
+
+static void
+free_attr_count(struct attr_counter **top)
+{
+ struct attr_counter *ac, *tac;
+
+ if (*top == NULL)
+ return;
+ ac = *top;
+ while (ac != NULL) {
+ tac = ac->next;
+ free(ac);
+ ac = tac;
+ }
+ *top = NULL;
+}
+
+static int
+inc_attr_count(struct attr_counter **top, struct attr_counter *ac,
+ struct attr_counter *last, struct mtree_entry *me)
+{
+ struct attr_counter *pac;
+
+ if (ac != NULL) {
+ ac->count++;
+ if (*top == ac || ac->prev->count >= ac->count)
+ return (0);
+ for (pac = ac->prev; pac; pac = pac->prev) {
+ if (pac->count >= ac->count)
+ break;
+ }
+ ac->prev->next = ac->next;
+ if (ac->next != NULL)
+ ac->next->prev = ac->prev;
+ if (pac != NULL) {
+ ac->prev = pac;
+ ac->next = pac->next;
+ pac->next = ac;
+ if (ac->next != NULL)
+ ac->next->prev = ac;
+ } else {
+ ac->prev = NULL;
+ ac->next = *top;
+ *top = ac;
+ ac->next->prev = ac;
+ }
+ } else {
+ ac = new_attr_count(me, last);
+ if (ac == NULL)
+ return (-1);
+ last->next = ac;
+ }
+ return (0);
+}
+
+static int
+collect_set_values(struct mtree_writer *mtree, struct mtree_entry *me)
+{
+ int keys = mtree->keys;
+ struct attr_counter *ac, *last;
+
+ if (keys & (F_UNAME | F_UID)) {
+ if (mtree->set.uid_list == NULL) {
+ mtree->set.uid_list = new_attr_count(me, NULL);
+ if (mtree->set.uid_list == NULL)
+ return (-1);
+ } else {
+ last = NULL;
+ for (ac = mtree->set.uid_list; ac; ac = ac->next) {
+ if (ac->m_entry->uid == me->uid)
+ break;
+ last = ac;
+ }
+ if (inc_attr_count(
+ &mtree->set.uid_list, ac, last, me) < 0)
+ return (-1);
+ }
+ }
+ if (keys & (F_GNAME | F_GID)) {
+ if (mtree->set.gid_list == NULL) {
+ mtree->set.gid_list = new_attr_count(me, NULL);
+ if (mtree->set.gid_list == NULL)
+ return (-1);
+ } else {
+ last = NULL;
+ for (ac = mtree->set.gid_list; ac; ac = ac->next) {
+ if (ac->m_entry->gid == me->gid)
+ break;
+ last = ac;
+ }
+ if (inc_attr_count(
+ &mtree->set.gid_list, ac, last, me) < 0)
+ return (-1);
+ }
+ }
+ if (keys & F_MODE) {
+ if (mtree->set.mode_list == NULL) {
+ mtree->set.mode_list = new_attr_count(me, NULL);
+ if (mtree->set.mode_list == NULL)
+ return (-1);
+ } else {
+ last = NULL;
+ for (ac = mtree->set.mode_list; ac; ac = ac->next) {
+ if (ac->m_entry->mode == me->mode)
+ break;
+ last = ac;
+ }
+ if (inc_attr_count(
+ &mtree->set.mode_list, ac, last, me) < 0)
+ return (-1);
+ }
+ }
+ if (keys & F_FLAGS) {
+ if (mtree->set.flags_list == NULL) {
+ mtree->set.flags_list = new_attr_count(me, NULL);
+ if (mtree->set.flags_list == NULL)
+ return (-1);
+ } else {
+ last = NULL;
+ for (ac = mtree->set.flags_list; ac; ac = ac->next) {
+ if (ac->m_entry->fflags_set == me->fflags_set &&
+ ac->m_entry->fflags_clear == me->fflags_clear)
+ break;
+ last = ac;
+ }
+ if (inc_attr_count(
+ &mtree->set.flags_list, ac, last, me) < 0)
+ return (-1);
+ }
+ }
+
+ /*
+ * Save a entry.
+ */
+ me->next = NULL;
+ *mtree->set.me_last = me;
+ mtree->set.me_last = &me->next;
+ return (0);
}
static int
-get_keys(struct mtree_writer *mtree, struct archive_entry *entry)
+get_keys(struct mtree_writer *mtree, struct mtree_entry *me)
{
int keys;
keys = mtree->keys;
+
+ /*
+ * If a keyword has been set by /set, we do not need to
+ * output it.
+ */
if (mtree->set.keys == 0)
- return (keys);
+ return (keys);/* /set is not used. */
+
if ((mtree->set.keys & (F_GNAME | F_GID)) != 0 &&
- mtree->set.gid == archive_entry_gid(entry))
+ mtree->set.gid == me->gid)
keys &= ~(F_GNAME | F_GID);
if ((mtree->set.keys & (F_UNAME | F_UID)) != 0 &&
- mtree->set.uid == archive_entry_uid(entry))
+ mtree->set.uid == me->uid)
keys &= ~(F_UNAME | F_UID);
if (mtree->set.keys & F_FLAGS) {
- unsigned long set, clear;
-
- archive_entry_fflags(entry, &set, &clear);
- if (mtree->set.fflags_set == set &&
- mtree->set.fflags_clear == clear)
+ if (mtree->set.fflags_set == me->fflags_set &&
+ mtree->set.fflags_clear == me->fflags_clear)
keys &= ~F_FLAGS;
}
- if ((mtree->set.keys & F_MODE) != 0 &&
- mtree->set.mode == (archive_entry_mode(entry) & 07777))
+ if ((mtree->set.keys & F_MODE) != 0 && mtree->set.mode == me->mode)
keys &= ~F_MODE;
- switch (archive_entry_filetype(entry)) {
+ switch (me->filetype) {
case AE_IFLNK: case AE_IFSOCK: case AE_IFCHR:
case AE_IFBLK: case AE_IFIFO:
break;
@@ -542,171 +788,145 @@ get_keys(struct mtree_writer *mtree, struct archive_entry *entry)
return (keys);
}
+static struct mtree_entry *
+new_mtree_entry(struct archive_entry *entry)
+{
+ struct mtree_entry *me;
+ const char *s;
+
+ me = calloc(1, sizeof(*me));
+ if (me == NULL)
+ return (NULL);
+ me->pathname = strdup(archive_entry_pathname(entry));
+ if ((s = archive_entry_symlink(entry)) != NULL)
+ me->symlink = strdup(s);
+ else
+ me->symlink = NULL;
+ me->nlink = archive_entry_nlink(entry);
+ me->filetype = archive_entry_filetype(entry);
+ me->mode = archive_entry_mode(entry) & 07777;
+ me->uid = archive_entry_uid(entry);
+ me->gid = archive_entry_gid(entry);
+ if ((s = archive_entry_uname(entry)) != NULL)
+ me->uname = strdup(s);
+ else
+ me->uname = NULL;
+ if ((s = archive_entry_gname(entry)) != NULL)
+ me->gname = strdup(s);
+ else
+ me->gname = NULL;
+ if ((s = archive_entry_fflags_text(entry)) != NULL)
+ me->fflags_text = strdup(s);
+ else
+ me->fflags_text = NULL;
+ archive_entry_fflags(entry, &me->fflags_set, &me->fflags_clear);
+ me->mtime = archive_entry_mtime(entry);
+ me->mtime_nsec = archive_entry_mtime_nsec(entry);
+ me->rdevmajor = archive_entry_rdevmajor(entry);
+ me->rdevminor = archive_entry_rdevminor(entry);
+ me->size = archive_entry_size(entry);
+ me->compute_sum = 0;
+
+ return (me);
+}
+
+static void
+free_mtree_entry(struct mtree_entry *me)
+{
+ free(me->pathname);
+ free(me->symlink);
+ free(me->uname);
+ free(me->gname);
+ free(me->fflags_text);
+ free(me);
+}
+
static int
archive_write_mtree_header(struct archive_write *a,
struct archive_entry *entry)
{
struct mtree_writer *mtree= a->format_data;
- struct archive_string *str;
- const char *path;
-
- mtree->entry = archive_entry_clone(entry);
- path = archive_entry_pathname(mtree->entry);
if (mtree->first) {
mtree->first = 0;
archive_strcat(&mtree->buf, "#mtree\n");
+ if ((mtree->keys & SET_KEYS) == 0)
+ mtree->set.output = 0;/* Disalbed. */
}
- if (mtree->set.output)
- set_global(mtree, entry);
-
- archive_string_empty(&mtree->ebuf);
- str = (mtree->indent)? &mtree->ebuf : &mtree->buf;
- if (!mtree->dironly || archive_entry_filetype(entry) == AE_IFDIR)
- mtree_quote(str, path);
mtree->entry_bytes_remaining = archive_entry_size(entry);
- if ((mtree->keys & F_CKSUM) != 0 &&
- archive_entry_filetype(entry) == AE_IFREG) {
- mtree->compute_sum |= F_CKSUM;
- mtree->crc = 0;
- mtree->crc_len = 0;
- } else
- mtree->compute_sum &= ~F_CKSUM;
-#ifdef ARCHIVE_HAS_MD5
- if ((mtree->keys & F_MD5) != 0 &&
- archive_entry_filetype(entry) == AE_IFREG) {
- mtree->compute_sum |= F_MD5;
- archive_md5_init(&mtree->md5ctx);
- } else
- mtree->compute_sum &= ~F_MD5;
-#endif
-#ifdef ARCHIVE_HAS_RMD160
- if ((mtree->keys & F_RMD160) != 0 &&
- archive_entry_filetype(entry) == AE_IFREG) {
- mtree->compute_sum |= F_RMD160;
- archive_rmd160_init(&mtree->rmd160ctx);
- } else
- mtree->compute_sum &= ~F_RMD160;
-#endif
-#ifdef ARCHIVE_HAS_SHA1
- if ((mtree->keys & F_SHA1) != 0 &&
- archive_entry_filetype(entry) == AE_IFREG) {
- mtree->compute_sum |= F_SHA1;
- archive_sha1_init(&mtree->sha1ctx);
- } else
- mtree->compute_sum &= ~F_SHA1;
-#endif
-#ifdef ARCHIVE_HAS_SHA256
- if ((mtree->keys & F_SHA256) != 0 &&
- archive_entry_filetype(entry) == AE_IFREG) {
- mtree->compute_sum |= F_SHA256;
- archive_sha256_init(&mtree->sha256ctx);
- } else
- mtree->compute_sum &= ~F_SHA256;
-#endif
-#ifdef ARCHIVE_HAS_SHA384
- if ((mtree->keys & F_SHA384) != 0 &&
- archive_entry_filetype(entry) == AE_IFREG) {
- mtree->compute_sum |= F_SHA384;
- archive_sha384_init(&mtree->sha384ctx);
- } else
- mtree->compute_sum &= ~F_SHA384;
-#endif
-#ifdef ARCHIVE_HAS_SHA512
- if ((mtree->keys & F_SHA512) != 0 &&
- archive_entry_filetype(entry) == AE_IFREG) {
- mtree->compute_sum |= F_SHA512;
- archive_sha512_init(&mtree->sha512ctx);
- } else
- mtree->compute_sum &= ~F_SHA512;
-#endif
+ if (mtree->dironly && archive_entry_filetype(entry) != AE_IFDIR)
+ return (ARCHIVE_OK);
- return (ARCHIVE_OK);
-}
+ mtree->mtree_entry = new_mtree_entry(entry);
+ if (mtree->mtree_entry == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate mtree entry");
+ return (ARCHIVE_FATAL);
+ }
-#if defined(ARCHIVE_HAS_MD5) || defined(ARCHIVE_HAS_RMD160) || \
- defined(ARCHIVE_HAS_SHA1) || defined(ARCHIVE_HAS_SHA256) || \
- defined(ARCHIVE_HAS_SHA384) || defined(ARCHIVE_HAS_SHA512)
-static void
-strappend_bin(struct archive_string *s, const unsigned char *bin, int n)
-{
- static const char hex[] = "0123456789abcdef";
- int i;
+ mtree->compute_sum = 0;
- for (i = 0; i < n; i++) {
- archive_strappend_char(s, hex[bin[i] >> 4]);
- archive_strappend_char(s, hex[bin[i] & 0x0f]);
- }
+ /* If current file is not a regular file, we do not have to
+ * compute the sum of its content. */
+ if (archive_entry_filetype(entry) != AE_IFREG)
+ return (ARCHIVE_OK);
+
+ /* Initialize a bunch of sum check context. */
+ sum_init(mtree);
+
+ return (ARCHIVE_OK);
}
-#endif
static int
-archive_write_mtree_finish_entry(struct archive_write *a)
+write_entry(struct archive_write *a, struct mtree_entry *me)
{
struct mtree_writer *mtree = a->format_data;
- struct archive_entry *entry;
struct archive_string *str;
- const char *name;
int keys, ret;
- entry = mtree->entry;
- if (entry == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "Finished entry without being open first.");
- return (ARCHIVE_FATAL);
- }
- mtree->entry = NULL;
-
- if (mtree->dironly && archive_entry_filetype(entry) != AE_IFDIR) {
- archive_entry_free(entry);
- return (ARCHIVE_OK);
- }
-
+ archive_string_empty(&mtree->ebuf);
str = (mtree->indent)? &mtree->ebuf : &mtree->buf;
- keys = get_keys(mtree, entry);
+ mtree_quote(str, me->pathname);
+ keys = get_keys(mtree, me);
if ((keys & F_NLINK) != 0 &&
- archive_entry_nlink(entry) != 1 &&
- archive_entry_filetype(entry) != AE_IFDIR)
- archive_string_sprintf(str,
- " nlink=%u", archive_entry_nlink(entry));
+ me->nlink != 1 && me->filetype != AE_IFDIR)
+ archive_string_sprintf(str, " nlink=%u", me->nlink);
- if ((keys & F_GNAME) != 0 &&
- (name = archive_entry_gname(entry)) != NULL) {
+ if ((keys & F_GNAME) != 0 && me->gname != NULL) {
archive_strcat(str, " gname=");
- mtree_quote(str, name);
+ mtree_quote(str, me->gname);
}
- if ((keys & F_UNAME) != 0 &&
- (name = archive_entry_uname(entry)) != NULL) {
+ if ((keys & F_UNAME) != 0 && me->uname != NULL) {
archive_strcat(str, " uname=");
- mtree_quote(str, name);
+ mtree_quote(str, me->uname);
}
- if ((keys & F_FLAGS) != 0 &&
- (name = archive_entry_fflags_text(entry)) != NULL) {
- archive_strcat(str, " flags=");
- mtree_quote(str, name);
+ if ((keys & F_FLAGS) != 0) {
+ if (me->fflags_text != NULL) {
+ archive_strcat(str, " flags=");
+ mtree_quote(str, me->fflags_text);
+ } else if (mtree->set.processed &&
+ (mtree->set.keys & F_FLAGS) != 0)
+ /* Overwrite the global parameter. */
+ archive_strcat(str, " flags=none");
}
if ((keys & F_TIME) != 0)
archive_string_sprintf(str, " time=%jd.%jd",
- (intmax_t)archive_entry_mtime(entry),
- (intmax_t)archive_entry_mtime_nsec(entry));
+ (intmax_t)me->mtime, (intmax_t)me->mtime_nsec);
if ((keys & F_MODE) != 0)
- archive_string_sprintf(str, " mode=%o",
- archive_entry_mode(entry) & 07777);
+ archive_string_sprintf(str, " mode=%o", (unsigned int)me->mode);
if ((keys & F_GID) != 0)
- archive_string_sprintf(str, " gid=%jd",
- (intmax_t)archive_entry_gid(entry));
+ archive_string_sprintf(str, " gid=%jd", (intmax_t)me->gid);
if ((keys & F_UID) != 0)
- archive_string_sprintf(str, " uid=%jd",
- (intmax_t)archive_entry_uid(entry));
+ archive_string_sprintf(str, " uid=%jd", (intmax_t)me->uid);
- switch (archive_entry_filetype(entry)) {
+ switch (me->filetype) {
case AE_IFLNK:
if ((keys & F_TYPE) != 0)
archive_strcat(str, " type=link");
if ((keys & F_SLINK) != 0) {
archive_strcat(str, " link=");
- mtree_quote(str, archive_entry_symlink(entry));
+ mtree_quote(str, me->symlink);
}
break;
case AE_IFSOCK:
@@ -718,9 +938,9 @@ archive_write_mtree_finish_entry(struct archive_write *a)
archive_strcat(str, " type=char");
if ((keys & F_DEV) != 0) {
archive_string_sprintf(str,
- " device=native,%d,%d",
- archive_entry_rdevmajor(entry),
- archive_entry_rdevminor(entry));
+ " device=native,%ju,%ju",
+ (uintmax_t)me->rdevmajor,
+ (uintmax_t)me->rdevminor);
}
break;
case AE_IFBLK:
@@ -728,9 +948,9 @@ archive_write_mtree_finish_entry(struct archive_write *a)
archive_strcat(str, " type=block");
if ((keys & F_DEV) != 0) {
archive_string_sprintf(str,
- " device=native,%d,%d",
- archive_entry_rdevmajor(entry),
- archive_entry_rdevminor(entry));
+ " device=native,%ju,%ju",
+ (uintmax_t)me->rdevmajor,
+ (uintmax_t)me->rdevminor);
}
break;
case AE_IFDIR:
@@ -747,96 +967,110 @@ archive_write_mtree_finish_entry(struct archive_write *a)
archive_strcat(str, " type=file");
if ((keys & F_SIZE) != 0)
archive_string_sprintf(str, " size=%jd",
- (intmax_t)archive_entry_size(entry));
+ (intmax_t)me->size);
break;
}
- if (mtree->compute_sum & F_CKSUM) {
- uint64_t len;
- /* Include the length of the file. */
- for (len = mtree->crc_len; len != 0; len >>= 8)
- COMPUTE_CRC(mtree->crc, len & 0xff);
- mtree->crc = ~mtree->crc;
- archive_string_sprintf(str, " cksum=%ju",
- (uintmax_t)mtree->crc);
- }
-#ifdef ARCHIVE_HAS_MD5
- if (mtree->compute_sum & F_MD5) {
- unsigned char buf[16];
-
- archive_md5_final(&mtree->md5ctx, buf);
- archive_strcat(str, " md5digest=");
- strappend_bin(str, buf, sizeof(buf));
- }
-#endif
-#ifdef ARCHIVE_HAS_RMD160
- if (mtree->compute_sum & F_RMD160) {
- unsigned char buf[20];
-
- archive_rmd160_final(&mtree->rmd160ctx, buf);
- archive_strcat(str, " rmd160digest=");
- strappend_bin(str, buf, sizeof(buf));
- }
-#endif
-#ifdef ARCHIVE_HAS_SHA1
- if (mtree->compute_sum & F_SHA1) {
- unsigned char buf[20];
-
- archive_sha1_final(&mtree->sha1ctx, buf);
- archive_strcat(str, " sha1digest=");
- strappend_bin(str, buf, sizeof(buf));
- }
-#endif
-#ifdef ARCHIVE_HAS_SHA256
- if (mtree->compute_sum & F_SHA256) {
- unsigned char buf[32];
-
- archive_sha256_final(&mtree->sha256ctx, buf);
- archive_strcat(str, " sha256digest=");
- strappend_bin(str, buf, sizeof(buf));
- }
-#endif
-#ifdef ARCHIVE_HAS_SHA384
- if (mtree->compute_sum & F_SHA384) {
- unsigned char buf[48];
+ /* Write a bunch of sum. */
+ if (me->filetype == AE_IFREG)
+ sum_write(str, me);
- archive_sha384_final(&mtree->sha384ctx, buf);
- archive_strcat(str, " sha384digest=");
- strappend_bin(str, buf, sizeof(buf));
- }
-#endif
-#ifdef ARCHIVE_HAS_SHA512
- if (mtree->compute_sum & F_SHA512) {
- unsigned char buf[64];
-
- archive_sha512_final(&mtree->sha512ctx, buf);
- archive_strcat(str, " sha512digest=");
- strappend_bin(str, buf, sizeof(buf));
- }
-#endif
archive_strcat(str, "\n");
if (mtree->indent)
mtree_indent(mtree);
- archive_entry_free(entry);
-
if (mtree->buf.length > 32768) {
- ret = (a->compressor.write)(a, mtree->buf.s, mtree->buf.length);
+ ret = __archive_write_output(a, mtree->buf.s, mtree->buf.length);
archive_string_empty(&mtree->buf);
} else
ret = ARCHIVE_OK;
+ return (ret);
+}
+
+/*
+ * Write mtree entries saved at collect_set_values() function.
+ */
+static int
+write_mtree_entries(struct archive_write *a)
+{
+ struct mtree_writer *mtree = a->format_data;
+ struct mtree_entry *me, *tme;
+ int ret;
+
+ for (me = mtree->set.me_first; me; me = me->next) {
+ ret = write_entry(a, me);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+
+ me = mtree->set.me_first;
+ while (me != NULL) {
+ tme = me->next;
+ free_mtree_entry(me);
+ me = tme;
+ }
+ mtree->set.me_first = NULL;
+ mtree->set.me_last = &mtree->set.me_first;
+ return (ARCHIVE_OK);
+}
+static int
+archive_write_mtree_finish_entry(struct archive_write *a)
+{
+ struct mtree_writer *mtree = a->format_data;
+ struct mtree_entry *me;
+ int ret;
+
+ if ((me = mtree->mtree_entry) == NULL)
+ return (ARCHIVE_OK);
+ mtree->mtree_entry = NULL;
+
+ if (me->filetype == AE_IFREG)
+ sum_final(mtree, me);
+
+ if (mtree->set.output) {
+ if (!mtree->dironly) {
+ if (archive_strlen(&mtree->set.parent) == 0)
+ parent_dir_changed(&mtree->set.parent, me);
+ if (parent_dir_changed(&mtree->set.parent, me)) {
+ /* Write /set keyword */
+ write_global(mtree);
+ /* Write entries saved by
+ * collect_set_values() function. */
+ ret = write_mtree_entries(a);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+ }
+ /* Tabulate uid,gid,mode and fflags of a entry
+ * in order to be used for /set. and, at this time
+ * we do not write a entry. */
+ collect_set_values(mtree, me);
+ return (ARCHIVE_OK);
+ } else {
+ /* Write the current entry and free it. */
+ ret = write_entry(a, me);
+ free_mtree_entry(me);
+ }
return (ret == ARCHIVE_OK ? ret : ARCHIVE_FATAL);
}
static int
-archive_write_mtree_finish(struct archive_write *a)
+archive_write_mtree_close(struct archive_write *a)
{
struct mtree_writer *mtree= a->format_data;
+ int ret;
+
+ if (mtree->set.output && mtree->set.me_first != NULL) {
+ write_global(mtree);
+ ret = write_mtree_entries(a);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
archive_write_set_bytes_in_last_block(&a->archive, 1);
- return (a->compressor.write)(a, mtree->buf.s, mtree->buf.length);
+ return __archive_write_output(a, mtree->buf.s, mtree->buf.length);
}
static ssize_t
@@ -846,59 +1080,41 @@ archive_write_mtree_data(struct archive_write *a, const void *buff, size_t n)
if (n > mtree->entry_bytes_remaining)
n = mtree->entry_bytes_remaining;
- if (mtree->dironly)
- /* We don't need compute a regular file sum */
+ mtree->entry_bytes_remaining -= n;
+
+ /* We don't need to compute a regular file sum */
+ if (mtree->mtree_entry == NULL)
return (n);
- if (mtree->compute_sum & F_CKSUM) {
- /*
- * Compute a POSIX 1003.2 checksum
- */
- const unsigned char *p;
- size_t nn;
- for (nn = n, p = buff; nn--; ++p)
- COMPUTE_CRC(mtree->crc, *p);
- mtree->crc_len += n;
- }
-#ifdef ARCHIVE_HAS_MD5
- if (mtree->compute_sum & F_MD5)
- archive_md5_update(&mtree->md5ctx, buff, n);
-#endif
-#ifdef ARCHIVE_HAS_RMD160
- if (mtree->compute_sum & F_RMD160)
- archive_rmd160_update(&mtree->rmd160ctx, buff, n);
-#endif
-#ifdef ARCHIVE_HAS_SHA1
- if (mtree->compute_sum & F_SHA1)
- archive_sha1_update(&mtree->sha1ctx, buff, n);
-#endif
-#ifdef ARCHIVE_HAS_SHA256
- if (mtree->compute_sum & F_SHA256)
- archive_sha256_update(&mtree->sha256ctx, buff, n);
-#endif
-#ifdef ARCHIVE_HAS_SHA384
- if (mtree->compute_sum & F_SHA384)
- archive_sha384_update(&mtree->sha384ctx, buff, n);
-#endif
-#ifdef ARCHIVE_HAS_SHA512
- if (mtree->compute_sum & F_SHA512)
- archive_sha512_update(&mtree->sha512ctx, buff, n);
-#endif
+ if (mtree->mtree_entry->filetype == AE_IFREG)
+ sum_update(mtree, buff, n);
+
return (n);
}
static int
-archive_write_mtree_destroy(struct archive_write *a)
+archive_write_mtree_free(struct archive_write *a)
{
struct mtree_writer *mtree= a->format_data;
+ struct mtree_entry *me, *tme;
if (mtree == NULL)
return (ARCHIVE_OK);
- archive_entry_free(mtree->entry);
+ /* Make sure we dot not leave any entries. */
+ me = mtree->set.me_first;
+ while (me != NULL) {
+ tme = me->next;
+ free_mtree_entry(me);
+ me = tme;
+ }
archive_string_free(&mtree->ebuf);
archive_string_free(&mtree->buf);
archive_string_free(&mtree->set.parent);
+ free_attr_count(&mtree->set.uid_list);
+ free_attr_count(&mtree->set.gid_list);
+ free_attr_count(&mtree->set.mode_list);
+ free_attr_count(&mtree->set.flags_list);
free(mtree);
a->format_data = NULL;
return (ARCHIVE_OK);
@@ -1006,7 +1222,7 @@ archive_write_mtree_options(struct archive_write *a, const char *key,
return (ARCHIVE_OK);
}
- return (ARCHIVE_WARN);
+ return (ARCHIVE_FAILED);
}
int
@@ -1015,16 +1231,19 @@ archive_write_set_format_mtree(struct archive *_a)
struct archive_write *a = (struct archive_write *)_a;
struct mtree_writer *mtree;
- if (a->format_destroy != NULL)
- (a->format_destroy)(a);
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_mtree");
+
+ if (a->format_free != NULL)
+ (a->format_free)(a);
- if ((mtree = malloc(sizeof(*mtree))) == NULL) {
+ if ((mtree = calloc(1, sizeof(*mtree))) == NULL) {
archive_set_error(&a->archive, ENOMEM,
"Can't allocate mtree data");
return (ARCHIVE_FATAL);
}
- mtree->entry = NULL;
+ mtree->mtree_entry = NULL;
mtree->first = 1;
memset(&(mtree->set), 0, sizeof(mtree->set));
archive_string_init(&mtree->set.parent);
@@ -1033,14 +1252,14 @@ archive_write_set_format_mtree(struct archive *_a)
mtree->indent = 0;
archive_string_init(&mtree->ebuf);
archive_string_init(&mtree->buf);
+ mtree->set.me_first = NULL;
+ mtree->set.me_last = &mtree->set.me_first;
a->format_data = mtree;
- a->format_destroy = archive_write_mtree_destroy;
-
- a->pad_uncompressed = 0;
+ a->format_free = archive_write_mtree_free;
a->format_name = "mtree";
a->format_options = archive_write_mtree_options;
a->format_write_header = archive_write_mtree_header;
- a->format_finish = archive_write_mtree_finish;
+ a->format_close = archive_write_mtree_close;
a->format_write_data = archive_write_mtree_data;
a->format_finish_entry = archive_write_mtree_finish_entry;
a->archive.archive_format = ARCHIVE_FORMAT_MTREE;
@@ -1048,3 +1267,202 @@ archive_write_set_format_mtree(struct archive *_a)
return (ARCHIVE_OK);
}
+
+static void
+sum_init(struct mtree_writer *mtree)
+{
+ if (mtree->keys & F_CKSUM) {
+ mtree->compute_sum |= F_CKSUM;
+ mtree->crc = 0;
+ mtree->crc_len = 0;
+ }
+#ifdef ARCHIVE_HAS_MD5
+ if (mtree->keys & F_MD5) {
+ if (archive_md5_init(&mtree->md5ctx) == ARCHIVE_OK)
+ mtree->compute_sum |= F_MD5;
+ else
+ mtree->keys &= ~F_MD5;/* Not supported. */
+ }
+#endif
+#ifdef ARCHIVE_HAS_RMD160
+ if (mtree->keys & F_RMD160) {
+ if (archive_rmd160_init(&mtree->rmd160ctx) == ARCHIVE_OK)
+ mtree->compute_sum |= F_RMD160;
+ else
+ mtree->keys &= ~F_RMD160;/* Not supported. */
+ }
+#endif
+#ifdef ARCHIVE_HAS_SHA1
+ if (mtree->keys & F_SHA1) {
+ if (archive_sha1_init(&mtree->sha1ctx) == ARCHIVE_OK)
+ mtree->compute_sum |= F_SHA1;
+ else
+ mtree->keys &= ~F_SHA1;/* Not supported. */
+ }
+#endif
+#ifdef ARCHIVE_HAS_SHA256
+ if (mtree->keys & F_SHA256) {
+ if (archive_sha256_init(&mtree->sha256ctx) == ARCHIVE_OK)
+ mtree->compute_sum |= F_SHA256;
+ else
+ mtree->keys &= ~F_SHA256;/* Not supported. */
+ }
+#endif
+#ifdef ARCHIVE_HAS_SHA384
+ if (mtree->keys & F_SHA384) {
+ if (archive_sha384_init(&mtree->sha384ctx) == ARCHIVE_OK)
+ mtree->compute_sum |= F_SHA384;
+ else
+ mtree->keys &= ~F_SHA384;/* Not supported. */
+ }
+#endif
+#ifdef ARCHIVE_HAS_SHA512
+ if (mtree->keys & F_SHA512) {
+ if (archive_sha512_init(&mtree->sha512ctx) == ARCHIVE_OK)
+ mtree->compute_sum |= F_SHA512;
+ else
+ mtree->keys &= ~F_SHA512;/* Not supported. */
+ }
+#endif
+}
+
+static void
+sum_update(struct mtree_writer *mtree, const void *buff, size_t n)
+{
+ if (mtree->compute_sum & F_CKSUM) {
+ /*
+ * Compute a POSIX 1003.2 checksum
+ */
+ const unsigned char *p;
+ size_t nn;
+
+ for (nn = n, p = buff; nn--; ++p)
+ COMPUTE_CRC(mtree->crc, *p);
+ mtree->crc_len += n;
+ }
+#ifdef ARCHIVE_HAS_MD5
+ if (mtree->compute_sum & F_MD5)
+ archive_md5_update(&mtree->md5ctx, buff, n);
+#endif
+#ifdef ARCHIVE_HAS_RMD160
+ if (mtree->compute_sum & F_RMD160)
+ archive_rmd160_update(&mtree->rmd160ctx, buff, n);
+#endif
+#ifdef ARCHIVE_HAS_SHA1
+ if (mtree->compute_sum & F_SHA1)
+ archive_sha1_update(&mtree->sha1ctx, buff, n);
+#endif
+#ifdef ARCHIVE_HAS_SHA256
+ if (mtree->compute_sum & F_SHA256)
+ archive_sha256_update(&mtree->sha256ctx, buff, n);
+#endif
+#ifdef ARCHIVE_HAS_SHA384
+ if (mtree->compute_sum & F_SHA384)
+ archive_sha384_update(&mtree->sha384ctx, buff, n);
+#endif
+#ifdef ARCHIVE_HAS_SHA512
+ if (mtree->compute_sum & F_SHA512)
+ archive_sha512_update(&mtree->sha512ctx, buff, n);
+#endif
+}
+
+static void
+sum_final(struct mtree_writer *mtree, struct mtree_entry *me)
+{
+
+ if (mtree->compute_sum & F_CKSUM) {
+ uint64_t len;
+ /* Include the length of the file. */
+ for (len = mtree->crc_len; len != 0; len >>= 8)
+ COMPUTE_CRC(mtree->crc, len & 0xff);
+ me->crc = ~mtree->crc;
+ }
+#ifdef ARCHIVE_HAS_MD5
+ if (mtree->compute_sum & F_MD5)
+ archive_md5_final(&mtree->md5ctx, me->buf_md5);
+#endif
+#ifdef ARCHIVE_HAS_RMD160
+ if (mtree->compute_sum & F_RMD160)
+ archive_rmd160_final(&mtree->rmd160ctx, me->buf_rmd160);
+#endif
+#ifdef ARCHIVE_HAS_SHA1
+ if (mtree->compute_sum & F_SHA1)
+ archive_sha1_final(&mtree->sha1ctx, me->buf_sha1);
+#endif
+#ifdef ARCHIVE_HAS_SHA256
+ if (mtree->compute_sum & F_SHA256)
+ archive_sha256_final(&mtree->sha256ctx, me->buf_sha256);
+#endif
+#ifdef ARCHIVE_HAS_SHA384
+ if (mtree->compute_sum & F_SHA384)
+ archive_sha384_final(&mtree->sha384ctx, me->buf_sha384);
+#endif
+#ifdef ARCHIVE_HAS_SHA512
+ if (mtree->compute_sum & F_SHA512)
+ archive_sha512_final(&mtree->sha512ctx, me->buf_sha512);
+#endif
+ /* Save what types of sum are computed. */
+ me->compute_sum = mtree->compute_sum;
+}
+
+#if defined(ARCHIVE_HAS_MD5) || defined(ARCHIVE_HAS_RMD160) || \
+ defined(ARCHIVE_HAS_SHA1) || defined(ARCHIVE_HAS_SHA256) || \
+ defined(ARCHIVE_HAS_SHA384) || defined(ARCHIVE_HAS_SHA512)
+static void
+strappend_bin(struct archive_string *s, const unsigned char *bin, int n)
+{
+ static const char hex[] = "0123456789abcdef";
+ int i;
+
+ for (i = 0; i < n; i++) {
+ archive_strappend_char(s, hex[bin[i] >> 4]);
+ archive_strappend_char(s, hex[bin[i] & 0x0f]);
+ }
+}
+#endif
+
+static void
+sum_write(struct archive_string *str, struct mtree_entry *me)
+{
+
+ if (me->compute_sum & F_CKSUM) {
+ archive_string_sprintf(str, " cksum=%ju",
+ (uintmax_t)me->crc);
+ }
+#ifdef ARCHIVE_HAS_MD5
+ if (me->compute_sum & F_MD5) {
+ archive_strcat(str, " md5digest=");
+ strappend_bin(str, me->buf_md5, sizeof(me->buf_md5));
+ }
+#endif
+#ifdef ARCHIVE_HAS_RMD160
+ if (me->compute_sum & F_RMD160) {
+ archive_strcat(str, " rmd160digest=");
+ strappend_bin(str, me->buf_rmd160, sizeof(me->buf_rmd160));
+ }
+#endif
+#ifdef ARCHIVE_HAS_SHA1
+ if (me->compute_sum & F_SHA1) {
+ archive_strcat(str, " sha1digest=");
+ strappend_bin(str, me->buf_sha1, sizeof(me->buf_sha1));
+ }
+#endif
+#ifdef ARCHIVE_HAS_SHA256
+ if (me->compute_sum & F_SHA256) {
+ archive_strcat(str, " sha256digest=");
+ strappend_bin(str, me->buf_sha256, sizeof(me->buf_sha256));
+ }
+#endif
+#ifdef ARCHIVE_HAS_SHA384
+ if (me->compute_sum & F_SHA384) {
+ archive_strcat(str, " sha384digest=");
+ strappend_bin(str, me->buf_sha384, sizeof(me->buf_sha384));
+ }
+#endif
+#ifdef ARCHIVE_HAS_SHA512
+ if (me->compute_sum & F_SHA512) {
+ archive_strcat(str, " sha512digest=");
+ strappend_bin(str, me->buf_sha512, sizeof(me->buf_sha512));
+ }
+#endif
+}
diff --git a/libarchive/archive_write_set_format_pax.c b/libarchive/archive_write_set_format_pax.c
index 00c3f3f08ccb..a62d99df8c1f 100644
--- a/libarchive/archive_write_set_format_pax.c
+++ b/libarchive/archive_write_set_format_pax.c
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2010-2011 Michihiro NAKAJIMA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -38,13 +39,28 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_pax.c 201162 20
#include "archive.h"
#include "archive_entry.h"
+#include "archive_entry_locale.h"
#include "archive_private.h"
#include "archive_write_private.h"
+struct sparse_block {
+ struct sparse_block *next;
+ int is_hole;
+ uint64_t offset;
+ uint64_t remaining;
+};
+
struct pax {
uint64_t entry_bytes_remaining;
uint64_t entry_padding;
+ struct archive_string l_url_encoded_name;
struct archive_string pax_header;
+ struct archive_string sparse_map;
+ size_t sparse_map_padding;
+ struct sparse_block *sparse_list;
+ struct sparse_block *sparse_tail;
+ struct archive_string_conv *sconv_utf8;
+ int opt_binary;
};
static void add_pax_attr(struct archive_string *, const char *key,
@@ -54,23 +70,25 @@ static void add_pax_attr_int(struct archive_string *,
static void add_pax_attr_time(struct archive_string *,
const char *key, int64_t sec,
unsigned long nanos);
-static void add_pax_attr_w(struct archive_string *,
- const char *key, const wchar_t *wvalue);
static ssize_t archive_write_pax_data(struct archive_write *,
const void *, size_t);
-static int archive_write_pax_finish(struct archive_write *);
-static int archive_write_pax_destroy(struct archive_write *);
+static int archive_write_pax_close(struct archive_write *);
+static int archive_write_pax_free(struct archive_write *);
static int archive_write_pax_finish_entry(struct archive_write *);
static int archive_write_pax_header(struct archive_write *,
struct archive_entry *);
+static int archive_write_pax_options(struct archive_write *,
+ const char *, const char *);
static char *base64_encode(const char *src, size_t len);
+static char *build_gnu_sparse_name(char *dest, const char *src);
static char *build_pax_attribute_name(char *dest, const char *src);
static char *build_ustar_entry_name(char *dest, const char *src,
size_t src_length, const char *insert);
static char *format_int(char *dest, int64_t);
-static int has_non_ASCII(const wchar_t *);
+static int has_non_ASCII(const char *);
+static void sparse_list_clear(struct pax *);
+static int sparse_list_add(struct pax *, int64_t, int64_t);
static char *url_encode(const char *in);
-static int write_nulls(struct archive_write *, size_t);
/*
* Set output format to 'restricted pax' format.
@@ -84,6 +102,10 @@ archive_write_set_format_pax_restricted(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
int r;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_pax_restricted");
+
r = archive_write_set_format_pax(&a->archive);
a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED;
a->archive.archive_format_name = "restricted POSIX pax interchange";
@@ -99,29 +121,79 @@ archive_write_set_format_pax(struct archive *_a)
struct archive_write *a = (struct archive_write *)_a;
struct pax *pax;
- if (a->format_destroy != NULL)
- (a->format_destroy)(a);
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_pax");
+
+ if (a->format_free != NULL)
+ (a->format_free)(a);
pax = (struct pax *)malloc(sizeof(*pax));
if (pax == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Can't allocate pax data");
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate pax data");
return (ARCHIVE_FATAL);
}
memset(pax, 0, sizeof(*pax));
a->format_data = pax;
-
- a->pad_uncompressed = 1;
a->format_name = "pax";
+ a->format_options = archive_write_pax_options;
a->format_write_header = archive_write_pax_header;
a->format_write_data = archive_write_pax_data;
- a->format_finish = archive_write_pax_finish;
- a->format_destroy = archive_write_pax_destroy;
+ a->format_close = archive_write_pax_close;
+ a->format_free = archive_write_pax_free;
a->format_finish_entry = archive_write_pax_finish_entry;
a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
a->archive.archive_format_name = "POSIX pax interchange";
return (ARCHIVE_OK);
}
+static int
+archive_write_pax_options(struct archive_write *a, const char *key,
+ const char *val)
+{
+ struct pax *pax = (struct pax *)a->format_data;
+ int ret = ARCHIVE_FAILED;
+
+ if (strcmp(key, "hdrcharset") == 0) {
+ /*
+ * The character-set we can use are defined in
+ * IEEE Std 1003.1-2001
+ */
+ if (val == NULL || val[0] == 0)
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "pax: hdrcharset option needs a character-set name");
+ else if (strcmp(val, "BINARY") == 0 ||
+ strcmp(val, "binary") == 0) {
+ /*
+ * Specify binary mode. We will not convert
+ * filenames, uname and gname to any charsets.
+ */
+ pax->opt_binary = 1;
+ ret = ARCHIVE_OK;
+ } else if (strcmp(val, "UTF-8") == 0) {
+ /*
+ * Specify UTF-8 character-set to be used for
+ * filenames. This is almost the test that
+ * running platform supports the string conversion.
+ * Especially libarchive_test needs this trick for
+ * its test.
+ */
+ pax->sconv_utf8 = archive_string_conversion_to_charset(
+ &(a->archive), "UTF-8", 0);
+ if (pax->sconv_utf8 == NULL)
+ ret = ARCHIVE_FATAL;
+ else
+ ret = ARCHIVE_OK;
+ } else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "pax: invalid charset name");
+ } else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "pax: unknown keyword ``%s''", key);
+
+ return (ret);
+}
+
/*
* Note: This code assumes that 'nanos' has the same sign as 'sec',
* which implies that sec=-1, nanos=200000000 represents -1.2 seconds
@@ -168,18 +240,17 @@ add_pax_attr_time(struct archive_string *as, const char *key,
static char *
format_int(char *t, int64_t i)
{
- int sign;
+ uint64_t ui;
- if (i < 0) {
- sign = -1;
- i = -i;
- } else
- sign = 1;
+ if (i < 0)
+ ui = (i == INT64_MIN) ? (uint64_t)(INT64_MAX) + 1 : (uint64_t)(-i);
+ else
+ ui = i;
do {
- *--t = "0123456789"[i % 10];
- } while (i /= 10);
- if (sign < 0)
+ *--t = "0123456789"[ui % 10];
+ } while (ui /= 10);
+ if (i < 0)
*--t = '-';
return (t);
}
@@ -193,106 +264,6 @@ add_pax_attr_int(struct archive_string *as, const char *key, int64_t value)
add_pax_attr(as, key, format_int(tmp + sizeof(tmp) - 1, value));
}
-static char *
-utf8_encode(const wchar_t *wval)
-{
- int utf8len;
- const wchar_t *wp;
- unsigned long wc;
- char *utf8_value, *p;
-
- utf8len = 0;
- for (wp = wval; *wp != L'\0'; ) {
- wc = *wp++;
-
- if (wc >= 0xd800 && wc <= 0xdbff
- && *wp >= 0xdc00 && *wp <= 0xdfff) {
- /* This is a surrogate pair. Combine into a
- * full Unicode value before encoding into
- * UTF-8. */
- wc = (wc - 0xd800) << 10; /* High 10 bits */
- wc += (*wp++ - 0xdc00); /* Low 10 bits */
- wc += 0x10000; /* Skip BMP */
- }
- if (wc <= 0x7f)
- utf8len++;
- else if (wc <= 0x7ff)
- utf8len += 2;
- else if (wc <= 0xffff)
- utf8len += 3;
- else if (wc <= 0x1fffff)
- utf8len += 4;
- else if (wc <= 0x3ffffff)
- utf8len += 5;
- else if (wc <= 0x7fffffff)
- utf8len += 6;
- /* Ignore larger values; UTF-8 can't encode them. */
- }
-
- utf8_value = (char *)malloc(utf8len + 1);
- if (utf8_value == NULL) {
- __archive_errx(1, "Not enough memory for attributes");
- return (NULL);
- }
-
- for (wp = wval, p = utf8_value; *wp != L'\0'; ) {
- wc = *wp++;
- if (wc >= 0xd800 && wc <= 0xdbff
- && *wp >= 0xdc00 && *wp <= 0xdfff) {
- /* Combine surrogate pair. */
- wc = (wc - 0xd800) << 10;
- wc += *wp++ - 0xdc00 + 0x10000;
- }
- if (wc <= 0x7f) {
- *p++ = (char)wc;
- } else if (wc <= 0x7ff) {
- p[0] = 0xc0 | ((wc >> 6) & 0x1f);
- p[1] = 0x80 | (wc & 0x3f);
- p += 2;
- } else if (wc <= 0xffff) {
- p[0] = 0xe0 | ((wc >> 12) & 0x0f);
- p[1] = 0x80 | ((wc >> 6) & 0x3f);
- p[2] = 0x80 | (wc & 0x3f);
- p += 3;
- } else if (wc <= 0x1fffff) {
- p[0] = 0xf0 | ((wc >> 18) & 0x07);
- p[1] = 0x80 | ((wc >> 12) & 0x3f);
- p[2] = 0x80 | ((wc >> 6) & 0x3f);
- p[3] = 0x80 | (wc & 0x3f);
- p += 4;
- } else if (wc <= 0x3ffffff) {
- p[0] = 0xf8 | ((wc >> 24) & 0x03);
- p[1] = 0x80 | ((wc >> 18) & 0x3f);
- p[2] = 0x80 | ((wc >> 12) & 0x3f);
- p[3] = 0x80 | ((wc >> 6) & 0x3f);
- p[4] = 0x80 | (wc & 0x3f);
- p += 5;
- } else if (wc <= 0x7fffffff) {
- p[0] = 0xfc | ((wc >> 30) & 0x01);
- p[1] = 0x80 | ((wc >> 24) & 0x3f);
- p[1] = 0x80 | ((wc >> 18) & 0x3f);
- p[2] = 0x80 | ((wc >> 12) & 0x3f);
- p[3] = 0x80 | ((wc >> 6) & 0x3f);
- p[4] = 0x80 | (wc & 0x3f);
- p += 6;
- }
- /* Ignore larger values; UTF-8 can't encode them. */
- }
- *p = '\0';
-
- return (utf8_value);
-}
-
-static void
-add_pax_attr_w(struct archive_string *as, const char *key, const wchar_t *wval)
-{
- char *utf8_value = utf8_encode(wval);
- if (utf8_value == NULL)
- return;
- add_pax_attr(as, key, utf8_value);
- free(utf8_value);
-}
-
/*
* Add a key/value attribute to the pax header. This function handles
* the length field and various other syntactic requirements.
@@ -342,8 +313,9 @@ add_pax_attr(struct archive_string *as, const char *key, const char *value)
archive_strappend_char(as, '\n');
}
-static void
-archive_write_pax_header_xattrs(struct pax *pax, struct archive_entry *entry)
+static int
+archive_write_pax_header_xattrs(struct archive_write *a,
+ struct pax *pax, struct archive_entry *entry)
{
struct archive_string s;
int i = archive_entry_xattr_reset(entry);
@@ -353,26 +325,24 @@ archive_write_pax_header_xattrs(struct pax *pax, struct archive_entry *entry)
const void *value;
char *encoded_value;
char *url_encoded_name = NULL, *encoded_name = NULL;
- wchar_t *wcs_name = NULL;
size_t size;
+ int r;
archive_entry_xattr_next(entry, &name, &value, &size);
- /* Name is URL-encoded, then converted to wchar_t,
- * then UTF-8 encoded. */
url_encoded_name = url_encode(name);
if (url_encoded_name != NULL) {
- /* Convert narrow-character to wide-character. */
- size_t wcs_length = strlen(url_encoded_name);
- wcs_name = (wchar_t *)malloc((wcs_length + 1) * sizeof(wchar_t));
- if (wcs_name == NULL)
- __archive_errx(1, "No memory for xattr conversion");
- mbstowcs(wcs_name, url_encoded_name, wcs_length);
- wcs_name[wcs_length] = 0;
+ /* Convert narrow-character to UTF-8. */
+ r = archive_strcpy_in_locale(
+ &(pax->l_url_encoded_name),
+ url_encoded_name, pax->sconv_utf8);
free(url_encoded_name); /* Done with this. */
- }
- if (wcs_name != NULL) {
- encoded_name = utf8_encode(wcs_name);
- free(wcs_name); /* Done with wchar_t name. */
+ if (r == 0)
+ encoded_name = pax->l_url_encoded_name.s;
+ else if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Linkname");
+ return (ARCHIVE_FATAL);
+ }
}
encoded_value = base64_encode((const char *)value, size);
@@ -384,9 +354,99 @@ archive_write_pax_header_xattrs(struct pax *pax, struct archive_entry *entry)
add_pax_attr(&(pax->pax_header), s.s, encoded_value);
archive_string_free(&s);
}
- free(encoded_name);
free(encoded_value);
}
+ return (ARCHIVE_OK);
+}
+
+static int
+get_entry_hardlink(struct archive_write *a, struct archive_entry *entry,
+ const char **name, size_t *length, struct archive_string_conv *sc)
+{
+ int r;
+
+ r = archive_entry_hardlink_l(entry, name, length, sc);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Linkname");
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_WARN);
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+get_entry_pathname(struct archive_write *a, struct archive_entry *entry,
+ const char **name, size_t *length, struct archive_string_conv *sc)
+{
+ int r;
+
+ r = archive_entry_pathname_l(entry, name, length, sc);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathname");
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_WARN);
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+get_entry_uname(struct archive_write *a, struct archive_entry *entry,
+ const char **name, size_t *length, struct archive_string_conv *sc)
+{
+ int r;
+
+ r = archive_entry_uname_l(entry, name, length, sc);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Uname");
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_WARN);
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+get_entry_gname(struct archive_write *a, struct archive_entry *entry,
+ const char **name, size_t *length, struct archive_string_conv *sc)
+{
+ int r;
+
+ r = archive_entry_gname_l(entry, name, length, sc);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Gname");
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_WARN);
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+get_entry_symlink(struct archive_write *a, struct archive_entry *entry,
+ const char **name, size_t *length, struct archive_string_conv *sc)
+{
+ int r;
+
+ r = archive_entry_symlink_l(entry, name, length, sc);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Linkname");
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_WARN);
+ }
+ return (ARCHIVE_OK);
}
/*
@@ -394,6 +454,8 @@ archive_write_pax_header_xattrs(struct pax *pax, struct archive_entry *entry)
* archive_entry so that clients can specify them. Also, consider
* adding generic key/value tags so clients can add arbitrary
* key/value data.
+ *
+ * TODO: Break up this 700-line function!!!! Yowza!
*/
static int
archive_write_pax_header(struct archive_write *a,
@@ -402,27 +464,72 @@ archive_write_pax_header(struct archive_write *a,
struct archive_entry *entry_main;
const char *p;
char *t;
- const wchar_t *wp;
const char *suffix;
int need_extension, r, ret;
+ int sparse_count;
+ uint64_t sparse_total, real_size;
struct pax *pax;
- const char *hdrcharset = NULL;
const char *hardlink;
const char *path = NULL, *linkpath = NULL;
const char *uname = NULL, *gname = NULL;
- const wchar_t *path_w = NULL, *linkpath_w = NULL;
- const wchar_t *uname_w = NULL, *gname_w = NULL;
+ const void *mac_metadata;
+ size_t mac_metadata_size;
+ struct archive_string_conv *sconv;
+ size_t hardlink_length, path_length, linkpath_length;
+ size_t uname_length, gname_length;
char paxbuff[512];
char ustarbuff[512];
char ustar_entry_name[256];
char pax_entry_name[256];
+ char gnu_sparse_name[256];
+ struct archive_string entry_name;
ret = ARCHIVE_OK;
need_extension = 0;
pax = (struct pax *)a->format_data;
- hardlink = archive_entry_hardlink(entry_original);
+ /* Sanity check. */
+ if (archive_entry_pathname(entry_original) == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Can't record entry in tar file without pathname");
+ return (ARCHIVE_FAILED);
+ }
+
+ /*
+ * Choose a header encoding.
+ */
+ if (pax->opt_binary)
+ sconv = NULL;/* Binary mode. */
+ else {
+ /* Header encoding is UTF-8. */
+ if (pax->sconv_utf8 == NULL) {
+ /* Initialize the string conversion object
+ * we must need */
+ pax->sconv_utf8 = archive_string_conversion_to_charset(
+ &(a->archive), "UTF-8", 1);
+ if (pax->sconv_utf8 == NULL)
+ /* Couldn't allocate memory */
+ return (ARCHIVE_FAILED);
+ }
+ sconv = pax->sconv_utf8;
+ }
+
+ r = get_entry_hardlink(a, entry_original, &hardlink,
+ &hardlink_length, sconv);
+ if (r == ARCHIVE_FATAL)
+ return (r);
+ else if (r != ARCHIVE_OK) {
+ r = get_entry_hardlink(a, entry_original, &hardlink,
+ &hardlink_length, NULL);
+ if (r == ARCHIVE_FATAL)
+ return (r);
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate linkname '%s' to %s", hardlink,
+ archive_string_conversion_charset_name(sconv));
+ ret = ARCHIVE_WARN;
+ sconv = NULL;/* The header charset switches to binary mode. */
+ }
/* Make sure this is a type of entry that we can handle here */
if (hardlink == NULL) {
@@ -456,68 +563,217 @@ archive_write_pax_header(struct archive_write *a,
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"tar format cannot archive socket");
- return (ARCHIVE_WARN);
+ return (ARCHIVE_FAILED);
default:
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"tar format cannot archive this (type=0%lo)",
- (unsigned long)archive_entry_filetype(entry_original));
- return (ARCHIVE_WARN);
+ (unsigned long)
+ archive_entry_filetype(entry_original));
+ return (ARCHIVE_FAILED);
+ }
+ }
+
+ /*
+ * If Mac OS metadata blob is here, recurse to write that
+ * as a separate entry. This is really a pretty poor design:
+ * In particular, it doubles the overhead for long filenames.
+ * TODO: Help Apple folks design something better and figure
+ * out how to transition from this legacy format.
+ *
+ * Note that this code is present on every platform; clients
+ * on non-Mac are unlikely to ever provide this data, but
+ * applications that copy entries from one archive to another
+ * should not lose data just because the local filesystem
+ * can't store it.
+ */
+ mac_metadata =
+ archive_entry_mac_metadata(entry_original, &mac_metadata_size);
+ if (mac_metadata != NULL) {
+ const char *oname;
+ char *name, *bname;
+ size_t name_length;
+ struct archive_entry *extra = archive_entry_new2(&a->archive);
+
+ oname = archive_entry_pathname(entry_original);
+ name_length = strlen(oname);
+ name = malloc(name_length + 3);
+ if (name == NULL) {
+ /* XXX error message */
+ return (ARCHIVE_FAILED);
+ }
+ strcpy(name, oname);
+ /* Find last '/'; strip trailing '/' characters */
+ bname = strrchr(name, '/');
+ while (bname != NULL && bname[1] == '\0') {
+ *bname = '\0';
+ bname = strrchr(name, '/');
+ }
+ if (bname == NULL) {
+ memmove(name + 2, name, name_length + 1);
+ memmove(name, "._", 2);
+ } else {
+ bname += 1;
+ memmove(bname + 2, bname, strlen(bname) + 1);
+ memmove(bname, "._", 2);
}
+ archive_entry_copy_pathname(extra, name);
+ free(name);
+
+ archive_entry_set_size(extra, mac_metadata_size);
+ archive_entry_set_filetype(extra, AE_IFREG);
+ archive_entry_set_perm(extra,
+ archive_entry_perm(entry_original));
+ archive_entry_set_mtime(extra,
+ archive_entry_mtime(entry_original),
+ archive_entry_mtime_nsec(entry_original));
+ archive_entry_set_gid(extra,
+ archive_entry_gid(entry_original));
+ archive_entry_set_gname(extra,
+ archive_entry_gname(entry_original));
+ archive_entry_set_uid(extra,
+ archive_entry_uid(entry_original));
+ archive_entry_set_uname(extra,
+ archive_entry_uname(entry_original));
+
+ /* Recurse to write the special copyfile entry. */
+ r = archive_write_pax_header(a, extra);
+ if (r < ARCHIVE_WARN)
+ return (r);
+ if (r < ret)
+ ret = r;
+ r = archive_write_pax_data(a, mac_metadata, mac_metadata_size);
+ if (r < ARCHIVE_WARN)
+ return (r);
+ if (r < ret)
+ ret = r;
+ r = archive_write_pax_finish_entry(a);
+ if (r < ARCHIVE_WARN)
+ return (r);
+ if (r < ret)
+ ret = r;
}
/* Copy entry so we can modify it as needed. */
entry_main = archive_entry_clone(entry_original);
archive_string_empty(&(pax->pax_header)); /* Blank our work area. */
+ archive_string_empty(&(pax->sparse_map));
+ sparse_total = 0;
+ sparse_list_clear(pax);
+
+ if (hardlink == NULL &&
+ archive_entry_filetype(entry_main) == AE_IFREG)
+ sparse_count = archive_entry_sparse_reset(entry_main);
+ else
+ sparse_count = 0;
+ if (sparse_count) {
+ int64_t offset, length, last_offset = 0;
+ /* Get the last entry of sparse block. */
+ while (archive_entry_sparse_next(
+ entry_main, &offset, &length) == ARCHIVE_OK)
+ last_offset = offset + length;
+
+ /* If the last sparse block does not reach the end of file,
+ * We have to add a empty sparse block as the last entry to
+ * manage storing file data. */
+ if (last_offset < archive_entry_size(entry_main))
+ archive_entry_sparse_add_entry(entry_main,
+ archive_entry_size(entry_main), 0);
+ sparse_count = archive_entry_sparse_reset(entry_main);
+ }
/*
* First, check the name fields and see if any of them
* require binary coding. If any of them does, then all of
* them do.
*/
- hdrcharset = NULL;
- path = archive_entry_pathname(entry_main);
- path_w = archive_entry_pathname_w(entry_main);
- if (path != NULL && path_w == NULL) {
+ r = get_entry_pathname(a, entry_main, &path, &path_length, sconv);
+ if (r == ARCHIVE_FATAL)
+ return (r);
+ else if (r != ARCHIVE_OK) {
+ r = get_entry_pathname(a, entry_main, &path,
+ &path_length, NULL);
+ if (r == ARCHIVE_FATAL)
+ return (r);
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate pathname '%s' to UTF-8", path);
+ "Can't translate pathname '%s' to %s", path,
+ archive_string_conversion_charset_name(sconv));
ret = ARCHIVE_WARN;
- hdrcharset = "BINARY";
+ sconv = NULL;/* The header charset switches to binary mode. */
}
- uname = archive_entry_uname(entry_main);
- uname_w = archive_entry_uname_w(entry_main);
- if (uname != NULL && uname_w == NULL) {
+ r = get_entry_uname(a, entry_main, &uname, &uname_length, sconv);
+ if (r == ARCHIVE_FATAL)
+ return (r);
+ else if (r != ARCHIVE_OK) {
+ r = get_entry_uname(a, entry_main, &uname, &uname_length, NULL);
+ if (r == ARCHIVE_FATAL)
+ return (r);
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate uname '%s' to UTF-8", uname);
+ "Can't translate uname '%s' to %s", uname,
+ archive_string_conversion_charset_name(sconv));
ret = ARCHIVE_WARN;
- hdrcharset = "BINARY";
+ sconv = NULL;/* The header charset switches to binary mode. */
}
- gname = archive_entry_gname(entry_main);
- gname_w = archive_entry_gname_w(entry_main);
- if (gname != NULL && gname_w == NULL) {
+ r = get_entry_gname(a, entry_main, &gname, &gname_length, sconv);
+ if (r == ARCHIVE_FATAL)
+ return (r);
+ else if (r != ARCHIVE_OK) {
+ r = get_entry_gname(a, entry_main, &gname, &gname_length, NULL);
+ if (r == ARCHIVE_FATAL)
+ return (r);
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate gname '%s' to UTF-8", gname);
+ "Can't translate gname '%s' to %s", gname,
+ archive_string_conversion_charset_name(sconv));
ret = ARCHIVE_WARN;
- hdrcharset = "BINARY";
+ sconv = NULL;/* The header charset switches to binary mode. */
}
linkpath = hardlink;
- if (linkpath != NULL) {
- linkpath_w = archive_entry_hardlink_w(entry_main);
- } else {
- linkpath = archive_entry_symlink(entry_main);
- if (linkpath != NULL)
- linkpath_w = archive_entry_symlink_w(entry_main);
+ linkpath_length = hardlink_length;
+ if (linkpath == NULL) {
+ r = get_entry_symlink(a, entry_main, &linkpath,
+ &linkpath_length, sconv);
+ if (r == ARCHIVE_FATAL)
+ return (r);
+ else if (r != ARCHIVE_OK) {
+ r = get_entry_symlink(a, entry_main, &linkpath,
+ &linkpath_length, NULL);
+ if (r == ARCHIVE_FATAL)
+ return (r);
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate linkname '%s' to %s", linkpath,
+ archive_string_conversion_charset_name(sconv));
+ ret = ARCHIVE_WARN;
+ sconv = NULL;
+ }
}
- if (linkpath != NULL && linkpath_w == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate linkpath '%s' to UTF-8", linkpath);
- ret = ARCHIVE_WARN;
- hdrcharset = "BINARY";
+
+ /* If any string conversions failed, get all attributes
+ * in binary-mode. */
+ if (sconv == NULL && !pax->opt_binary) {
+ if (hardlink != NULL) {
+ r = get_entry_hardlink(a, entry_main, &hardlink,
+ &hardlink_length, NULL);
+ if (r == ARCHIVE_FATAL)
+ return (r);
+ linkpath = hardlink;
+ linkpath_length = hardlink_length;
+ }
+ r = get_entry_pathname(a, entry_main, &path,
+ &path_length, NULL);
+ if (r == ARCHIVE_FATAL)
+ return (r);
+ r = get_entry_uname(a, entry_main, &uname, &uname_length, NULL);
+ if (r == ARCHIVE_FATAL)
+ return (r);
+ r = get_entry_gname(a, entry_main, &gname, &gname_length, NULL);
+ if (r == ARCHIVE_FATAL)
+ return (r);
}
/* Store the header encoding first, to be nice to readers. */
- if (hdrcharset != NULL)
- add_pax_attr(&(pax->pax_header), "hdrcharset", hdrcharset);
+ if (sconv == NULL)
+ add_pax_attr(&(pax->pax_header), "hdrcharset", "BINARY");
/*
@@ -525,38 +781,25 @@ archive_write_pax_header(struct archive_write *a,
* 'path' to pax extended attrs. (Note that an unconvertible
* name must have non-ASCII characters.)
*/
- if (path == NULL) {
- /* We don't have a narrow version, so we have to store
- * the wide version. */
- add_pax_attr_w(&(pax->pax_header), "path", path_w);
- archive_entry_set_pathname(entry_main, "@WidePath");
- need_extension = 1;
- } else if (has_non_ASCII(path_w)) {
+ if (has_non_ASCII(path)) {
/* We have non-ASCII characters. */
- if (path_w == NULL || hdrcharset != NULL) {
- /* Can't do UTF-8, so store it raw. */
- add_pax_attr(&(pax->pax_header), "path", path);
- } else {
- /* Store UTF-8 */
- add_pax_attr_w(&(pax->pax_header),
- "path", path_w);
- }
+ add_pax_attr(&(pax->pax_header), "path", path);
archive_entry_set_pathname(entry_main,
build_ustar_entry_name(ustar_entry_name,
- path, strlen(path), NULL));
+ path, path_length, NULL));
need_extension = 1;
} else {
/* We have an all-ASCII path; we'd like to just store
* it in the ustar header if it will fit. Yes, this
* duplicates some of the logic in
- * write_set_format_ustar.c
+ * archive_write_set_format_ustar.c
*/
- if (strlen(path) <= 100) {
+ if (path_length <= 100) {
/* Fits in the old 100-char tar name field. */
} else {
/* Find largest suffix that will fit. */
/* Note: strlen() > 100, so strlen() - 100 - 1 >= 0 */
- suffix = strchr(path + strlen(path) - 100 - 1, '/');
+ suffix = strchr(path + path_length - 100 - 1, '/');
/* Don't attempt an empty prefix. */
if (suffix == path)
suffix = strchr(suffix + 1, '/');
@@ -571,18 +814,10 @@ archive_write_pax_header(struct archive_write *a,
|| suffix[1] == '\0' /* empty suffix */
|| suffix - path > 155) /* Prefix > 155 chars */
{
- if (path_w == NULL || hdrcharset != NULL) {
- /* Can't do UTF-8, so store it raw. */
- add_pax_attr(&(pax->pax_header),
- "path", path);
- } else {
- /* Store UTF-8 */
- add_pax_attr_w(&(pax->pax_header),
- "path", path_w);
- }
+ add_pax_attr(&(pax->pax_header), "path", path);
archive_entry_set_pathname(entry_main,
build_ustar_entry_name(ustar_entry_name,
- path, strlen(path), NULL));
+ path, path_length, NULL));
need_extension = 1;
}
}
@@ -591,21 +826,9 @@ archive_write_pax_header(struct archive_write *a,
if (linkpath != NULL) {
/* If link name is too long or has non-ASCII characters, add
* 'linkpath' to pax extended attrs. */
- if (strlen(linkpath) > 100 || linkpath_w == NULL
- || linkpath_w == NULL || has_non_ASCII(linkpath_w)) {
- if (linkpath_w == NULL || hdrcharset != NULL)
- /* If the linkpath is not convertible
- * to wide, or we're encoding in
- * binary anyway, store it raw. */
- add_pax_attr(&(pax->pax_header),
- "linkpath", linkpath);
- else
- /* If the link is long or has a
- * non-ASCII character, store it as a
- * pax extended attribute. */
- add_pax_attr_w(&(pax->pax_header),
- "linkpath", linkpath_w);
- if (strlen(linkpath) > 100) {
+ if (linkpath_length > 100 || has_non_ASCII(linkpath)) {
+ add_pax_attr(&(pax->pax_header), "linkpath", linkpath);
+ if (linkpath_length > 100) {
if (hardlink != NULL)
archive_entry_set_hardlink(entry_main,
"././@LongHardLink");
@@ -616,6 +839,10 @@ archive_write_pax_header(struct archive_write *a,
need_extension = 1;
}
}
+ /* Save a pathname since it will be renamed if `entry_main` has
+ * sparse blocks. */
+ archive_string_init(&entry_name);
+ archive_strcpy(&entry_name, archive_entry_pathname(entry_main));
/* If file size is too large, add 'size' to pax extended attrs. */
if (archive_entry_size(entry_main) >= (((int64_t)1) << 33)) {
@@ -634,17 +861,8 @@ archive_write_pax_header(struct archive_write *a,
/* If group name is too large or has non-ASCII characters, add
* 'gname' to pax extended attrs. */
if (gname != NULL) {
- if (strlen(gname) > 31
- || gname_w == NULL
- || has_non_ASCII(gname_w))
- {
- if (gname_w == NULL || hdrcharset != NULL) {
- add_pax_attr(&(pax->pax_header),
- "gname", gname);
- } else {
- add_pax_attr_w(&(pax->pax_header),
- "gname", gname_w);
- }
+ if (gname_length > 31 || has_non_ASCII(gname)) {
+ add_pax_attr(&(pax->pax_header), "gname", gname);
need_extension = 1;
}
}
@@ -658,17 +876,8 @@ archive_write_pax_header(struct archive_write *a,
/* Add 'uname' to pax extended attrs if necessary. */
if (uname != NULL) {
- if (strlen(uname) > 31
- || uname_w == NULL
- || has_non_ASCII(uname_w))
- {
- if (uname_w == NULL || hdrcharset != NULL) {
- add_pax_attr(&(pax->pax_header),
- "uname", uname);
- } else {
- add_pax_attr_w(&(pax->pax_header),
- "uname", uname_w);
- }
+ if (uname_length > 31 || has_non_ASCII(uname)) {
+ add_pax_attr(&(pax->pax_header), "uname", uname);
need_extension = 1;
}
}
@@ -690,7 +899,7 @@ archive_write_pax_header(struct archive_write *a,
* If rdevmajor is too large, add 'SCHILY.devmajor' to
* extended attributes.
*/
- dev_t rdevmajor, rdevminor;
+ int rdevmajor, rdevminor;
rdevmajor = archive_entry_rdevmajor(entry_main);
rdevminor = archive_entry_rdevminor(entry_main);
if (rdevmajor >= (1 << 18)) {
@@ -756,6 +965,10 @@ archive_write_pax_header(struct archive_write *a,
if (!need_extension && archive_entry_xattr_count(entry_original) > 0)
need_extension = 1;
+ /* If there are sparse info, we need an extension */
+ if (!need_extension && sparse_count > 0)
+ need_extension = 1;
+
/*
* The following items are handled differently in "pax
* restricted" format. In particular, in "pax restricted"
@@ -800,31 +1013,98 @@ archive_write_pax_header(struct archive_write *a,
add_pax_attr(&(pax->pax_header), "SCHILY.fflags", p);
/* I use star-compatible ACL attributes. */
- wp = archive_entry_acl_text_w(entry_original,
+ r = archive_entry_acl_text_l(entry_original,
ARCHIVE_ENTRY_ACL_TYPE_ACCESS |
- ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID);
- if (wp != NULL && *wp != L'\0')
- add_pax_attr_w(&(pax->pax_header),
- "SCHILY.acl.access", wp);
- wp = archive_entry_acl_text_w(entry_original,
+ ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID,
+ &p, NULL, pax->sconv_utf8);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for "
+ "ACL.access");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate ACL.access to UTF-8");
+ ret = ARCHIVE_WARN;
+ } else if (p != NULL && *p != '\0') {
+ add_pax_attr(&(pax->pax_header),
+ "SCHILY.acl.access", p);
+ }
+ r = archive_entry_acl_text_l(entry_original,
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT |
- ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID);
- if (wp != NULL && *wp != L'\0')
- add_pax_attr_w(&(pax->pax_header),
- "SCHILY.acl.default", wp);
-
- /* Include star-compatible metadata info. */
- /* Note: "SCHILY.dev{major,minor}" are NOT the
- * major/minor portions of "SCHILY.dev". */
- add_pax_attr_int(&(pax->pax_header), "SCHILY.dev",
- archive_entry_dev(entry_main));
- add_pax_attr_int(&(pax->pax_header), "SCHILY.ino",
- archive_entry_ino64(entry_main));
- add_pax_attr_int(&(pax->pax_header), "SCHILY.nlink",
- archive_entry_nlink(entry_main));
+ ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID,
+ &p, NULL, pax->sconv_utf8);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for "
+ "ACL.default");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate ACL.default to UTF-8");
+ ret = ARCHIVE_WARN;
+ } else if (p != NULL && *p != '\0') {
+ add_pax_attr(&(pax->pax_header),
+ "SCHILY.acl.default", p);
+ }
+
+ /* We use GNU-tar-compatible sparse attributes. */
+ if (sparse_count > 0) {
+ int64_t soffset, slength;
+
+ add_pax_attr_int(&(pax->pax_header),
+ "GNU.sparse.major", 1);
+ add_pax_attr_int(&(pax->pax_header),
+ "GNU.sparse.minor", 0);
+ add_pax_attr(&(pax->pax_header),
+ "GNU.sparse.name", entry_name.s);
+ add_pax_attr_int(&(pax->pax_header),
+ "GNU.sparse.realsize",
+ archive_entry_size(entry_main));
+
+ /* Rename the file name which will be used for
+ * ustar header to a special name, which GNU
+ * PAX Format 1.0 requires */
+ archive_entry_set_pathname(entry_main,
+ build_gnu_sparse_name(gnu_sparse_name,
+ entry_name.s));
+
+ /*
+ * - Make a sparse map, which will precede a file data.
+ * - Get the total size of available data of sparse.
+ */
+ archive_string_sprintf(&(pax->sparse_map), "%d\n",
+ sparse_count);
+ while (archive_entry_sparse_next(entry_main,
+ &soffset, &slength) == ARCHIVE_OK) {
+ archive_string_sprintf(&(pax->sparse_map),
+ "%jd\n%jd\n",
+ (intmax_t)soffset,
+ (intmax_t)slength);
+ sparse_total += slength;
+ if (sparse_list_add(pax, soffset, slength)
+ != ARCHIVE_OK) {
+ archive_set_error(&a->archive,
+ ENOMEM,
+ "Can't allocate memory");
+ archive_entry_free(entry_main);
+ archive_string_free(&entry_name);
+ return (ARCHIVE_FATAL);
+ }
+ }
+ }
/* Store extended attributes */
- archive_write_pax_header_xattrs(pax, entry_original);
+ if (archive_write_pax_header_xattrs(a, pax, entry_original)
+ == ARCHIVE_FATAL) {
+ archive_entry_free(entry_main);
+ archive_string_free(&entry_name);
+ return (ARCHIVE_FATAL);
+ }
}
/* Only regular files have data. */
@@ -852,6 +1132,20 @@ archive_write_pax_header(struct archive_write *a,
if (hardlink != NULL)
archive_entry_set_size(entry_main, 0);
+ /* Save a real file size. */
+ real_size = archive_entry_size(entry_main);
+ /*
+ * Overwrite a file size by the total size of sparse blocks and
+ * the size of sparse map info. That file size is the length of
+ * the data, which we will exactly store into an archive file.
+ */
+ if (archive_strlen(&(pax->sparse_map))) {
+ size_t mapsize = archive_strlen(&(pax->sparse_map));
+ pax->sparse_map_padding = 0x1ff & (-(ssize_t)mapsize);
+ archive_entry_set_size(entry_main,
+ mapsize + pax->sparse_map_padding + sparse_total);
+ }
+
/* Format 'ustar' header for main entry.
*
* The trouble with file size: If the reader can't understand
@@ -878,30 +1172,31 @@ archive_write_pax_header(struct archive_write *a,
* The non-strict formatter uses similar logic for other
* numeric fields, though they're less critical.
*/
- __archive_write_format_header_ustar(a, ustarbuff, entry_main, -1, 0);
+ if (__archive_write_format_header_ustar(a, ustarbuff, entry_main, -1, 0,
+ NULL) == ARCHIVE_FATAL)
+ return (ARCHIVE_FATAL);
/* If we built any extended attributes, write that entry first. */
if (archive_strlen(&(pax->pax_header)) > 0) {
struct archive_entry *pax_attr_entry;
time_t s;
- uid_t uid;
- gid_t gid;
- mode_t mode;
+ int64_t uid, gid;
+ int mode;
- pax_attr_entry = archive_entry_new();
- p = archive_entry_pathname(entry_main);
+ pax_attr_entry = archive_entry_new2(&a->archive);
+ p = entry_name.s;
archive_entry_set_pathname(pax_attr_entry,
build_pax_attribute_name(pax_entry_name, p));
archive_entry_set_size(pax_attr_entry,
archive_strlen(&(pax->pax_header)));
/* Copy uid/gid (but clip to ustar limits). */
uid = archive_entry_uid(entry_main);
- if ((unsigned int)uid >= 1 << 18)
- uid = (uid_t)(1 << 18) - 1;
+ if (uid >= 1 << 18)
+ uid = (1 << 18) - 1;
archive_entry_set_uid(pax_attr_entry, uid);
gid = archive_entry_gid(entry_main);
- if ((unsigned int)gid >= 1 << 18)
- gid = (gid_t)(1 << 18) - 1;
+ if (gid >= 1 << 18)
+ gid = (1 << 18) - 1;
archive_entry_set_gid(pax_attr_entry, gid);
/* Copy mode over (but not setuid/setgid bits) */
mode = archive_entry_mode(entry_main);
@@ -935,36 +1230,38 @@ archive_write_pax_header(struct archive_write *a,
archive_entry_set_ctime(pax_attr_entry, 0, 0);
r = __archive_write_format_header_ustar(a, paxbuff,
- pax_attr_entry, 'x', 1);
+ pax_attr_entry, 'x', 1, NULL);
archive_entry_free(pax_attr_entry);
/* Note that the 'x' header shouldn't ever fail to format */
- if (r != 0) {
- const char *msg = "archive_write_pax_header: "
- "'x' header failed?! This can't happen.\n";
- size_t u = write(2, msg, strlen(msg));
- (void)u; /* UNUSED */
- exit(1);
- }
- r = (a->compressor.write)(a, paxbuff, 512);
+ if (r < ARCHIVE_WARN) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "archive_write_pax_header: "
+ "'x' header failed?! This can't happen.\n");
+ return (ARCHIVE_FATAL);
+ } else if (r < ret)
+ ret = r;
+ r = __archive_write_output(a, paxbuff, 512);
if (r != ARCHIVE_OK) {
+ sparse_list_clear(pax);
pax->entry_bytes_remaining = 0;
pax->entry_padding = 0;
return (ARCHIVE_FATAL);
}
pax->entry_bytes_remaining = archive_strlen(&(pax->pax_header));
- pax->entry_padding = 0x1ff & (-(int64_t)pax->entry_bytes_remaining);
+ pax->entry_padding =
+ 0x1ff & (-(int64_t)pax->entry_bytes_remaining);
- r = (a->compressor.write)(a, pax->pax_header.s,
+ r = __archive_write_output(a, pax->pax_header.s,
archive_strlen(&(pax->pax_header)));
if (r != ARCHIVE_OK) {
/* If a write fails, we're pretty much toast. */
return (ARCHIVE_FATAL);
}
/* Pad out the end of the entry. */
- r = write_nulls(a, pax->entry_padding);
+ r = __archive_write_nulls(a, pax->entry_padding);
if (r != ARCHIVE_OK) {
/* If a write fails, we're pretty much toast. */
return (ARCHIVE_FATAL);
@@ -973,7 +1270,7 @@ archive_write_pax_header(struct archive_write *a,
}
/* Write the header for main entry. */
- r = (a->compressor.write)(a, ustarbuff, 512);
+ r = __archive_write_output(a, ustarbuff, 512);
if (r != ARCHIVE_OK)
return (r);
@@ -982,10 +1279,16 @@ archive_write_pax_header(struct archive_write *a,
* they can avoid unnecessarily writing a body for something
* that we're just going to ignore.
*/
- archive_entry_set_size(entry_original, archive_entry_size(entry_main));
- pax->entry_bytes_remaining = archive_entry_size(entry_main);
- pax->entry_padding = 0x1ff & (-(int64_t)pax->entry_bytes_remaining);
+ archive_entry_set_size(entry_original, real_size);
+ if (pax->sparse_list == NULL && real_size > 0) {
+ /* This is not a sparse file but we handle its data as
+ * a sparse block. */
+ sparse_list_add(pax, 0, real_size);
+ sparse_total = real_size;
+ }
+ pax->entry_padding = 0x1ff & (-(int64_t)sparse_total);
archive_entry_free(entry_main);
+ archive_string_free(&entry_name);
return (ret);
}
@@ -1136,7 +1439,7 @@ build_ustar_entry_name(char *dest, const char *src, size_t src_length,
*
* Joerg Schilling has argued that this is unnecessary because, in
* practice, if the pax extended attributes get extracted as regular
- * files, noone is going to bother reading those attributes to
+ * files, no one is going to bother reading those attributes to
* manually restore them. Based on this, 'star' uses
* /tmp/PaxHeader/'basename' as the ustar header name. This is a
* tempting argument, in part because it's simpler than the SUSv3
@@ -1200,27 +1503,71 @@ build_pax_attribute_name(char *dest, const char *src)
/* If the platform can't fetch the pid, don't include it. */
strcpy(buff, "PaxHeader");
#endif
- /* General case: build a ustar-compatible name adding "/PaxHeader/". */
+ /* General case: build a ustar-compatible name adding
+ * "/PaxHeader/". */
build_ustar_entry_name(dest, src, p - src, buff);
return (dest);
}
-/* Write two null blocks for the end of archive */
-static int
-archive_write_pax_finish(struct archive_write *a)
+/*
+ * GNU PAX Format 1.0 requires the special name, which pattern is:
+ * <dir>/GNUSparseFile.<pid>/<original file name>
+ *
+ * This function is used for only Sparse file, a file type of which
+ * is regular file.
+ */
+static char *
+build_gnu_sparse_name(char *dest, const char *src)
{
- int r;
+ char buff[64];
+ const char *p;
- if (a->compressor.write == NULL)
- return (ARCHIVE_OK);
+ /* Handle the null filename case. */
+ if (src == NULL || *src == '\0') {
+ strcpy(dest, "GNUSparseFile/blank");
+ return (dest);
+ }
- r = write_nulls(a, 512 * 2);
- return (r);
+ /* Prune final '/' and other unwanted final elements. */
+ p = src + strlen(src);
+ for (;;) {
+ /* Ends in "/", remove the '/' */
+ if (p > src && p[-1] == '/') {
+ --p;
+ continue;
+ }
+ /* Ends in "/.", remove the '.' */
+ if (p > src + 1 && p[-1] == '.'
+ && p[-2] == '/') {
+ --p;
+ continue;
+ }
+ break;
+ }
+
+#if HAVE_GETPID && 0 /* Disable this as pax attribute name. */
+ sprintf(buff, "GNUSparseFile.%d", getpid());
+#else
+ /* If the platform can't fetch the pid, don't include it. */
+ strcpy(buff, "GNUSparseFile");
+#endif
+ /* General case: build a ustar-compatible name adding
+ * "/GNUSparseFile/". */
+ build_ustar_entry_name(dest, src, p - src, buff);
+
+ return (dest);
}
+/* Write two null blocks for the end of archive */
static int
-archive_write_pax_destroy(struct archive_write *a)
+archive_write_pax_close(struct archive_write *a)
+{
+ return (__archive_write_nulls(a, 512 * 2));
+}
+
+static int
+archive_write_pax_free(struct archive_write *a)
{
struct pax *pax;
@@ -1229,6 +1576,9 @@ archive_write_pax_destroy(struct archive_write *a)
return (ARCHIVE_OK);
archive_string_free(&pax->pax_header);
+ archive_string_free(&pax->sparse_map);
+ archive_string_free(&pax->l_url_encoded_name);
+ sparse_list_clear(pax);
free(pax);
a->format_data = NULL;
return (ARCHIVE_OK);
@@ -1238,56 +1588,97 @@ static int
archive_write_pax_finish_entry(struct archive_write *a)
{
struct pax *pax;
+ uint64_t remaining;
int ret;
pax = (struct pax *)a->format_data;
- ret = write_nulls(a, pax->entry_bytes_remaining + pax->entry_padding);
+ remaining = pax->entry_bytes_remaining;
+ if (remaining == 0) {
+ while (pax->sparse_list) {
+ struct sparse_block *sb;
+ if (!pax->sparse_list->is_hole)
+ remaining += pax->sparse_list->remaining;
+ sb = pax->sparse_list->next;
+ free(pax->sparse_list);
+ pax->sparse_list = sb;
+ }
+ }
+ ret = __archive_write_nulls(a, remaining + pax->entry_padding);
pax->entry_bytes_remaining = pax->entry_padding = 0;
return (ret);
}
-static int
-write_nulls(struct archive_write *a, size_t padding)
+static ssize_t
+archive_write_pax_data(struct archive_write *a, const void *buff, size_t s)
{
+ struct pax *pax;
+ size_t ws;
+ size_t total;
int ret;
- size_t to_write;
- while (padding > 0) {
- to_write = padding < a->null_length ? padding : a->null_length;
- ret = (a->compressor.write)(a, a->nulls, to_write);
+ pax = (struct pax *)a->format_data;
+
+ /*
+ * According to GNU PAX format 1.0, write a sparse map
+ * before the body.
+ */
+ if (archive_strlen(&(pax->sparse_map))) {
+ ret = __archive_write_output(a, pax->sparse_map.s,
+ archive_strlen(&(pax->sparse_map)));
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ ret = __archive_write_nulls(a, pax->sparse_map_padding);
if (ret != ARCHIVE_OK)
return (ret);
- padding -= to_write;
+ archive_string_empty(&(pax->sparse_map));
}
- return (ARCHIVE_OK);
-}
-static ssize_t
-archive_write_pax_data(struct archive_write *a, const void *buff, size_t s)
-{
- struct pax *pax;
- int ret;
+ total = 0;
+ while (total < s) {
+ const unsigned char *p;
- pax = (struct pax *)a->format_data;
- if (s > pax->entry_bytes_remaining)
- s = pax->entry_bytes_remaining;
+ while (pax->sparse_list != NULL &&
+ pax->sparse_list->remaining == 0) {
+ struct sparse_block *sb = pax->sparse_list->next;
+ free(pax->sparse_list);
+ pax->sparse_list = sb;
+ }
- ret = (a->compressor.write)(a, buff, s);
- pax->entry_bytes_remaining -= s;
- if (ret == ARCHIVE_OK)
- return (s);
- else
- return (ret);
+ if (pax->sparse_list == NULL)
+ return (total);
+
+ p = ((const unsigned char *)buff) + total;
+ ws = s - total;
+ if (ws > pax->sparse_list->remaining)
+ ws = pax->sparse_list->remaining;
+
+ if (pax->sparse_list->is_hole) {
+ /* Current block is hole thus we do not write
+ * the body. */
+ pax->sparse_list->remaining -= ws;
+ total += ws;
+ continue;
+ }
+
+ ret = __archive_write_output(a, p, ws);
+ pax->sparse_list->remaining -= ws;
+ total += ws;
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ }
+ return (total);
}
static int
-has_non_ASCII(const wchar_t *wp)
+has_non_ASCII(const char *_p)
{
- if (wp == NULL)
+ const unsigned char *p = (const unsigned char *)_p;
+
+ if (p == NULL)
return (1);
- while (*wp != L'\0' && *wp < 128)
- wp++;
- return (*wp != L'\0');
+ while (*p != '\0' && *p < 128)
+ p++;
+ return (*p != '\0');
}
/*
@@ -1384,3 +1775,60 @@ base64_encode(const char *s, size_t len)
*d = '\0';
return (out);
}
+
+static void
+sparse_list_clear(struct pax *pax)
+{
+ while (pax->sparse_list != NULL) {
+ struct sparse_block *sb = pax->sparse_list;
+ pax->sparse_list = sb->next;
+ free(sb);
+ }
+ pax->sparse_tail = NULL;
+}
+
+static int
+_sparse_list_add_block(struct pax *pax, int64_t offset, int64_t length,
+ int is_hole)
+{
+ struct sparse_block *sb;
+
+ sb = (struct sparse_block *)malloc(sizeof(*sb));
+ if (sb == NULL)
+ return (ARCHIVE_FATAL);
+ sb->next = NULL;
+ sb->is_hole = is_hole;
+ sb->offset = offset;
+ sb->remaining = length;
+ if (pax->sparse_list == NULL)
+ pax->sparse_list = pax->sparse_tail = sb;
+ else {
+ pax->sparse_tail->next = sb;
+ pax->sparse_tail = sb;
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+sparse_list_add(struct pax *pax, int64_t offset, int64_t length)
+{
+ int64_t last_offset;
+ int r;
+
+ if (pax->sparse_tail == NULL)
+ last_offset = 0;
+ else {
+ last_offset = pax->sparse_tail->offset +
+ pax->sparse_tail->remaining;
+ }
+ if (last_offset < offset) {
+ /* Add a hole block. */
+ r = _sparse_list_add_block(pax, last_offset,
+ offset - last_offset, 1);
+ if (r != ARCHIVE_OK)
+ return (r);
+ }
+ /* Add data block. */
+ return (_sparse_list_add_block(pax, offset, length, 0));
+}
+
diff --git a/libarchive/archive_write_set_format_shar.c b/libarchive/archive_write_set_format_shar.c
index 235e4c187991..9ec15f915c9d 100644
--- a/libarchive/archive_write_set_format_shar.c
+++ b/libarchive/archive_write_set_format_shar.c
@@ -59,8 +59,8 @@ struct shar {
struct archive_string quoted_name;
};
-static int archive_write_shar_finish(struct archive_write *);
-static int archive_write_shar_destroy(struct archive_write *);
+static int archive_write_shar_close(struct archive_write *);
+static int archive_write_shar_free(struct archive_write *);
static int archive_write_shar_header(struct archive_write *,
struct archive_entry *);
static ssize_t archive_write_shar_data_sed(struct archive_write *,
@@ -106,9 +106,12 @@ archive_write_set_format_shar(struct archive *_a)
struct archive_write *a = (struct archive_write *)_a;
struct shar *shar;
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_shar");
+
/* If someone else was already registered, unregister them. */
- if (a->format_destroy != NULL)
- (a->format_destroy)(a);
+ if (a->format_free != NULL)
+ (a->format_free)(a);
shar = (struct shar *)malloc(sizeof(*shar));
if (shar == NULL) {
@@ -119,12 +122,10 @@ archive_write_set_format_shar(struct archive *_a)
archive_string_init(&shar->work);
archive_string_init(&shar->quoted_name);
a->format_data = shar;
-
- a->pad_uncompressed = 0;
a->format_name = "shar";
a->format_write_header = archive_write_shar_header;
- a->format_finish = archive_write_shar_finish;
- a->format_destroy = archive_write_shar_destroy;
+ a->format_close = archive_write_shar_close;
+ a->format_free = archive_write_shar_free;
a->format_write_data = archive_write_shar_data_sed;
a->format_finish_entry = archive_write_shar_finish_entry;
a->archive.archive_format = ARCHIVE_FORMAT_SHAR_BASE;
@@ -266,12 +267,12 @@ archive_write_shar_header(struct archive_write *a, struct archive_entry *entry)
shar->quoted_name.s, shar->quoted_name.s);
} else {
if (shar->dump) {
+ unsigned int mode = archive_entry_mode(entry) & 0777;
archive_string_sprintf(&shar->work,
"uudecode -p > %s << 'SHAR_END'\n",
shar->quoted_name.s);
archive_string_sprintf(&shar->work,
- "begin %o ",
- archive_entry_mode(entry) & 0777);
+ "begin %o ", mode);
shar_quote(&shar->work, name, 0);
archive_strcat(&shar->work, "\n");
} else {
@@ -308,15 +309,15 @@ archive_write_shar_header(struct archive_write *a, struct archive_entry *entry)
break;
case AE_IFCHR:
archive_string_sprintf(&shar->work,
- "mknod %s c %d %d\n", shar->quoted_name.s,
- archive_entry_rdevmajor(entry),
- archive_entry_rdevminor(entry));
+ "mknod %s c %ju %ju\n", shar->quoted_name.s,
+ (uintmax_t)archive_entry_rdevmajor(entry),
+ (uintmax_t)archive_entry_rdevminor(entry));
break;
case AE_IFBLK:
archive_string_sprintf(&shar->work,
- "mknod %s b %d %d\n", shar->quoted_name.s,
- archive_entry_rdevmajor(entry),
- archive_entry_rdevminor(entry));
+ "mknod %s b %ju %ju\n", shar->quoted_name.s,
+ (uintmax_t)archive_entry_rdevmajor(entry),
+ (uintmax_t)archive_entry_rdevminor(entry));
break;
default:
return (ARCHIVE_WARN);
@@ -349,11 +350,13 @@ archive_write_shar_data_sed(struct archive_write *a, const void *buff, size_t n)
* twice before entering the loop, so make sure three additional
* bytes can be written.
*/
- if (archive_string_ensure(&shar->work, ensured + 3) == NULL)
- __archive_errx(1, "Out of memory");
+ if (archive_string_ensure(&shar->work, ensured + 3) == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
if (shar->work.length > ensured) {
- ret = (*a->compressor.write)(a, shar->work.s,
+ ret = __archive_write_output(a, shar->work.s,
shar->work.length);
if (ret != ARCHIVE_OK)
return (ARCHIVE_FATAL);
@@ -377,7 +380,7 @@ archive_write_shar_data_sed(struct archive_write *a, const void *buff, size_t n)
if (buf >= buf_end) {
shar->work.length = buf - shar->work.s;
- ret = (*a->compressor.write)(a, shar->work.s,
+ ret = __archive_write_output(a, shar->work.s,
shar->work.length);
if (ret != ARCHIVE_OK)
return (ARCHIVE_FATAL);
@@ -406,16 +409,18 @@ uuencode_group(const char _in[3], char out[4])
out[3] = UUENC( 0x3f & t );
}
-static void
-uuencode_line(struct shar *shar, const char *inbuf, size_t len)
+static int
+_uuencode_line(struct archive_write *a, struct shar *shar, const char *inbuf, size_t len)
{
- char tmp_buf[3], *buf;
+ char *buf;
size_t alloc_len;
/* len <= 45 -> expanded to 60 + len byte + new line */
alloc_len = shar->work.length + 62;
- if (archive_string_ensure(&shar->work, alloc_len) == NULL)
- __archive_errx(1, "Out of memory");
+ if (archive_string_ensure(&shar->work, alloc_len) == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
buf = shar->work.s + shar->work.length;
*buf++ = UUENC(len);
@@ -426,21 +431,33 @@ uuencode_line(struct shar *shar, const char *inbuf, size_t len)
buf += 4;
}
if (len != 0) {
+ char tmp_buf[3];
tmp_buf[0] = inbuf[0];
if (len == 1)
tmp_buf[1] = '\0';
else
tmp_buf[1] = inbuf[1];
tmp_buf[2] = '\0';
- uuencode_group(inbuf, buf);
+ uuencode_group(tmp_buf, buf);
buf += 4;
}
*buf++ = '\n';
- if ((buf - shar->work.s) > (ptrdiff_t)(shar->work.length + 62))
- __archive_errx(1, "Buffer overflow");
+ if ((buf - shar->work.s) > (ptrdiff_t)(shar->work.length + 62)) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC, "Buffer overflow");
+ return (ARCHIVE_FATAL);
+ }
shar->work.length = buf - shar->work.s;
+ return (ARCHIVE_OK);
}
+#define uuencode_line(__a, __shar, __inbuf, __len) \
+ do { \
+ int r = _uuencode_line(__a, __shar, __inbuf, __len); \
+ if (r != ARCHIVE_OK) \
+ return (ARCHIVE_FATAL); \
+ } while (0)
+
static ssize_t
archive_write_shar_data_uuencode(struct archive_write *a, const void *buff,
size_t length)
@@ -464,7 +481,7 @@ archive_write_shar_data_uuencode(struct archive_write *a, const void *buff,
shar->outpos += n;
return length;
}
- uuencode_line(shar, shar->outbuff, 45);
+ uuencode_line(a, shar, shar->outbuff, 45);
src += n;
n = length - n;
} else {
@@ -472,13 +489,13 @@ archive_write_shar_data_uuencode(struct archive_write *a, const void *buff,
}
while (n >= 45) {
- uuencode_line(shar, src, 45);
+ uuencode_line(a, shar, src, 45);
src += 45;
n -= 45;
if (shar->work.length < 65536)
continue;
- ret = (*a->compressor.write)(a, shar->work.s,
+ ret = __archive_write_output(a, shar->work.s,
shar->work.length);
if (ret != ARCHIVE_OK)
return (ARCHIVE_FATAL);
@@ -506,7 +523,7 @@ archive_write_shar_finish_entry(struct archive_write *a)
/* Finish uuencoded data. */
if (shar->has_data) {
if (shar->outpos > 0)
- uuencode_line(shar, shar->outbuff,
+ uuencode_line(a, shar, shar->outbuff,
shar->outpos);
archive_strcat(&shar->work, "`\nend\n");
archive_strcat(&shar->work, "SHAR_END\n");
@@ -517,7 +534,7 @@ archive_write_shar_finish_entry(struct archive_write *a)
* directories; defer that to end of script.
*/
archive_string_sprintf(&shar->work, "chmod %o ",
- archive_entry_mode(shar->entry) & 07777);
+ (unsigned int)(archive_entry_mode(shar->entry) & 07777));
shar_quote(&shar->work, archive_entry_pathname(shar->entry), 1);
archive_strcat(&shar->work, "\n");
@@ -560,7 +577,7 @@ archive_write_shar_finish_entry(struct archive_write *a)
if (shar->work.length < 65536)
return (ARCHIVE_OK);
- ret = (*a->compressor.write)(a, shar->work.s, shar->work.length);
+ ret = __archive_write_output(a, shar->work.s, shar->work.length);
if (ret != ARCHIVE_OK)
return (ARCHIVE_FATAL);
archive_string_empty(&shar->work);
@@ -569,7 +586,7 @@ archive_write_shar_finish_entry(struct archive_write *a)
}
static int
-archive_write_shar_finish(struct archive_write *a)
+archive_write_shar_close(struct archive_write *a)
{
struct shar *shar;
int ret;
@@ -592,7 +609,7 @@ archive_write_shar_finish(struct archive_write *a)
archive_strcat(&shar->work, "exit\n");
- ret = (*a->compressor.write)(a, shar->work.s, shar->work.length);
+ ret = __archive_write_output(a, shar->work.s, shar->work.length);
if (ret != ARCHIVE_OK)
return (ARCHIVE_FATAL);
@@ -607,7 +624,7 @@ archive_write_shar_finish(struct archive_write *a)
}
static int
-archive_write_shar_destroy(struct archive_write *a)
+archive_write_shar_free(struct archive_write *a)
{
struct shar *shar;
diff --git a/libarchive/archive_write_set_format_ustar.c b/libarchive/archive_write_set_format_ustar.c
index 9be4986c885e..4b96ac23c06f 100644
--- a/libarchive/archive_write_set_format_ustar.c
+++ b/libarchive/archive_write_set_format_ustar.c
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2011 Michihiro NAKAJIMA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -40,12 +41,17 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_ustar.c 191579
#include "archive.h"
#include "archive_entry.h"
+#include "archive_entry_locale.h"
#include "archive_private.h"
#include "archive_write_private.h"
struct ustar {
uint64_t entry_bytes_remaining;
uint64_t entry_padding;
+
+ struct archive_string_conv *opt_sconv;
+ struct archive_string_conv *sconv_default;
+ int init_default_conversion;
};
/*
@@ -143,15 +149,16 @@ static const char template_header[] = {
static ssize_t archive_write_ustar_data(struct archive_write *a, const void *buff,
size_t s);
-static int archive_write_ustar_destroy(struct archive_write *);
-static int archive_write_ustar_finish(struct archive_write *);
+static int archive_write_ustar_free(struct archive_write *);
+static int archive_write_ustar_close(struct archive_write *);
static int archive_write_ustar_finish_entry(struct archive_write *);
static int archive_write_ustar_header(struct archive_write *,
struct archive_entry *entry);
+static int archive_write_ustar_options(struct archive_write *,
+ const char *, const char *);
static int format_256(int64_t, char *, int);
static int format_number(int64_t, char *, int size, int max, int strict);
static int format_octal(int64_t, char *, int);
-static int write_nulls(struct archive_write *a, size_t);
/*
* Set output format to 'ustar' format.
@@ -162,30 +169,35 @@ archive_write_set_format_ustar(struct archive *_a)
struct archive_write *a = (struct archive_write *)_a;
struct ustar *ustar;
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_ustar");
+
/* If someone else was already registered, unregister them. */
- if (a->format_destroy != NULL)
- (a->format_destroy)(a);
+ if (a->format_free != NULL)
+ (a->format_free)(a);
/* Basic internal sanity test. */
if (sizeof(template_header) != 512) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Internal: template_header wrong size: %d should be 512", (int)sizeof(template_header));
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Internal: template_header wrong size: %zu should be 512",
+ sizeof(template_header));
return (ARCHIVE_FATAL);
}
ustar = (struct ustar *)malloc(sizeof(*ustar));
if (ustar == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Can't allocate ustar data");
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate ustar data");
return (ARCHIVE_FATAL);
}
memset(ustar, 0, sizeof(*ustar));
a->format_data = ustar;
-
- a->pad_uncompressed = 1; /* Mimic gtar in this respect. */
a->format_name = "ustar";
+ a->format_options = archive_write_ustar_options;
a->format_write_header = archive_write_ustar_header;
a->format_write_data = archive_write_ustar_data;
- a->format_finish = archive_write_ustar_finish;
- a->format_destroy = archive_write_ustar_destroy;
+ a->format_close = archive_write_ustar_close;
+ a->format_free = archive_write_ustar_free;
a->format_finish_entry = archive_write_ustar_finish_entry;
a->archive.archive_format = ARCHIVE_FORMAT_TAR_USTAR;
a->archive.archive_format_name = "POSIX ustar";
@@ -193,14 +205,60 @@ archive_write_set_format_ustar(struct archive *_a)
}
static int
+archive_write_ustar_options(struct archive_write *a, const char *key,
+ const char *val)
+{
+ struct ustar *ustar = (struct ustar *)a->format_data;
+ int ret = ARCHIVE_FAILED;
+
+ if (strcmp(key, "hdrcharset") == 0) {
+ if (val == NULL || val[0] == 0)
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "%s: hdrcharset option needs a character-set name",
+ a->format_name);
+ else {
+ ustar->opt_sconv = archive_string_conversion_to_charset(
+ &a->archive, val, 0);
+ if (ustar->opt_sconv != NULL)
+ ret = ARCHIVE_OK;
+ else
+ ret = ARCHIVE_FATAL;
+ }
+ } else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "%s: unknown keyword ``%s''", a->format_name, key);
+
+ return (ret);
+}
+
+static int
archive_write_ustar_header(struct archive_write *a, struct archive_entry *entry)
{
char buff[512];
int ret, ret2;
struct ustar *ustar;
+ struct archive_string_conv *sconv;
ustar = (struct ustar *)a->format_data;
+ /* Setup default string conversion. */
+ if (ustar->opt_sconv == NULL) {
+ if (!ustar->init_default_conversion) {
+ ustar->sconv_default =
+ archive_string_default_conversion_for_write(&(a->archive));
+ ustar->init_default_conversion = 1;
+ }
+ sconv = ustar->sconv_default;
+ } else
+ sconv = ustar->opt_sconv;
+
+ /* Sanity check. */
+ if (archive_entry_pathname(entry) == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Can't record entry in tar file without pathname");
+ return (ARCHIVE_FAILED);
+ }
+
/* Only regular files (not hardlinks) have data. */
if (archive_entry_hardlink(entry) != NULL ||
archive_entry_symlink(entry) != NULL ||
@@ -229,10 +287,10 @@ archive_write_ustar_header(struct archive_write *a, struct archive_entry *entry)
}
}
- ret = __archive_write_format_header_ustar(a, buff, entry, -1, 1);
+ ret = __archive_write_format_header_ustar(a, buff, entry, -1, 1, sconv);
if (ret < ARCHIVE_WARN)
return (ret);
- ret2 = (a->compressor.write)(a, buff, 512);
+ ret2 = __archive_write_output(a, buff, 512);
if (ret2 < ARCHIVE_WARN)
return (ret2);
if (ret2 < ret)
@@ -255,10 +313,11 @@ archive_write_ustar_header(struct archive_write *a, struct archive_entry *entry)
*/
int
__archive_write_format_header_ustar(struct archive_write *a, char h[512],
- struct archive_entry *entry, int tartype, int strict)
+ struct archive_entry *entry, int tartype, int strict,
+ struct archive_string_conv *sconv)
{
unsigned int checksum;
- int i, ret;
+ int i, r, ret;
size_t copy_length;
const char *p, *pp;
int mytartype;
@@ -277,13 +336,23 @@ __archive_write_format_header_ustar(struct archive_write *a, char h[512],
* are allowed to exactly fill their destination (without null),
* I use memcpy(dest, src, strlen()) here a lot to copy strings.
*/
-
- pp = archive_entry_pathname(entry);
- if (strlen(pp) <= USTAR_name_size)
- memcpy(h + USTAR_name_offset, pp, strlen(pp));
+ r = archive_entry_pathname_l(entry, &pp, &copy_length, sconv);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate pathname '%s' to %s",
+ pp, archive_string_conversion_charset_name(sconv));
+ ret = ARCHIVE_WARN;
+ }
+ if (copy_length <= USTAR_name_size)
+ memcpy(h + USTAR_name_offset, pp, copy_length);
else {
/* Store in two pieces, splitting at a '/'. */
- p = strchr(pp + strlen(pp) - USTAR_name_size - 1, '/');
+ p = strchr(pp + copy_length - USTAR_name_size - 1, '/');
/*
* Look for the next '/' if we chose the first character
* as the separator. (ustar format doesn't permit
@@ -302,7 +371,7 @@ __archive_write_format_header_ustar(struct archive_write *a, char h[512],
* The only feasible separator is a final '/';
* this would result in a non-empty prefix and
* an empty name, which POSIX doesn't
- * explicity forbid, but it just feels wrong.
+ * explicitly forbid, but it just feels wrong.
*/
archive_set_error(&a->archive, ENAMETOOLONG,
"Pathname too long");
@@ -315,17 +384,42 @@ __archive_write_format_header_ustar(struct archive_write *a, char h[512],
} else {
/* Copy prefix and remainder to appropriate places */
memcpy(h + USTAR_prefix_offset, pp, p - pp);
- memcpy(h + USTAR_name_offset, p + 1, pp + strlen(pp) - p - 1);
+ memcpy(h + USTAR_name_offset, p + 1,
+ pp + copy_length - p - 1);
}
}
- p = archive_entry_hardlink(entry);
- if (p != NULL)
+ r = archive_entry_hardlink_l(entry, &p, &copy_length, sconv);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Linkname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate linkname '%s' to %s",
+ p, archive_string_conversion_charset_name(sconv));
+ ret = ARCHIVE_WARN;
+ }
+ if (copy_length > 0)
mytartype = '1';
- else
- p = archive_entry_symlink(entry);
- if (p != NULL && p[0] != '\0') {
- copy_length = strlen(p);
+ else {
+ r = archive_entry_symlink_l(entry, &p, &copy_length, sconv);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Linkname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate linkname '%s' to %s",
+ p, archive_string_conversion_charset_name(sconv));
+ ret = ARCHIVE_WARN;
+ }
+ }
+ if (copy_length > 0) {
if (copy_length > USTAR_linkname_size) {
archive_set_error(&a->archive, ENAMETOOLONG,
"Link contents too long");
@@ -335,9 +429,20 @@ __archive_write_format_header_ustar(struct archive_write *a, char h[512],
memcpy(h + USTAR_linkname_offset, p, copy_length);
}
- p = archive_entry_uname(entry);
- if (p != NULL && p[0] != '\0') {
- copy_length = strlen(p);
+ r = archive_entry_uname_l(entry, &p, &copy_length, sconv);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Uname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate uname '%s' to %s",
+ p, archive_string_conversion_charset_name(sconv));
+ ret = ARCHIVE_WARN;
+ }
+ if (copy_length > 0) {
if (copy_length > USTAR_uname_size) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Username too long");
@@ -347,9 +452,20 @@ __archive_write_format_header_ustar(struct archive_write *a, char h[512],
memcpy(h + USTAR_uname_offset, p, copy_length);
}
- p = archive_entry_gname(entry);
- if (p != NULL && p[0] != '\0') {
- copy_length = strlen(p);
+ r = archive_entry_gname_l(entry, &p, &copy_length, sconv);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Gname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate gname '%s' to %s",
+ p, archive_string_conversion_charset_name(sconv));
+ ret = ARCHIVE_WARN;
+ }
+ if (copy_length > 0) {
if (strlen(p) > USTAR_gname_size) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Group name too long");
@@ -359,27 +475,36 @@ __archive_write_format_header_ustar(struct archive_write *a, char h[512],
memcpy(h + USTAR_gname_offset, p, copy_length);
}
- if (format_number(archive_entry_mode(entry) & 07777, h + USTAR_mode_offset, USTAR_mode_size, USTAR_mode_max_size, strict)) {
- archive_set_error(&a->archive, ERANGE, "Numeric mode too large");
+ if (format_number(archive_entry_mode(entry) & 07777,
+ h + USTAR_mode_offset, USTAR_mode_size, USTAR_mode_max_size, strict)) {
+ archive_set_error(&a->archive, ERANGE,
+ "Numeric mode too large");
ret = ARCHIVE_FAILED;
}
- if (format_number(archive_entry_uid(entry), h + USTAR_uid_offset, USTAR_uid_size, USTAR_uid_max_size, strict)) {
- archive_set_error(&a->archive, ERANGE, "Numeric user ID too large");
+ if (format_number(archive_entry_uid(entry),
+ h + USTAR_uid_offset, USTAR_uid_size, USTAR_uid_max_size, strict)) {
+ archive_set_error(&a->archive, ERANGE,
+ "Numeric user ID too large");
ret = ARCHIVE_FAILED;
}
- if (format_number(archive_entry_gid(entry), h + USTAR_gid_offset, USTAR_gid_size, USTAR_gid_max_size, strict)) {
- archive_set_error(&a->archive, ERANGE, "Numeric group ID too large");
+ if (format_number(archive_entry_gid(entry),
+ h + USTAR_gid_offset, USTAR_gid_size, USTAR_gid_max_size, strict)) {
+ archive_set_error(&a->archive, ERANGE,
+ "Numeric group ID too large");
ret = ARCHIVE_FAILED;
}
- if (format_number(archive_entry_size(entry), h + USTAR_size_offset, USTAR_size_size, USTAR_size_max_size, strict)) {
- archive_set_error(&a->archive, ERANGE, "File size out of range");
+ if (format_number(archive_entry_size(entry),
+ h + USTAR_size_offset, USTAR_size_size, USTAR_size_max_size, strict)) {
+ archive_set_error(&a->archive, ERANGE,
+ "File size out of range");
ret = ARCHIVE_FAILED;
}
- if (format_number(archive_entry_mtime(entry), h + USTAR_mtime_offset, USTAR_mtime_size, USTAR_mtime_max_size, strict)) {
+ if (format_number(archive_entry_mtime(entry),
+ h + USTAR_mtime_offset, USTAR_mtime_size, USTAR_mtime_max_size, strict)) {
archive_set_error(&a->archive, ERANGE,
"File modification time too large");
ret = ARCHIVE_FAILED;
@@ -387,15 +512,17 @@ __archive_write_format_header_ustar(struct archive_write *a, char h[512],
if (archive_entry_filetype(entry) == AE_IFBLK
|| archive_entry_filetype(entry) == AE_IFCHR) {
- if (format_number(archive_entry_rdevmajor(entry), h + USTAR_rdevmajor_offset,
- USTAR_rdevmajor_size, USTAR_rdevmajor_max_size, strict)) {
+ if (format_number(archive_entry_rdevmajor(entry),
+ h + USTAR_rdevmajor_offset, USTAR_rdevmajor_size,
+ USTAR_rdevmajor_max_size, strict)) {
archive_set_error(&a->archive, ERANGE,
"Major device number too large");
ret = ARCHIVE_FAILED;
}
- if (format_number(archive_entry_rdevminor(entry), h + USTAR_rdevminor_offset,
- USTAR_rdevminor_size, USTAR_rdevminor_max_size, strict)) {
+ if (format_number(archive_entry_rdevminor(entry),
+ h + USTAR_rdevminor_offset, USTAR_rdevminor_size,
+ USTAR_rdevminor_max_size, strict)) {
archive_set_error(&a->archive, ERANGE,
"Minor device number too large");
ret = ARCHIVE_FAILED;
@@ -519,19 +646,13 @@ format_octal(int64_t v, char *p, int s)
}
static int
-archive_write_ustar_finish(struct archive_write *a)
+archive_write_ustar_close(struct archive_write *a)
{
- int r;
-
- if (a->compressor.write == NULL)
- return (ARCHIVE_OK);
-
- r = write_nulls(a, 512*2);
- return (r);
+ return (__archive_write_nulls(a, 512*2));
}
static int
-archive_write_ustar_destroy(struct archive_write *a)
+archive_write_ustar_free(struct archive_write *a)
{
struct ustar *ustar;
@@ -548,28 +669,12 @@ archive_write_ustar_finish_entry(struct archive_write *a)
int ret;
ustar = (struct ustar *)a->format_data;
- ret = write_nulls(a,
+ ret = __archive_write_nulls(a,
ustar->entry_bytes_remaining + ustar->entry_padding);
ustar->entry_bytes_remaining = ustar->entry_padding = 0;
return (ret);
}
-static int
-write_nulls(struct archive_write *a, size_t padding)
-{
- int ret;
- size_t to_write;
-
- while (padding > 0) {
- to_write = padding < a->null_length ? padding : a->null_length;
- ret = (a->compressor.write)(a, a->nulls, to_write);
- if (ret != ARCHIVE_OK)
- return (ret);
- padding -= to_write;
- }
- return (ARCHIVE_OK);
-}
-
static ssize_t
archive_write_ustar_data(struct archive_write *a, const void *buff, size_t s)
{
@@ -579,7 +684,7 @@ archive_write_ustar_data(struct archive_write *a, const void *buff, size_t s)
ustar = (struct ustar *)a->format_data;
if (s > ustar->entry_bytes_remaining)
s = ustar->entry_bytes_remaining;
- ret = (a->compressor.write)(a, buff, s);
+ ret = __archive_write_output(a, buff, s);
ustar->entry_bytes_remaining -= s;
if (ret != ARCHIVE_OK)
return (ret);
diff --git a/libarchive/archive_write_set_format_xar.c b/libarchive/archive_write_set_format_xar.c
new file mode 100644
index 000000000000..8e1794370076
--- /dev/null
+++ b/libarchive/archive_write_set_format_xar.c
@@ -0,0 +1,3175 @@
+/*-
+ * Copyright (c) 2010-2011 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+__FBSDID("$FreeBSD$");
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#include <stdlib.h>
+#if HAVE_LIBXML_XMLWRITER_H
+#include <libxml/xmlwriter.h>
+#endif
+#ifdef HAVE_BZLIB_H
+#include <bzlib.h>
+#endif
+#if HAVE_LZMA_H
+#include <lzma.h>
+#endif
+#ifdef HAVE_ZLIB_H
+#include <zlib.h>
+#endif
+
+#ifndef PATH_MAX
+#define PATH_MAX 4096
+#endif
+
+#include "archive.h"
+#include "archive_crypto_private.h"
+#include "archive_endian.h"
+#include "archive_entry.h"
+#include "archive_entry_locale.h"
+#include "archive_private.h"
+#include "archive_rb.h"
+#include "archive_string.h"
+#include "archive_write_private.h"
+
+/*
+ * Differences to xar utility.
+ * - Subdocument is not supported yet.
+ * - ACL is not supported yet.
+ * - When writing an XML element <link type="<file-type>">, <file-type>
+ * which is a file type a symbolic link is referencing is always marked
+ * as "broken". Xar utility uses stat(2) to get the file type, but, in
+ * libarcive format writer, we should not use it; if it is needed, we
+ * should get about it at archive_read_disk.c.
+ * - It is possible to appear both <flags> and <ext2> elements.
+ * Xar utility generates <flags> on BSD platform and <ext2> on Linux
+ * platform.
+ *
+ */
+
+#if !(defined(HAVE_LIBXML_XMLWRITER_H) && defined(LIBXML_VERSION) &&\
+ LIBXML_VERSION >= 20703) ||\
+ !defined(HAVE_ZLIB_H) || \
+ !defined(ARCHIVE_HAS_MD5) || !defined(ARCHIVE_HAS_SHA1)
+/*
+ * xar needs several external libraries.
+ * o libxml2
+ * o openssl or MD5/SHA1 hash function
+ * o zlib
+ * o bzlib2 (option)
+ * o liblzma (option)
+ */
+int
+archive_write_set_format_xar(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Xar not supported on this platform");
+ return (ARCHIVE_WARN);
+}
+
+#else /* Support xar format */
+
+/*#define DEBUG_PRINT_TOC 1 */
+
+#define HEADER_MAGIC 0x78617221
+#define HEADER_SIZE 28
+#define HEADER_VERSION 1
+
+enum sumalg {
+ CKSUM_NONE = 0,
+ CKSUM_SHA1 = 1,
+ CKSUM_MD5 = 2
+};
+
+#define MD5_SIZE 16
+#define SHA1_SIZE 20
+#define MAX_SUM_SIZE 20
+#define MD5_NAME "md5"
+#define SHA1_NAME "sha1"
+
+enum enctype {
+ NONE,
+ GZIP,
+ BZIP2,
+ LZMA,
+ XZ,
+};
+
+struct chksumwork {
+ enum sumalg alg;
+#ifdef ARCHIVE_HAS_MD5
+ archive_md5_ctx md5ctx;
+#endif
+#ifdef ARCHIVE_HAS_SHA1
+ archive_sha1_ctx sha1ctx;
+#endif
+};
+
+enum la_zaction {
+ ARCHIVE_Z_FINISH,
+ ARCHIVE_Z_RUN
+};
+
+/*
+ * Universal zstream.
+ */
+struct la_zstream {
+ const unsigned char *next_in;
+ size_t avail_in;
+ uint64_t total_in;
+
+ unsigned char *next_out;
+ size_t avail_out;
+ uint64_t total_out;
+
+ int valid;
+ void *real_stream;
+ int (*code) (struct archive *a,
+ struct la_zstream *lastrm,
+ enum la_zaction action);
+ int (*end)(struct archive *a,
+ struct la_zstream *lastrm);
+};
+
+struct chksumval {
+ enum sumalg alg;
+ size_t len;
+ unsigned char val[MAX_SUM_SIZE];
+};
+
+struct heap_data {
+ int id;
+ struct heap_data *next;
+ uint64_t temp_offset;
+ uint64_t length; /* archived size. */
+ uint64_t size; /* extracted size. */
+ enum enctype compression;
+ struct chksumval a_sum; /* archived checksum. */
+ struct chksumval e_sum; /* extracted checksum. */
+};
+
+struct file {
+ struct archive_rb_node rbnode;
+
+ int id;
+ struct archive_entry *entry;
+
+ struct archive_rb_tree rbtree;
+ struct file *next;
+ struct file *chnext;
+ struct file *hlnext;
+ /* For hardlinked files.
+ * Use only when archive_entry_nlink() > 1 */
+ struct file *hardlink_target;
+ struct file *parent; /* parent directory entry */
+ /*
+ * To manage sub directory files.
+ * We use 'chnext' a menber of struct file to chain.
+ */
+ struct {
+ struct file *first;
+ struct file **last;
+ } children;
+
+ /* For making a directory tree. */
+ struct archive_string parentdir;
+ struct archive_string basename;
+ struct archive_string symlink;
+
+ int ea_idx;
+ struct {
+ struct heap_data *first;
+ struct heap_data **last;
+ } xattr;
+ struct heap_data data;
+ struct archive_string script;
+
+ int virtual:1;
+ int dir:1;
+};
+
+struct hardlink {
+ struct archive_rb_node rbnode;
+ int nlink;
+ struct {
+ struct file *first;
+ struct file **last;
+ } file_list;
+};
+
+struct xar {
+ int temp_fd;
+ uint64_t temp_offset;
+
+ int file_idx;
+ struct file *root;
+ struct file *cur_dirent;
+ struct archive_string cur_dirstr;
+ struct file *cur_file;
+ uint64_t bytes_remaining;
+ struct archive_string tstr;
+ struct archive_string vstr;
+
+ enum sumalg opt_toc_sumalg;
+ enum sumalg opt_sumalg;
+ enum enctype opt_compression;
+ int opt_compression_level;
+
+ struct chksumwork a_sumwrk; /* archived checksum. */
+ struct chksumwork e_sumwrk; /* extracted checksum. */
+ struct la_zstream stream;
+ struct archive_string_conv *sconv;
+ /*
+ * Compressed data buffer.
+ */
+ unsigned char wbuff[1024 * 64];
+ size_t wbuff_remaining;
+
+ struct heap_data toc;
+ /*
+ * The list of all file entries is used to manage struct file
+ * objects.
+ * We use 'next' a menber of struct file to chain.
+ */
+ struct {
+ struct file *first;
+ struct file **last;
+ } file_list;
+ /*
+ * The list of hard-linked file entries.
+ * We use 'hlnext' a menber of struct file to chain.
+ */
+ struct archive_rb_tree hardlink_rbtree;
+};
+
+static int xar_options(struct archive_write *,
+ const char *, const char *);
+static int xar_write_header(struct archive_write *,
+ struct archive_entry *);
+static ssize_t xar_write_data(struct archive_write *,
+ const void *, size_t);
+static int xar_finish_entry(struct archive_write *);
+static int xar_close(struct archive_write *);
+static int xar_free(struct archive_write *);
+
+static struct file *file_new(struct archive_write *a, struct archive_entry *);
+static void file_free(struct file *);
+static struct file *file_create_virtual_dir(struct archive_write *a, struct xar *,
+ const char *);
+static int file_add_child_tail(struct file *, struct file *);
+static struct file *file_find_child(struct file *, const char *);
+static int file_gen_utility_names(struct archive_write *,
+ struct file *);
+static int get_path_component(char *, int, const char *);
+static int file_tree(struct archive_write *, struct file **);
+static void file_register(struct xar *, struct file *);
+static void file_init_register(struct xar *);
+static void file_free_register(struct xar *);
+static int file_register_hardlink(struct archive_write *,
+ struct file *);
+static void file_connect_hardlink_files(struct xar *);
+static void file_init_hardlinks(struct xar *);
+static void file_free_hardlinks(struct xar *);
+
+static void checksum_init(struct chksumwork *, enum sumalg);
+static void checksum_update(struct chksumwork *, const void *, size_t);
+static void checksum_final(struct chksumwork *, struct chksumval *);
+static int compression_init_encoder_gzip(struct archive *,
+ struct la_zstream *, int, int);
+static int compression_code_gzip(struct archive *,
+ struct la_zstream *, enum la_zaction);
+static int compression_end_gzip(struct archive *, struct la_zstream *);
+static int compression_init_encoder_bzip2(struct archive *,
+ struct la_zstream *, int);
+#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
+static int compression_code_bzip2(struct archive *,
+ struct la_zstream *, enum la_zaction);
+static int compression_end_bzip2(struct archive *, struct la_zstream *);
+#endif
+static int compression_init_encoder_lzma(struct archive *,
+ struct la_zstream *, int);
+static int compression_init_encoder_xz(struct archive *,
+ struct la_zstream *, int);
+#if defined(HAVE_LZMA_H)
+static int compression_code_lzma(struct archive *,
+ struct la_zstream *, enum la_zaction);
+static int compression_end_lzma(struct archive *, struct la_zstream *);
+#endif
+static int xar_compression_init_encoder(struct archive_write *);
+static int compression_code(struct archive *,
+ struct la_zstream *, enum la_zaction);
+static int compression_end(struct archive *,
+ struct la_zstream *);
+static int save_xattrs(struct archive_write *, struct file *);
+static int getalgsize(enum sumalg);
+static const char *getalgname(enum sumalg);
+
+int
+archive_write_set_format_xar(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ struct xar *xar;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_xar");
+
+ /* If another format was already registered, unregister it. */
+ if (a->format_free != NULL)
+ (a->format_free)(a);
+
+ xar = calloc(1, sizeof(*xar));
+ if (xar == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate xar data");
+ return (ARCHIVE_FATAL);
+ }
+ xar->temp_fd = -1;
+ file_init_register(xar);
+ file_init_hardlinks(xar);
+ archive_string_init(&(xar->tstr));
+ archive_string_init(&(xar->vstr));
+
+ /*
+ * Create the root directory.
+ */
+ xar->root = file_create_virtual_dir(a, xar, "");
+ if (xar->root == NULL) {
+ free(xar);
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate xar data");
+ return (ARCHIVE_FATAL);
+ }
+ xar->root->parent = xar->root;
+ file_register(xar, xar->root);
+ xar->cur_dirent = xar->root;
+ archive_string_init(&(xar->cur_dirstr));
+ archive_string_ensure(&(xar->cur_dirstr), 1);
+ xar->cur_dirstr.s[0] = 0;
+
+ /*
+ * Initialize option.
+ */
+ /* Set default checksum type. */
+ xar->opt_toc_sumalg = CKSUM_SHA1;
+ xar->opt_sumalg = CKSUM_SHA1;
+ /* Set default compression type and level. */
+ xar->opt_compression = GZIP;
+ xar->opt_compression_level = 6;
+
+ a->format_data = xar;
+
+ a->format_name = "xar";
+ a->format_options = xar_options;
+ a->format_write_header = xar_write_header;
+ a->format_write_data = xar_write_data;
+ a->format_finish_entry = xar_finish_entry;
+ a->format_close = xar_close;
+ a->format_free = xar_free;
+ a->archive.archive_format = ARCHIVE_FORMAT_XAR;
+ a->archive.archive_format_name = "xar";
+
+ return (ARCHIVE_OK);
+}
+
+static int
+xar_options(struct archive_write *a, const char *key, const char *value)
+{
+ struct xar *xar;
+
+ xar = (struct xar *)a->format_data;
+
+ if (strcmp(key, "checksum") == 0) {
+ if (value == NULL)
+ xar->opt_sumalg = CKSUM_NONE;
+ else if (strcmp(value, "sha1") == 0)
+ xar->opt_sumalg = CKSUM_SHA1;
+ else if (strcmp(value, "md5") == 0)
+ xar->opt_sumalg = CKSUM_MD5;
+ else {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "Unkonwn checksum name: `%s'",
+ value);
+ return (ARCHIVE_FAILED);
+ }
+ return (ARCHIVE_OK);
+ }
+ if (strcmp(key, "compression") == 0) {
+ const char *name = NULL;
+
+ if (value == NULL)
+ xar->opt_compression = NONE;
+ else if (strcmp(value, "gzip") == 0)
+ xar->opt_compression = GZIP;
+ else if (strcmp(value, "bzip2") == 0)
+#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
+ xar->opt_compression = BZIP2;
+#else
+ name = "bzip2";
+#endif
+ else if (strcmp(value, "lzma") == 0)
+#if HAVE_LZMA_H
+ xar->opt_compression = LZMA;
+#else
+ name = "lzma";
+#endif
+ else if (strcmp(value, "xz") == 0)
+#if HAVE_LZMA_H
+ xar->opt_compression = XZ;
+#else
+ name = "xz";
+#endif
+ else {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "Unkonwn compression name: `%s'",
+ value);
+ return (ARCHIVE_FAILED);
+ }
+ if (name != NULL) {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "`%s' compression not supported "
+ "on this platform",
+ name);
+ return (ARCHIVE_FAILED);
+ }
+ return (ARCHIVE_OK);
+ }
+ if (strcmp(key, "compression-level") == 0) {
+ if (value == NULL ||
+ !(value[0] >= '0' && value[0] <= '9') ||
+ value[1] != '\0') {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "Illeagal value `%s'",
+ value);
+ return (ARCHIVE_FAILED);
+ }
+ xar->opt_compression_level = value[0] - '0';
+ return (ARCHIVE_OK);
+ }
+ if (strcmp(key, "toc-checksum") == 0) {
+ if (value == NULL)
+ xar->opt_toc_sumalg = CKSUM_NONE;
+ else if (strcmp(value, "sha1") == 0)
+ xar->opt_toc_sumalg = CKSUM_SHA1;
+ else if (strcmp(value, "md5") == 0)
+ xar->opt_toc_sumalg = CKSUM_MD5;
+ else {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "Unkonwn checksum name: `%s'",
+ value);
+ return (ARCHIVE_FAILED);
+ }
+ return (ARCHIVE_OK);
+ }
+
+ return (ARCHIVE_FAILED);
+}
+
+static int
+xar_write_header(struct archive_write *a, struct archive_entry *entry)
+{
+ struct xar *xar;
+ struct file *file;
+ struct archive_entry *file_entry;
+ int r, r2;
+
+ xar = (struct xar *)a->format_data;
+ xar->cur_file = NULL;
+ xar->bytes_remaining = 0;
+
+ if (xar->sconv == NULL) {
+ xar->sconv = archive_string_conversion_to_charset(
+ &a->archive, "UTF-8", 1);
+ if (xar->sconv == NULL)
+ return (ARCHIVE_FATAL);
+ }
+
+ file = file_new(a, entry);
+ if (file == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate data");
+ return (ARCHIVE_FATAL);
+ }
+ r2 = file_gen_utility_names(a, file);
+ if (r2 < ARCHIVE_WARN)
+ return (r2);
+
+ /*
+ * Ignore a path which looks like the top of directory name
+ * since we have already made the root directory of an Xar archive.
+ */
+ if (archive_strlen(&(file->parentdir)) == 0 &&
+ archive_strlen(&(file->basename)) == 0) {
+ file_free(file);
+ return (r2);
+ }
+
+ /* Add entry into tree */
+ file_entry = file->entry;
+ r = file_tree(a, &file);
+ if (r != ARCHIVE_OK)
+ return (r);
+ /* There is the same file in tree and
+ * the current file is older than the file in tree.
+ * So we don't need the current file data anymore. */
+ if (file->entry != file_entry)
+ return (r2);
+ if (file->id == 0)
+ file_register(xar, file);
+
+ /* A virtual file, which is a directory, does not have
+ * any contents and we won't store it into a archive
+ * file other than its name. */
+ if (file->virtual)
+ return (r2);
+
+ /*
+ * Prepare to save the contents of the file.
+ */
+ if (xar->temp_fd == -1) {
+ int algsize;
+ xar->temp_offset = 0;
+ xar->temp_fd = __archive_mktemp(NULL);
+ if (xar->temp_fd < 0) {
+ archive_set_error(&a->archive, errno,
+ "Couldn't create temporary file");
+ return (ARCHIVE_FATAL);
+ }
+ algsize = getalgsize(xar->opt_toc_sumalg);
+ if (algsize > 0) {
+ if (lseek(xar->temp_fd, algsize, SEEK_SET) < 0) {
+ archive_set_error(&(a->archive), errno,
+ "lseek failed");
+ return (ARCHIVE_FATAL);
+ }
+ xar->temp_offset = algsize;
+ }
+ }
+
+ if (archive_entry_hardlink(file->entry) == NULL) {
+ r = save_xattrs(a, file);
+ if (r != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+
+ /* Non regular files contents are unneeded to be saved to
+ * a temporary file. */
+ if (archive_entry_filetype(file->entry) != AE_IFREG)
+ return (r2);
+
+ /*
+ * Set the current file to cur_file to read its contents.
+ */
+ xar->cur_file = file;
+
+ if (archive_entry_nlink(file->entry) > 1) {
+ r = file_register_hardlink(a, file);
+ if (r != ARCHIVE_OK)
+ return (r);
+ if (archive_entry_hardlink(file->entry) != NULL) {
+ archive_entry_unset_size(file->entry);
+ return (r2);
+ }
+ }
+
+ /* Save a offset of current file in temporary file. */
+ file->data.temp_offset = xar->temp_offset;
+ file->data.size = archive_entry_size(file->entry);
+ file->data.compression = xar->opt_compression;
+ xar->bytes_remaining = archive_entry_size(file->entry);
+ checksum_init(&(xar->a_sumwrk), xar->opt_sumalg);
+ checksum_init(&(xar->e_sumwrk), xar->opt_sumalg);
+ r = xar_compression_init_encoder(a);
+
+ if (r != ARCHIVE_OK)
+ return (r);
+ else
+ return (r2);
+}
+
+static int
+write_to_temp(struct archive_write *a, const void *buff, size_t s)
+{
+ struct xar *xar;
+ unsigned char *p;
+ ssize_t ws;
+
+ xar = (struct xar *)a->format_data;
+ p = (unsigned char *)buff;
+ while (s) {
+ ws = write(xar->temp_fd, p, s);
+ if (ws < 0) {
+ archive_set_error(&(a->archive), errno,
+ "fwrite function failed");
+ return (ARCHIVE_FATAL);
+ }
+ s -= ws;
+ p += ws;
+ xar->temp_offset += ws;
+ }
+ return (ARCHIVE_OK);
+}
+
+static ssize_t
+xar_write_data(struct archive_write *a, const void *buff, size_t s)
+{
+ struct xar *xar;
+ enum la_zaction run;
+ size_t size, rsize;
+ int r;
+
+ xar = (struct xar *)a->format_data;
+
+ if (s > xar->bytes_remaining)
+ s = xar->bytes_remaining;
+ if (s == 0 || xar->cur_file == NULL)
+ return (0);
+ if (xar->cur_file->data.compression == NONE) {
+ checksum_update(&(xar->e_sumwrk), buff, s);
+ checksum_update(&(xar->a_sumwrk), buff, s);
+ size = rsize = s;
+ } else {
+ xar->stream.next_in = (const unsigned char *)buff;
+ xar->stream.avail_in = s;
+ if (xar->bytes_remaining > s)
+ run = ARCHIVE_Z_RUN;
+ else
+ run = ARCHIVE_Z_FINISH;
+ /* Compress file data. */
+ r = compression_code(&(a->archive), &(xar->stream), run);
+ if (r != ARCHIVE_OK && r != ARCHIVE_EOF)
+ return (ARCHIVE_FATAL);
+ rsize = s - xar->stream.avail_in;
+ checksum_update(&(xar->e_sumwrk), buff, rsize);
+ size = sizeof(xar->wbuff) - xar->stream.avail_out;
+ checksum_update(&(xar->a_sumwrk), xar->wbuff, size);
+ }
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ if (xar->bytes_remaining ==
+ archive_entry_size(xar->cur_file->entry)) {
+ /*
+ * Get the path of a shell script if so.
+ */
+ const unsigned char *b = (const unsigned char *)buff;
+
+ archive_string_empty(&(xar->cur_file->script));
+ if (rsize > 2 && b[0] == '#' && b[1] == '!') {
+ size_t i, end, off;
+
+ off = 2;
+ if (b[off] == ' ')
+ off++;
+#ifdef PATH_MAX
+ if ((rsize - off) > PATH_MAX)
+ end = off + PATH_MAX;
+ else
+#endif
+ end = rsize;
+ /* Find the end of a script path. */
+ for (i = off; i < end && b[i] != '\0' &&
+ b[i] != '\n' && b[i] != '\r' &&
+ b[i] != ' ' && b[i] != '\t'; i++)
+ ;
+ archive_strncpy(&(xar->cur_file->script), b + off,
+ i - off);
+ }
+ }
+#endif
+
+ if (xar->cur_file->data.compression == NONE) {
+ if (write_to_temp(a, buff, size) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ } else {
+ if (write_to_temp(a, xar->wbuff, size) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+ xar->bytes_remaining -= rsize;
+ xar->cur_file->data.length += size;
+
+ return (rsize);
+}
+
+static int
+xar_finish_entry(struct archive_write *a)
+{
+ struct xar *xar;
+ struct file *file;
+ size_t s;
+ ssize_t w;
+
+ xar = (struct xar *)a->format_data;
+ if (xar->cur_file == NULL)
+ return (ARCHIVE_OK);
+
+ while (xar->bytes_remaining > 0) {
+ s = xar->bytes_remaining;
+ if (s > a->null_length)
+ s = a->null_length;
+ w = xar_write_data(a, a->nulls, s);
+ if (w > 0)
+ xar->bytes_remaining -= w;
+ else
+ return (w);
+ }
+ file = xar->cur_file;
+ checksum_final(&(xar->e_sumwrk), &(file->data.e_sum));
+ checksum_final(&(xar->a_sumwrk), &(file->data.a_sum));
+ xar->cur_file = NULL;
+
+ return (ARCHIVE_OK);
+}
+
+static int
+xmlwrite_string_attr(struct archive_write *a, xmlTextWriterPtr writer,
+ const char *key, const char *value,
+ const char *attrkey, const char *attrvalue)
+{
+ int r;
+
+ r = xmlTextWriterStartElement(writer, BAD_CAST(key));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterStartElement() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ if (attrkey != NULL && attrvalue != NULL) {
+ r = xmlTextWriterWriteAttribute(writer,
+ BAD_CAST(attrkey), BAD_CAST(attrvalue));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterWriteAttribute() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ }
+ if (value != NULL) {
+ r = xmlTextWriterWriteString(writer, BAD_CAST(value));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterWriteString() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ }
+ r = xmlTextWriterEndElement(writer);
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterEndElement() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+xmlwrite_string(struct archive_write *a, xmlTextWriterPtr writer,
+ const char *key, const char *value)
+{
+ int r;
+
+ if (value == NULL)
+ return (ARCHIVE_OK);
+
+ r = xmlTextWriterStartElement(writer, BAD_CAST(key));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterStartElement() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ if (value != NULL) {
+ r = xmlTextWriterWriteString(writer, BAD_CAST(value));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterWriteString() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ }
+ r = xmlTextWriterEndElement(writer);
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterEndElement() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+xmlwrite_fstring(struct archive_write *a, xmlTextWriterPtr writer,
+ const char *key, const char *fmt, ...)
+{
+ struct xar *xar;
+ va_list ap;
+
+ xar = (struct xar *)a->format_data;
+ va_start(ap, fmt);
+ archive_string_empty(&xar->vstr);
+ archive_string_vsprintf(&xar->vstr, fmt, ap);
+ va_end(ap);
+ return (xmlwrite_string(a, writer, key, xar->vstr.s));
+}
+
+static int
+xmlwrite_time(struct archive_write *a, xmlTextWriterPtr writer,
+ const char *key, time_t t, int z)
+{
+ char timestr[100];
+ struct tm tm;
+
+#if defined(HAVE_GMTIME_R)
+ gmtime_r(&t, &tm);
+#elif defined(HAVE__GMTIME64_S)
+ _gmtime64_s(&tm, &t);
+#else
+ memcpy(&tm, gmtime(&t), sizeof(tm));
+#endif
+ memset(&timestr, 0, sizeof(timestr));
+ /* Do not use %F and %T for portability. */
+ strftime(timestr, sizeof(timestr), "%Y-%m-%dT%H:%M:%S", &tm);
+ if (z)
+ strcat(timestr, "Z");
+ return (xmlwrite_string(a, writer, key, timestr));
+}
+
+static int
+xmlwrite_mode(struct archive_write *a, xmlTextWriterPtr writer,
+ const char *key, mode_t mode)
+{
+ char ms[5];
+
+ ms[0] = '0';
+ ms[1] = '0' + ((mode >> 6) & 07);
+ ms[2] = '0' + ((mode >> 3) & 07);
+ ms[3] = '0' + (mode & 07);
+ ms[4] = '\0';
+
+ return (xmlwrite_string(a, writer, key, ms));
+}
+
+static int
+xmlwrite_sum(struct archive_write *a, xmlTextWriterPtr writer,
+ const char *key, struct chksumval *sum)
+{
+ const char *algname;
+ int algsize;
+ char buff[MAX_SUM_SIZE*2 + 1];
+ char *p;
+ unsigned char *s;
+ int i, r;
+
+ if (sum->len > 0) {
+ algname = getalgname(sum->alg);
+ algsize = getalgsize(sum->alg);
+ if (algname != NULL) {
+ const char *hex = "0123456789abcdef";
+ p = buff;
+ s = sum->val;
+ for (i = 0; i < algsize; i++) {
+ *p++ = hex[(*s >> 4)];
+ *p++ = hex[(*s & 0x0f)];
+ s++;
+ }
+ *p = '\0';
+ r = xmlwrite_string_attr(a, writer,
+ key, buff,
+ "style", algname);
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ }
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+xmlwrite_heap(struct archive_write *a, xmlTextWriterPtr writer,
+ struct heap_data *heap)
+{
+ const char *encname;
+ int r;
+
+ r = xmlwrite_fstring(a, writer, "length", "%ju", heap->length);
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ r = xmlwrite_fstring(a, writer, "offset", "%ju", heap->temp_offset);
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ r = xmlwrite_fstring(a, writer, "size", "%ju", heap->size);
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ switch (heap->compression) {
+ case GZIP:
+ encname = "application/x-gzip"; break;
+ case BZIP2:
+ encname = "application/x-bzip2"; break;
+ case LZMA:
+ encname = "application/x-lzma"; break;
+ case XZ:
+ encname = "application/x-xz"; break;
+ default:
+ encname = "application/octet-stream"; break;
+ }
+ r = xmlwrite_string_attr(a, writer, "encoding", NULL,
+ "style", encname);
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ r = xmlwrite_sum(a, writer, "archived-checksum", &(heap->a_sum));
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ r = xmlwrite_sum(a, writer, "extracted-checksum", &(heap->e_sum));
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ return (ARCHIVE_OK);
+}
+
+/*
+ * xar utility records fflags as following xml elements:
+ * <flags>
+ * <UserNoDump/>
+ * .....
+ * </flags>
+ * or
+ * <ext2>
+ * <NoDump/>
+ * .....
+ * </ext2>
+ * If xar is running on BSD platform, records <flags>..</flags>;
+ * if xar is running on linux platform, records <ext2>..</ext2>;
+ * otherwise does not record.
+ *
+ * Our implements records both <flags> and <ext2> if it's necessary.
+ */
+static int
+make_fflags_entry(struct archive_write *a, xmlTextWriterPtr writer,
+ const char *element, const char *fflags_text)
+{
+ static const struct flagentry {
+ const char *name;
+ const char *xarname;
+ }
+ flagbsd[] = {
+ { "sappnd", "SystemAppend"},
+ { "sappend", "SystemAppend"},
+ { "arch", "SystemArchived"},
+ { "archived", "SystemArchived"},
+ { "schg", "SystemImmutable"},
+ { "schange", "SystemImmutable"},
+ { "simmutable", "SystemImmutable"},
+ { "nosunlnk", "SystemNoUnlink"},
+ { "nosunlink", "SystemNoUnlink"},
+ { "snapshot", "SystemSnapshot"},
+ { "uappnd", "UserAppend"},
+ { "uappend", "UserAppend"},
+ { "uchg", "UserImmutable"},
+ { "uchange", "UserImmutable"},
+ { "uimmutable", "UserImmutable"},
+ { "nodump", "UserNoDump"},
+ { "noopaque", "UserOpaque"},
+ { "nouunlnk", "UserNoUnlink"},
+ { "nouunlink", "UserNoUnlink"},
+ { NULL, NULL}
+ },
+ flagext2[] = {
+ { "sappnd", "AppendOnly"},
+ { "sappend", "AppendOnly"},
+ { "schg", "Immutable"},
+ { "schange", "Immutable"},
+ { "simmutable", "Immutable"},
+ { "nodump", "NoDump"},
+ { "nouunlnk", "Undelete"},
+ { "nouunlink", "Undelete"},
+ { "btree", "BTree"},
+ { "comperr", "CompError"},
+ { "compress", "Compress"},
+ { "noatime", "NoAtime"},
+ { "compdirty", "CompDirty"},
+ { "comprblk", "CompBlock"},
+ { "dirsync", "DirSync"},
+ { "hashidx", "HashIndexed"},
+ { "imagic", "iMagic"},
+ { "journal", "Journaled"},
+ { "securedeletion", "SecureDeletion"},
+ { "sync", "Synchronous"},
+ { "notail", "NoTail"},
+ { "topdir", "TopDir"},
+ { "reserved", "Reserved"},
+ { NULL, NULL}
+ };
+ const struct flagentry *fe, *flagentry;
+#define FLAGENTRY_MAXSIZE ((sizeof(flagbsd)+sizeof(flagext2))/sizeof(flagbsd))
+ const struct flagentry *avail[FLAGENTRY_MAXSIZE];
+ const char *p;
+ int i, n, r;
+
+ if (strcmp(element, "ext2") == 0)
+ flagentry = flagext2;
+ else
+ flagentry = flagbsd;
+ n = 0;
+ p = fflags_text;
+ do {
+ const char *cp;
+
+ cp = strchr(p, ',');
+ if (cp == NULL)
+ cp = p + strlen(p);
+
+ for (fe = flagentry; fe->name != NULL; fe++) {
+ if (fe->name[cp - p] != '\0'
+ || p[0] != fe->name[0])
+ continue;
+ if (strncmp(p, fe->name, cp - p) == 0) {
+ avail[n++] = fe;
+ break;
+ }
+ }
+ if (*cp == ',')
+ p = cp + 1;
+ else
+ p = NULL;
+ } while (p != NULL);
+
+ if (n > 0) {
+ r = xmlTextWriterStartElement(writer, BAD_CAST(element));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterStartElement() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ for (i = 0; i < n; i++) {
+ r = xmlwrite_string(a, writer,
+ avail[i]->xarname, NULL);
+ if (r != ARCHIVE_OK)
+ return (r);
+ }
+
+ r = xmlTextWriterEndElement(writer);
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterEndElement() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+make_file_entry(struct archive_write *a, xmlTextWriterPtr writer,
+ struct file *file)
+{
+ struct xar *xar;
+ const char *filetype, *filelink, *fflags;
+ struct archive_string linkto;
+ struct heap_data *heap;
+ unsigned char *tmp;
+ const char *p;
+ size_t len;
+ int r, r2, l, ll;
+
+ xar = (struct xar *)a->format_data;
+ r2 = ARCHIVE_OK;
+
+ /*
+ * Make a file name entry, "<name>".
+ */
+ l = ll = archive_strlen(&(file->basename));
+ tmp = malloc(l);
+ if (tmp == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ r = UTF8Toisolat1(tmp, &l, BAD_CAST(file->basename.s), &ll);
+ free(tmp);
+ if (r < 0) {
+ r = xmlTextWriterStartElement(writer, BAD_CAST("name"));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterStartElement() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ r = xmlTextWriterWriteAttribute(writer,
+ BAD_CAST("enctype"), BAD_CAST("base64"));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterWriteAttribute() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ r = xmlTextWriterWriteBase64(writer, file->basename.s,
+ 0, archive_strlen(&(file->basename)));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterWriteBase64() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ r = xmlTextWriterEndElement(writer);
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterEndElement() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ } else {
+ r = xmlwrite_string(a, writer, "name", file->basename.s);
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ }
+
+ /*
+ * Make a file type entry, "<type>".
+ */
+ filelink = NULL;
+ archive_string_init(&linkto);
+ switch (archive_entry_filetype(file->entry)) {
+ case AE_IFDIR:
+ filetype = "directory"; break;
+ case AE_IFLNK:
+ filetype = "symlink"; break;
+ case AE_IFCHR:
+ filetype = "character special"; break;
+ case AE_IFBLK:
+ filetype = "block special"; break;
+ case AE_IFSOCK:
+ filetype = "socket"; break;
+ case AE_IFIFO:
+ filetype = "fifo"; break;
+ case AE_IFREG:
+ default:
+ if (file->hardlink_target != NULL) {
+ filetype = "hardlink";
+ filelink = "link";
+ if (file->hardlink_target == file)
+ archive_strcpy(&linkto, "original");
+ else
+ archive_string_sprintf(&linkto, "%d",
+ file->hardlink_target->id);
+ } else
+ filetype = "file";
+ break;
+ }
+ r = xmlwrite_string_attr(a, writer, "type", filetype,
+ filelink, linkto.s);
+ archive_string_free(&linkto);
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+
+ /*
+ * On a virtual directory, we record "name" and "type" only.
+ */
+ if (file->virtual)
+ return (ARCHIVE_OK);
+
+ switch (archive_entry_filetype(file->entry)) {
+ case AE_IFLNK:
+ /*
+ * xar utility has checked a file type, which
+ * a symblic-link file has referenced.
+ * For example:
+ * <link type="directory">../ref/</link>
+ * The symlink target file is "../ref/" and its
+ * file type is a directory.
+ *
+ * <link type="file">../f</link>
+ * The symlink target file is "../f" and its
+ * file type is a regular file.
+ *
+ * But our implemention cannot do it, and then we
+ * always record that a attribute "type" is "borken",
+ * for example:
+ * <link type="broken">foo/bar</link>
+ * It means "foo/bar" is not reachable.
+ */
+ r = xmlwrite_string_attr(a, writer, "link",
+ file->symlink.s,
+ "type", "broken");
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ break;
+ case AE_IFCHR:
+ case AE_IFBLK:
+ r = xmlTextWriterStartElement(writer, BAD_CAST("device"));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterStartElement() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ r = xmlwrite_fstring(a, writer, "major",
+ "%d", archive_entry_rdevmajor(file->entry));
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ r = xmlwrite_fstring(a, writer, "minor",
+ "%d", archive_entry_rdevminor(file->entry));
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ r = xmlTextWriterEndElement(writer);
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterEndElement() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ break;
+ default:
+ break;
+ }
+
+ /*
+ * Make a inode entry, "<inode>".
+ */
+ r = xmlwrite_fstring(a, writer, "inode",
+ "%jd", archive_entry_ino64(file->entry));
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ if (archive_entry_dev(file->entry) != 0) {
+ r = xmlwrite_fstring(a, writer, "deviceno",
+ "%d", archive_entry_dev(file->entry));
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ }
+
+ /*
+ * Make a file mode entry, "<mode>".
+ */
+ r = xmlwrite_mode(a, writer, "mode",
+ archive_entry_mode(file->entry));
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+
+ /*
+ * Make a user entry, "<uid>" and "<user>.
+ */
+ r = xmlwrite_fstring(a, writer, "uid",
+ "%d", archive_entry_uid(file->entry));
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ r = archive_entry_uname_l(file->entry, &p, &len, xar->sconv);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Uname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate uname '%s' to UTF-8",
+ archive_entry_uname(file->entry));
+ r2 = ARCHIVE_WARN;
+ }
+ if (len > 0) {
+ r = xmlwrite_string(a, writer, "user", p);
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ }
+
+ /*
+ * Make a group entry, "<gid>" and "<group>.
+ */
+ r = xmlwrite_fstring(a, writer, "gid",
+ "%d", archive_entry_gid(file->entry));
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ r = archive_entry_gname_l(file->entry, &p, &len, xar->sconv);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Gname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate gname '%s' to UTF-8",
+ archive_entry_gname(file->entry));
+ r2 = ARCHIVE_WARN;
+ }
+ if (len > 0) {
+ r = xmlwrite_string(a, writer, "group", p);
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ }
+
+ /*
+ * Make a ctime entry, "<ctime>".
+ */
+ if (archive_entry_ctime_is_set(file->entry)) {
+ r = xmlwrite_time(a, writer, "ctime",
+ archive_entry_ctime(file->entry), 1);
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ }
+
+ /*
+ * Make a mtime entry, "<mtime>".
+ */
+ if (archive_entry_mtime_is_set(file->entry)) {
+ r = xmlwrite_time(a, writer, "mtime",
+ archive_entry_mtime(file->entry), 1);
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ }
+
+ /*
+ * Make a atime entry, "<atime>".
+ */
+ if (archive_entry_atime_is_set(file->entry)) {
+ r = xmlwrite_time(a, writer, "atime",
+ archive_entry_atime(file->entry), 1);
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ }
+
+ /*
+ * Make fflags entries, "<flags>" and "<ext2>".
+ */
+ fflags = archive_entry_fflags_text(file->entry);
+ if (fflags != NULL) {
+ r = make_fflags_entry(a, writer, "flags", fflags);
+ if (r < 0)
+ return (r);
+ r = make_fflags_entry(a, writer, "ext2", fflags);
+ if (r < 0)
+ return (r);
+ }
+
+ /*
+ * Make extended attribute entries, "<ea>".
+ */
+ archive_entry_xattr_reset(file->entry);
+ for (heap = file->xattr.first; heap != NULL; heap = heap->next) {
+ const char *name;
+ const void *value;
+ size_t size;
+
+ archive_entry_xattr_next(file->entry,
+ &name, &value, &size);
+ r = xmlTextWriterStartElement(writer, BAD_CAST("ea"));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterStartElement() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ r = xmlTextWriterWriteFormatAttribute(writer,
+ BAD_CAST("id"), "%d", heap->id);
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterWriteAttribute() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ r = xmlwrite_heap(a, writer, heap);
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ r = xmlwrite_string(a, writer, "name", name);
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+
+ r = xmlTextWriterEndElement(writer);
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterEndElement() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ /*
+ * Make a file data entry, "<data>".
+ */
+ if (file->data.length > 0) {
+ r = xmlTextWriterStartElement(writer, BAD_CAST("data"));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterStartElement() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+
+ r = xmlwrite_heap(a, writer, &(file->data));
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+
+ r = xmlTextWriterEndElement(writer);
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterEndElement() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ if (archive_strlen(&file->script) > 0) {
+ r = xmlTextWriterStartElement(writer, BAD_CAST("content"));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterStartElement() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+
+ r = xmlwrite_string(a, writer,
+ "interpreter", file->script.s);
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+
+ r = xmlwrite_string(a, writer, "type", "script");
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+
+ r = xmlTextWriterEndElement(writer);
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterEndElement() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ return (r2);
+}
+
+/*
+ * Make the TOC
+ */
+static int
+make_toc(struct archive_write *a)
+{
+ struct xar *xar;
+ struct file *np;
+ xmlBufferPtr bp;
+ xmlTextWriterPtr writer;
+ int algsize;
+ int r, ret;
+
+ xar = (struct xar *)a->format_data;
+
+ ret = ARCHIVE_FATAL;
+
+ /*
+ * Initialize xml writer.
+ */
+ writer = NULL;
+ bp = xmlBufferCreate();
+ if (bp == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "xmlBufferCreate() "
+ "couldn't create xml buffer");
+ goto exit_toc;
+ }
+ writer = xmlNewTextWriterMemory(bp, 0);
+ if (writer == NULL) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlNewTextWriterMemory() "
+ "couldn't create xml writer");
+ goto exit_toc;
+ }
+ r = xmlTextWriterStartDocument(writer, "1.0", "UTF-8", NULL);
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterStartDocument() failed: %d", r);
+ goto exit_toc;
+ }
+ r = xmlTextWriterSetIndent(writer, 4);
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterSetIndent() failed: %d", r);
+ goto exit_toc;
+ }
+
+ /*
+ * Start recoding TOC
+ */
+ r = xmlTextWriterStartElement(writer, BAD_CAST("xar"));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterStartElement() failed: %d", r);
+ goto exit_toc;
+ }
+ r = xmlTextWriterStartElement(writer, BAD_CAST("toc"));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterStartDocument() failed: %d", r);
+ goto exit_toc;
+ }
+
+ /*
+ * Record the creation time of the archive file.
+ */
+ r = xmlwrite_time(a, writer, "creation-time", time(NULL), 0);
+ if (r < 0)
+ goto exit_toc;
+
+ /*
+ * Record the checksum value of TOC
+ */
+ algsize = getalgsize(xar->opt_toc_sumalg);
+ if (algsize) {
+ /*
+ * Record TOC checksum
+ */
+ r = xmlTextWriterStartElement(writer, BAD_CAST("checksum"));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterStartElement() failed: %d", r);
+ goto exit_toc;
+ }
+ r = xmlTextWriterWriteAttribute(writer, BAD_CAST("style"),
+ BAD_CAST(getalgname(xar->opt_toc_sumalg)));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterWriteAttribute() failed: %d", r);
+ goto exit_toc;
+ }
+
+ /*
+ * Record the offset of the value of checksum of TOC
+ */
+ r = xmlwrite_string(a, writer, "offset", "0");
+ if (r < 0)
+ goto exit_toc;
+
+ /*
+ * Record the size of the value of checksum of TOC
+ */
+ r = xmlwrite_fstring(a, writer, "size", "%d", algsize);
+ if (r < 0)
+ goto exit_toc;
+
+ r = xmlTextWriterEndElement(writer);
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterEndElement() failed: %d", r);
+ goto exit_toc;
+ }
+ }
+
+ np = xar->root;
+ do {
+ if (np != np->parent) {
+ r = make_file_entry(a, writer, np);
+ if (r != ARCHIVE_OK)
+ goto exit_toc;
+ }
+
+ if (np->dir && np->children.first != NULL) {
+ /* Enter to sub directories. */
+ np = np->children.first;
+ r = xmlTextWriterStartElement(writer,
+ BAD_CAST("file"));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterStartElement() "
+ "failed: %d", r);
+ goto exit_toc;
+ }
+ r = xmlTextWriterWriteFormatAttribute(
+ writer, BAD_CAST("id"), "%d", np->id);
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterWriteAttribute() "
+ "failed: %d", r);
+ goto exit_toc;
+ }
+ continue;
+ }
+ while (np != np->parent) {
+ r = xmlTextWriterEndElement(writer);
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterEndElement() "
+ "failed: %d", r);
+ goto exit_toc;
+ }
+ if (np->chnext == NULL) {
+ /* Return to the parent directory. */
+ np = np->parent;
+ } else {
+ np = np->chnext;
+ r = xmlTextWriterStartElement(writer,
+ BAD_CAST("file"));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterStartElement() "
+ "failed: %d", r);
+ goto exit_toc;
+ }
+ r = xmlTextWriterWriteFormatAttribute(
+ writer, BAD_CAST("id"), "%d", np->id);
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterWriteAttribute() "
+ "failed: %d", r);
+ goto exit_toc;
+ }
+ break;
+ }
+ }
+ } while (np != np->parent);
+
+ r = xmlTextWriterEndDocument(writer);
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterEndDocument() failed: %d", r);
+ goto exit_toc;
+ }
+#if DEBUG_PRINT_TOC
+ fprintf(stderr, "\n---TOC-- %d bytes --\n%s\n",
+ strlen((const char *)bp->content), bp->content);
+#endif
+
+ /*
+ * Compress the TOC and calculate the sum of the TOC.
+ */
+ xar->toc.temp_offset = xar->temp_offset;
+ xar->toc.size = bp->use;
+ checksum_init(&(xar->a_sumwrk), xar->opt_toc_sumalg);
+
+ r = compression_init_encoder_gzip(&(a->archive),
+ &(xar->stream), 6, 1);
+ if (r != ARCHIVE_OK)
+ goto exit_toc;
+ xar->stream.next_in = bp->content;
+ xar->stream.avail_in = bp->use;
+ xar->stream.total_in = 0;
+ xar->stream.next_out = xar->wbuff;
+ xar->stream.avail_out = sizeof(xar->wbuff);
+ xar->stream.total_out = 0;
+ for (;;) {
+ size_t size;
+
+ r = compression_code(&(a->archive),
+ &(xar->stream), ARCHIVE_Z_FINISH);
+ if (r != ARCHIVE_OK && r != ARCHIVE_EOF)
+ goto exit_toc;
+ size = sizeof(xar->wbuff) - xar->stream.avail_out;
+ checksum_update(&(xar->a_sumwrk), xar->wbuff, size);
+ if (write_to_temp(a, xar->wbuff, size) != ARCHIVE_OK)
+ goto exit_toc;
+ if (r == ARCHIVE_EOF)
+ break;
+ xar->stream.next_out = xar->wbuff;
+ xar->stream.avail_out = sizeof(xar->wbuff);
+ }
+ r = compression_end(&(a->archive), &(xar->stream));
+ if (r != ARCHIVE_OK)
+ goto exit_toc;
+ xar->toc.length = xar->stream.total_out;
+ xar->toc.compression = GZIP;
+ checksum_final(&(xar->a_sumwrk), &(xar->toc.a_sum));
+
+ ret = ARCHIVE_OK;
+exit_toc:
+ if (writer)
+ xmlFreeTextWriter(writer);
+ if (bp)
+ xmlBufferFree(bp);
+
+ return (ret);
+}
+
+static int
+flush_wbuff(struct archive_write *a)
+{
+ struct xar *xar;
+ int r;
+ size_t s;
+
+ xar = (struct xar *)a->format_data;
+ s = sizeof(xar->wbuff) - xar->wbuff_remaining;
+ r = __archive_write_output(a, xar->wbuff, s);
+ if (r != ARCHIVE_OK)
+ return (r);
+ xar->wbuff_remaining = sizeof(xar->wbuff);
+ return (r);
+}
+
+static int
+copy_out(struct archive_write *a, uint64_t offset, uint64_t length)
+{
+ struct xar *xar;
+ int r;
+
+ xar = (struct xar *)a->format_data;
+ if (lseek(xar->temp_fd, offset, SEEK_SET) < 0) {
+ archive_set_error(&(a->archive), errno, "lseek failed");
+ return (ARCHIVE_FATAL);
+ }
+ while (length) {
+ size_t rsize;
+ ssize_t rs;
+ unsigned char *wb;
+
+ if (length > xar->wbuff_remaining)
+ rsize = xar->wbuff_remaining;
+ else
+ rsize = (size_t)length;
+ wb = xar->wbuff + (sizeof(xar->wbuff) - xar->wbuff_remaining);
+ rs = read(xar->temp_fd, wb, rsize);
+ if (rs < 0) {
+ archive_set_error(&(a->archive), errno,
+ "Can't read temporary file(%jd)",
+ (intmax_t)rs);
+ return (ARCHIVE_FATAL);
+ }
+ if (rs == 0) {
+ archive_set_error(&(a->archive), 0,
+ "Truncated xar archive");
+ return (ARCHIVE_FATAL);
+ }
+ xar->wbuff_remaining -= rs;
+ length -= rs;
+ if (xar->wbuff_remaining == 0) {
+ r = flush_wbuff(a);
+ if (r != ARCHIVE_OK)
+ return (r);
+ }
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+xar_close(struct archive_write *a)
+{
+ struct xar *xar;
+ unsigned char *wb;
+ uint64_t length;
+ int r;
+
+ xar = (struct xar *)a->format_data;
+
+ /* Empty! */
+ if (xar->root->children.first == NULL)
+ return (ARCHIVE_OK);
+
+ /* Save the length of all file extended attributes and contents. */
+ length = xar->temp_offset;
+
+ /* Connect hardlinked files */
+ file_connect_hardlink_files(xar);
+
+ /* Make the TOC */
+ r = make_toc(a);
+ if (r != ARCHIVE_OK)
+ return (r);
+ /*
+ * Make the xar header on wbuff(write buffer).
+ */
+ wb = xar->wbuff;
+ xar->wbuff_remaining = sizeof(xar->wbuff);
+ archive_be32enc(&wb[0], HEADER_MAGIC);
+ archive_be16enc(&wb[4], HEADER_SIZE);
+ archive_be16enc(&wb[6], HEADER_VERSION);
+ archive_be64enc(&wb[8], xar->toc.length);
+ archive_be64enc(&wb[16], xar->toc.size);
+ archive_be32enc(&wb[24], xar->toc.a_sum.alg);
+ xar->wbuff_remaining -= HEADER_SIZE;
+
+ /*
+ * Write the TOC
+ */
+ r = copy_out(a, xar->toc.temp_offset, xar->toc.length);
+ if (r != ARCHIVE_OK)
+ return (r);
+
+ /* Write the checksum value of the TOC. */
+ if (xar->toc.a_sum.len) {
+ if (xar->wbuff_remaining < xar->toc.a_sum.len) {
+ r = flush_wbuff(a);
+ if (r != ARCHIVE_OK)
+ return (r);
+ }
+ wb = xar->wbuff + (sizeof(xar->wbuff) - xar->wbuff_remaining);
+ memcpy(wb, xar->toc.a_sum.val, xar->toc.a_sum.len);
+ xar->wbuff_remaining -= xar->toc.a_sum.len;
+ }
+
+ /*
+ * Write all file extended attributes and contents.
+ */
+ r = copy_out(a, xar->toc.a_sum.len, length);
+ if (r != ARCHIVE_OK)
+ return (r);
+ r = flush_wbuff(a);
+ return (r);
+}
+
+static int
+xar_free(struct archive_write *a)
+{
+ struct xar *xar;
+
+ xar = (struct xar *)a->format_data;
+ archive_string_free(&(xar->cur_dirstr));
+ archive_string_free(&(xar->tstr));
+ archive_string_free(&(xar->vstr));
+ file_free_hardlinks(xar);
+ file_free_register(xar);
+ compression_end(&(a->archive), &(xar->stream));
+ free(xar);
+
+ return (ARCHIVE_OK);
+}
+
+static int
+file_cmp_node(const struct archive_rb_node *n1,
+ const struct archive_rb_node *n2)
+{
+ struct file *f1 = (struct file *)n1;
+ struct file *f2 = (struct file *)n2;
+
+ return (strcmp(f1->basename.s, f2->basename.s));
+}
+
+static int
+file_cmp_key(const struct archive_rb_node *n, const void *key)
+{
+ struct file *f = (struct file *)n;
+
+ return (strcmp(f->basename.s, (const char *)key));
+}
+
+static struct file *
+file_new(struct archive_write *a, struct archive_entry *entry)
+{
+ struct file *file;
+ static const struct archive_rb_tree_ops rb_ops = {
+ file_cmp_node, file_cmp_key
+ };
+
+ file = calloc(1, sizeof(*file));
+ if (file == NULL)
+ return (NULL);
+
+ if (entry != NULL)
+ file->entry = archive_entry_clone(entry);
+ else
+ file->entry = archive_entry_new2(&a->archive);
+ if (file->entry == NULL) {
+ free(file);
+ return (NULL);
+ }
+ __archive_rb_tree_init(&(file->rbtree), &rb_ops);
+ file->children.first = NULL;
+ file->children.last = &(file->children.first);
+ file->xattr.first = NULL;
+ file->xattr.last = &(file->xattr.first);
+ archive_string_init(&(file->parentdir));
+ archive_string_init(&(file->basename));
+ archive_string_init(&(file->symlink));
+ archive_string_init(&(file->script));
+ if (entry != NULL && archive_entry_filetype(entry) == AE_IFDIR)
+ file->dir = 1;
+
+ return (file);
+}
+
+static void
+file_free(struct file *file)
+{
+ struct heap_data *heap, *next_heap;
+
+ heap = file->xattr.first;
+ while (heap != NULL) {
+ next_heap = heap->next;
+ free(heap);
+ heap = next_heap;
+ }
+ archive_string_free(&(file->parentdir));
+ archive_string_free(&(file->basename));
+ archive_string_free(&(file->symlink));
+ archive_string_free(&(file->script));
+ free(file);
+}
+
+static struct file *
+file_create_virtual_dir(struct archive_write *a, struct xar *xar,
+ const char *pathname)
+{
+ struct file *file;
+
+ file = file_new(a, NULL);
+ if (file == NULL)
+ return (NULL);
+ archive_entry_set_pathname(file->entry, pathname);
+ archive_entry_set_mode(file->entry, 0555 | AE_IFDIR);
+
+ file->dir = 1;
+ file->virtual = 1;
+
+ return (file);
+}
+
+static int
+file_add_child_tail(struct file *parent, struct file *child)
+{
+ if (!__archive_rb_tree_insert_node(
+ &(parent->rbtree), (struct archive_rb_node *)child))
+ return (0);
+ child->chnext = NULL;
+ *parent->children.last = child;
+ parent->children.last = &(child->chnext);
+ child->parent = parent;
+ return (1);
+}
+
+/*
+ * Find a entry from `parent'
+ */
+static struct file *
+file_find_child(struct file *parent, const char *child_name)
+{
+ struct file *np;
+
+ np = (struct file *)__archive_rb_tree_find_node(
+ &(parent->rbtree), child_name);
+ return (np);
+}
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+static void
+cleanup_backslash(char *utf8, size_t len)
+{
+
+ /* Convert a path-separator from '\' to '/' */
+ while (*utf8 != '\0' && len) {
+ if (*utf8 == '\\')
+ *utf8 = '/';
+ ++utf8;
+ --len;
+ }
+}
+#else
+#define cleanup_backslash(p, len) /* nop */
+#endif
+
+/*
+ * Generate a parent directory name and a base name from a pathname.
+ */
+static int
+file_gen_utility_names(struct archive_write *a, struct file *file)
+{
+ struct xar *xar;
+ const char *pp;
+ char *p, *dirname, *slash;
+ size_t len;
+ int r = ARCHIVE_OK;
+
+ xar = (struct xar *)a->format_data;
+ archive_string_empty(&(file->parentdir));
+ archive_string_empty(&(file->basename));
+ archive_string_empty(&(file->symlink));
+
+ if (file->parent == file)/* virtual root */
+ return (ARCHIVE_OK);
+
+ if (archive_entry_pathname_l(file->entry, &pp, &len, xar->sconv)
+ != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate pathname '%s' to UTF-8",
+ archive_entry_pathname(file->entry));
+ r = ARCHIVE_WARN;
+ }
+ archive_strncpy(&(file->parentdir), pp, len);
+ len = file->parentdir.length;
+ p = dirname = file->parentdir.s;
+ /*
+ * Convert a path-separator from '\' to '/'
+ */
+ cleanup_backslash(p, len);
+
+ /*
+ * Remove leading '/', '../' and './' elements
+ */
+ while (*p) {
+ if (p[0] == '/') {
+ p++;
+ len--;
+ } else if (p[0] != '.')
+ break;
+ else if (p[1] == '.' && p[2] == '/') {
+ p += 3;
+ len -= 3;
+ } else if (p[1] == '/' || (p[1] == '.' && p[2] == '\0')) {
+ p += 2;
+ len -= 2;
+ } else if (p[1] == '\0') {
+ p++;
+ len--;
+ } else
+ break;
+ }
+ if (p != dirname) {
+ memmove(dirname, p, len+1);
+ p = dirname;
+ }
+ /*
+ * Remove "/","/." and "/.." elements from tail.
+ */
+ while (len > 0) {
+ size_t ll = len;
+
+ if (len > 0 && p[len-1] == '/') {
+ p[len-1] = '\0';
+ len--;
+ }
+ if (len > 1 && p[len-2] == '/' && p[len-1] == '.') {
+ p[len-2] = '\0';
+ len -= 2;
+ }
+ if (len > 2 && p[len-3] == '/' && p[len-2] == '.' &&
+ p[len-1] == '.') {
+ p[len-3] = '\0';
+ len -= 3;
+ }
+ if (ll == len)
+ break;
+ }
+ while (*p) {
+ if (p[0] == '/') {
+ if (p[1] == '/')
+ /* Convert '//' --> '/' */
+ strcpy(p, p+1);
+ else if (p[1] == '.' && p[2] == '/')
+ /* Convert '/./' --> '/' */
+ strcpy(p, p+2);
+ else if (p[1] == '.' && p[2] == '.' && p[3] == '/') {
+ /* Convert 'dir/dir1/../dir2/'
+ * --> 'dir/dir2/'
+ */
+ char *rp = p -1;
+ while (rp >= dirname) {
+ if (*rp == '/')
+ break;
+ --rp;
+ }
+ if (rp > dirname) {
+ strcpy(rp, p+3);
+ p = rp;
+ } else {
+ strcpy(dirname, p+4);
+ p = dirname;
+ }
+ } else
+ p++;
+ } else
+ p++;
+ }
+ p = dirname;
+ len = strlen(p);
+
+ if (archive_entry_filetype(file->entry) == AE_IFLNK) {
+ size_t len2;
+ /* Convert symlink name too. */
+ if (archive_entry_symlink_l(file->entry, &pp, &len2,
+ xar->sconv) != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Linkname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate symlink '%s' to UTF-8",
+ archive_entry_symlink(file->entry));
+ r = ARCHIVE_WARN;
+ }
+ archive_strncpy(&(file->symlink), pp, len2);
+ cleanup_backslash(file->symlink.s, file->symlink.length);
+ }
+ /*
+ * - Count up directory elements.
+ * - Find out the position which points the last position of
+ * path separator('/').
+ */
+ slash = NULL;
+ for (; *p != '\0'; p++)
+ if (*p == '/')
+ slash = p;
+ if (slash == NULL) {
+ /* The pathname doesn't have a parent directory. */
+ file->parentdir.length = len;
+ archive_string_copy(&(file->basename), &(file->parentdir));
+ archive_string_empty(&(file->parentdir));
+ file->parentdir.s = '\0';
+ return (r);
+ }
+
+ /* Make a basename from dirname and slash */
+ *slash = '\0';
+ file->parentdir.length = slash - dirname;
+ archive_strcpy(&(file->basename), slash + 1);
+ return (r);
+}
+
+static int
+get_path_component(char *name, int n, const char *fn)
+{
+ char *p;
+ int l;
+
+ p = strchr(fn, '/');
+ if (p == NULL) {
+ if ((l = strlen(fn)) == 0)
+ return (0);
+ } else
+ l = p - fn;
+ if (l > n -1)
+ return (-1);
+ memcpy(name, fn, l);
+ name[l] = '\0';
+
+ return (l);
+}
+
+/*
+ * Add a new entry into the tree.
+ */
+static int
+file_tree(struct archive_write *a, struct file **filepp)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ char name[_MAX_FNAME];/* Included null terminator size. */
+#elif defined(NAME_MAX) && NAME_MAX >= 255
+ char name[NAME_MAX+1];
+#else
+ char name[256];
+#endif
+ struct xar *xar = (struct xar *)a->format_data;
+ struct file *dent, *file, *np;
+ struct archive_entry *ent;
+ const char *fn, *p;
+ int l;
+
+ file = *filepp;
+ dent = xar->root;
+ if (file->parentdir.length > 0)
+ fn = p = file->parentdir.s;
+ else
+ fn = p = "";
+
+ /*
+ * If the path of the parent directory of `file' entry is
+ * the same as the path of `cur_dirent', add isoent to
+ * `cur_dirent'.
+ */
+ if (archive_strlen(&(xar->cur_dirstr))
+ == archive_strlen(&(file->parentdir)) &&
+ strcmp(xar->cur_dirstr.s, fn) == 0) {
+ if (!file_add_child_tail(xar->cur_dirent, file)) {
+ np = (struct file *)__archive_rb_tree_find_node(
+ &(xar->cur_dirent->rbtree),
+ file->basename.s);
+ goto same_entry;
+ }
+ return (ARCHIVE_OK);
+ }
+
+ for (;;) {
+ l = get_path_component(name, sizeof(name), fn);
+ if (l == 0) {
+ np = NULL;
+ break;
+ }
+ if (l < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "A name buffer is too small");
+ file_free(file);
+ *filepp = NULL;
+ return (ARCHIVE_FATAL);
+ }
+
+ np = file_find_child(dent, name);
+ if (np == NULL || fn[0] == '\0')
+ break;
+
+ /* Find next subdirectory. */
+ if (!np->dir) {
+ /* NOT Directory! */
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "`%s' is not directory, we cannot insert `%s' ",
+ archive_entry_pathname(np->entry),
+ archive_entry_pathname(file->entry));
+ file_free(file);
+ *filepp = NULL;
+ return (ARCHIVE_FAILED);
+ }
+ fn += l;
+ if (fn[0] == '/')
+ fn++;
+ dent = np;
+ }
+ if (np == NULL) {
+ /*
+ * Create virtual parent directories.
+ */
+ while (fn[0] != '\0') {
+ struct file *vp;
+ struct archive_string as;
+
+ archive_string_init(&as);
+ archive_strncat(&as, p, fn - p + l);
+ if (as.s[as.length-1] == '/') {
+ as.s[as.length-1] = '\0';
+ as.length--;
+ }
+ vp = file_create_virtual_dir(a, xar, as.s);
+ if (vp == NULL) {
+ archive_string_free(&as);
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ file_free(file);
+ *filepp = NULL;
+ return (ARCHIVE_FATAL);
+ }
+ archive_string_free(&as);
+ if (file_gen_utility_names(a, vp) <= ARCHIVE_FAILED)
+ return (ARCHIVE_FATAL);
+ file_add_child_tail(dent, vp);
+ file_register(xar, vp);
+ np = vp;
+
+ fn += l;
+ if (fn[0] == '/')
+ fn++;
+ l = get_path_component(name, sizeof(name), fn);
+ if (l < 0) {
+ archive_string_free(&as);
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "A name buffer is too small");
+ file_free(file);
+ *filepp = NULL;
+ return (ARCHIVE_FATAL);
+ }
+ dent = np;
+ }
+
+ /* Found out the parent directory where isoent can be
+ * inserted. */
+ xar->cur_dirent = dent;
+ archive_string_empty(&(xar->cur_dirstr));
+ archive_string_ensure(&(xar->cur_dirstr),
+ archive_strlen(&(dent->parentdir)) +
+ archive_strlen(&(dent->basename)) + 2);
+ if (archive_strlen(&(dent->parentdir)) +
+ archive_strlen(&(dent->basename)) == 0)
+ xar->cur_dirstr.s[0] = 0;
+ else {
+ if (archive_strlen(&(dent->parentdir)) > 0) {
+ archive_string_copy(&(xar->cur_dirstr),
+ &(dent->parentdir));
+ archive_strappend_char(&(xar->cur_dirstr), '/');
+ }
+ archive_string_concat(&(xar->cur_dirstr),
+ &(dent->basename));
+ }
+
+ if (!file_add_child_tail(dent, file)) {
+ np = (struct file *)__archive_rb_tree_find_node(
+ &(dent->rbtree), file->basename.s);
+ goto same_entry;
+ }
+ return (ARCHIVE_OK);
+ }
+
+same_entry:
+ /*
+ * We have already has the entry the filename of which is
+ * the same.
+ */
+ if (archive_entry_filetype(np->entry) !=
+ archive_entry_filetype(file->entry)) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Found duplicate entries `%s' and its file type is "
+ "different",
+ archive_entry_pathname(np->entry));
+ file_free(file);
+ *filepp = NULL;
+ return (ARCHIVE_FAILED);
+ }
+
+ /* Swap files. */
+ ent = np->entry;
+ np->entry = file->entry;
+ file->entry = ent;
+ np->virtual = 0;
+
+ file_free(file);
+ *filepp = np;
+ return (ARCHIVE_OK);
+}
+
+static void
+file_register(struct xar *xar, struct file *file)
+{
+ file->id = xar->file_idx++;
+ file->next = NULL;
+ *xar->file_list.last = file;
+ xar->file_list.last = &(file->next);
+}
+
+static void
+file_init_register(struct xar *xar)
+{
+ xar->file_list.first = NULL;
+ xar->file_list.last = &(xar->file_list.first);
+}
+
+static void
+file_free_register(struct xar *xar)
+{
+ struct file *file, *file_next;
+
+ file = xar->file_list.first;
+ while (file != NULL) {
+ file_next = file->next;
+ file_free(file);
+ file = file_next;
+ }
+}
+
+/*
+ * Register entry to get a hardlink target.
+ */
+static int
+file_register_hardlink(struct archive_write *a, struct file *file)
+{
+ struct xar *xar = (struct xar *)a->format_data;
+ struct hardlink *hl;
+ const char *pathname;
+
+ archive_entry_set_nlink(file->entry, 1);
+ pathname = archive_entry_hardlink(file->entry);
+ if (pathname == NULL) {
+ /* This `file` is a hardlink target. */
+ hl = malloc(sizeof(*hl));
+ if (hl == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ hl->nlink = 1;
+ /* A hardlink target must be the first position. */
+ file->hlnext = NULL;
+ hl->file_list.first = file;
+ hl->file_list.last = &(file->hlnext);
+ __archive_rb_tree_insert_node(&(xar->hardlink_rbtree),
+ (struct archive_rb_node *)hl);
+ } else {
+ hl = (struct hardlink *)__archive_rb_tree_find_node(
+ &(xar->hardlink_rbtree), pathname);
+ if (hl != NULL) {
+ /* Insert `file` entry into the tail. */
+ file->hlnext = NULL;
+ *hl->file_list.last = file;
+ hl->file_list.last = &(file->hlnext);
+ hl->nlink++;
+ }
+ archive_entry_unset_size(file->entry);
+ }
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Hardlinked files have to have the same location of extent.
+ * We have to find out hardlink target entries for entries which
+ * have a hardlink target name.
+ */
+static void
+file_connect_hardlink_files(struct xar *xar)
+{
+ struct archive_rb_node *n;
+ struct hardlink *hl;
+ struct file *target, *nf;
+
+ ARCHIVE_RB_TREE_FOREACH(n, &(xar->hardlink_rbtree)) {
+ hl = (struct hardlink *)n;
+
+ /* The first entry must be a hardlink target. */
+ target = hl->file_list.first;
+ archive_entry_set_nlink(target->entry, hl->nlink);
+ if (hl->nlink > 1)
+ /* It means this file is a hardlink
+ * targe itself. */
+ target->hardlink_target = target;
+ for (nf = target->hlnext;
+ nf != NULL; nf = nf->hlnext) {
+ nf->hardlink_target = target;
+ archive_entry_set_nlink(nf->entry, hl->nlink);
+ }
+ }
+}
+
+static int
+file_hd_cmp_node(const struct archive_rb_node *n1,
+ const struct archive_rb_node *n2)
+{
+ struct hardlink *h1 = (struct hardlink *)n1;
+ struct hardlink *h2 = (struct hardlink *)n2;
+
+ return (strcmp(archive_entry_pathname(h1->file_list.first->entry),
+ archive_entry_pathname(h2->file_list.first->entry)));
+}
+
+static int
+file_hd_cmp_key(const struct archive_rb_node *n, const void *key)
+{
+ struct hardlink *h = (struct hardlink *)n;
+
+ return (strcmp(archive_entry_pathname(h->file_list.first->entry),
+ (const char *)key));
+}
+
+
+static void
+file_init_hardlinks(struct xar *xar)
+{
+ static const struct archive_rb_tree_ops rb_ops = {
+ file_hd_cmp_node, file_hd_cmp_key,
+ };
+
+ __archive_rb_tree_init(&(xar->hardlink_rbtree), &rb_ops);
+}
+
+static void
+file_free_hardlinks(struct xar *xar)
+{
+ struct archive_rb_node *n, *next;
+
+ for (n = ARCHIVE_RB_TREE_MIN(&(xar->hardlink_rbtree)); n;) {
+ next = __archive_rb_tree_iterate(&(xar->hardlink_rbtree),
+ n, ARCHIVE_RB_DIR_RIGHT);
+ free(n);
+ n = next;
+ }
+}
+
+static void
+checksum_init(struct chksumwork *sumwrk, enum sumalg sum_alg)
+{
+ sumwrk->alg = sum_alg;
+ switch (sum_alg) {
+ case CKSUM_NONE:
+ break;
+ case CKSUM_SHA1:
+ archive_sha1_init(&(sumwrk->sha1ctx));
+ break;
+ case CKSUM_MD5:
+ archive_md5_init(&(sumwrk->md5ctx));
+ break;
+ }
+}
+
+static void
+checksum_update(struct chksumwork *sumwrk, const void *buff, size_t size)
+{
+
+ switch (sumwrk->alg) {
+ case CKSUM_NONE:
+ break;
+ case CKSUM_SHA1:
+ archive_sha1_update(&(sumwrk->sha1ctx), buff, size);
+ break;
+ case CKSUM_MD5:
+ archive_md5_update(&(sumwrk->md5ctx), buff, size);
+ break;
+ }
+}
+
+static void
+checksum_final(struct chksumwork *sumwrk, struct chksumval *sumval)
+{
+
+ switch (sumwrk->alg) {
+ case CKSUM_NONE:
+ sumval->len = 0;
+ break;
+ case CKSUM_SHA1:
+ archive_sha1_final(&(sumwrk->sha1ctx), sumval->val);
+ sumval->len = SHA1_SIZE;
+ break;
+ case CKSUM_MD5:
+ archive_md5_final(&(sumwrk->md5ctx), sumval->val);
+ sumval->len = MD5_SIZE;
+ break;
+ }
+ sumval->alg = sumwrk->alg;
+}
+
+#if !defined(HAVE_BZLIB_H) || !defined(BZ_CONFIG_ERROR) || !defined(HAVE_LZMA_H)
+static int
+compression_unsupported_encoder(struct archive *a,
+ struct la_zstream *lastrm, const char *name)
+{
+
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "%s compression not supported on this platform", name);
+ lastrm->valid = 0;
+ lastrm->real_stream = NULL;
+ return (ARCHIVE_FAILED);
+}
+#endif
+
+static int
+compression_init_encoder_gzip(struct archive *a,
+ struct la_zstream *lastrm, int level, int withheader)
+{
+ z_stream *strm;
+
+ if (lastrm->valid)
+ compression_end(a, lastrm);
+ strm = calloc(1, sizeof(*strm));
+ if (strm == NULL) {
+ archive_set_error(a, ENOMEM,
+ "Can't allocate memory for gzip stream");
+ return (ARCHIVE_FATAL);
+ }
+ /* zlib.h is not const-correct, so we need this one bit
+ * of ugly hackery to convert a const * pointer to
+ * a non-const pointer. */
+ strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
+ strm->avail_in = lastrm->avail_in;
+ strm->total_in = lastrm->total_in;
+ strm->next_out = lastrm->next_out;
+ strm->avail_out = lastrm->avail_out;
+ strm->total_out = lastrm->total_out;
+ if (deflateInit2(strm, level, Z_DEFLATED,
+ (withheader)?15:-15,
+ 8, Z_DEFAULT_STRATEGY) != Z_OK) {
+ free(strm);
+ lastrm->real_stream = NULL;
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Internal error initializing compression library");
+ return (ARCHIVE_FATAL);
+ }
+ lastrm->real_stream = strm;
+ lastrm->valid = 1;
+ lastrm->code = compression_code_gzip;
+ lastrm->end = compression_end_gzip;
+ return (ARCHIVE_OK);
+}
+
+static int
+compression_code_gzip(struct archive *a,
+ struct la_zstream *lastrm, enum la_zaction action)
+{
+ z_stream *strm;
+ int r;
+
+ strm = (z_stream *)lastrm->real_stream;
+ /* zlib.h is not const-correct, so we need this one bit
+ * of ugly hackery to convert a const * pointer to
+ * a non-const pointer. */
+ strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
+ strm->avail_in = lastrm->avail_in;
+ strm->total_in = lastrm->total_in;
+ strm->next_out = lastrm->next_out;
+ strm->avail_out = lastrm->avail_out;
+ strm->total_out = lastrm->total_out;
+ r = deflate(strm,
+ (action == ARCHIVE_Z_FINISH)? Z_FINISH: Z_NO_FLUSH);
+ lastrm->next_in = strm->next_in;
+ lastrm->avail_in = strm->avail_in;
+ lastrm->total_in = strm->total_in;
+ lastrm->next_out = strm->next_out;
+ lastrm->avail_out = strm->avail_out;
+ lastrm->total_out = strm->total_out;
+ switch (r) {
+ case Z_OK:
+ return (ARCHIVE_OK);
+ case Z_STREAM_END:
+ return (ARCHIVE_EOF);
+ default:
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "GZip compression failed:"
+ " deflate() call returned status %d", r);
+ return (ARCHIVE_FATAL);
+ }
+}
+
+static int
+compression_end_gzip(struct archive *a, struct la_zstream *lastrm)
+{
+ z_stream *strm;
+ int r;
+
+ strm = (z_stream *)lastrm->real_stream;
+ r = deflateEnd(strm);
+ free(strm);
+ lastrm->real_stream = NULL;
+ lastrm->valid = 0;
+ if (r != Z_OK) {
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Failed to clean up compressor");
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_OK);
+}
+
+#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
+static int
+compression_init_encoder_bzip2(struct archive *a,
+ struct la_zstream *lastrm, int level)
+{
+ bz_stream *strm;
+
+ if (lastrm->valid)
+ compression_end(a, lastrm);
+ strm = calloc(1, sizeof(*strm));
+ if (strm == NULL) {
+ archive_set_error(a, ENOMEM,
+ "Can't allocate memory for bzip2 stream");
+ return (ARCHIVE_FATAL);
+ }
+ /* bzlib.h is not const-correct, so we need this one bit
+ * of ugly hackery to convert a const * pointer to
+ * a non-const pointer. */
+ strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
+ strm->avail_in = lastrm->avail_in;
+ strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
+ strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
+ strm->next_out = (char *)lastrm->next_out;
+ strm->avail_out = lastrm->avail_out;
+ strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
+ strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
+ if (BZ2_bzCompressInit(strm, level, 0, 30) != BZ_OK) {
+ free(strm);
+ lastrm->real_stream = NULL;
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Internal error initializing compression library");
+ return (ARCHIVE_FATAL);
+ }
+ lastrm->real_stream = strm;
+ lastrm->valid = 1;
+ lastrm->code = compression_code_bzip2;
+ lastrm->end = compression_end_bzip2;
+ return (ARCHIVE_OK);
+}
+
+static int
+compression_code_bzip2(struct archive *a,
+ struct la_zstream *lastrm, enum la_zaction action)
+{
+ bz_stream *strm;
+ int r;
+
+ strm = (bz_stream *)lastrm->real_stream;
+ /* bzlib.h is not const-correct, so we need this one bit
+ * of ugly hackery to convert a const * pointer to
+ * a non-const pointer. */
+ strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
+ strm->avail_in = lastrm->avail_in;
+ strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
+ strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
+ strm->next_out = (char *)lastrm->next_out;
+ strm->avail_out = lastrm->avail_out;
+ strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
+ strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
+ r = BZ2_bzCompress(strm,
+ (action == ARCHIVE_Z_FINISH)? BZ_FINISH: BZ_RUN);
+ lastrm->next_in = (const unsigned char *)strm->next_in;
+ lastrm->avail_in = strm->avail_in;
+ lastrm->total_in =
+ (((uint64_t)(uint32_t)strm->total_in_hi32) << 32)
+ + (uint64_t)(uint32_t)strm->total_in_lo32;
+ lastrm->next_out = (unsigned char *)strm->next_out;
+ lastrm->avail_out = strm->avail_out;
+ lastrm->total_out =
+ (((uint64_t)(uint32_t)strm->total_out_hi32) << 32)
+ + (uint64_t)(uint32_t)strm->total_out_lo32;
+ switch (r) {
+ case BZ_RUN_OK: /* Non-finishing */
+ case BZ_FINISH_OK: /* Finishing: There's more work to do */
+ return (ARCHIVE_OK);
+ case BZ_STREAM_END: /* Finishing: all done */
+ /* Only occurs in finishing case */
+ return (ARCHIVE_EOF);
+ default:
+ /* Any other return value indicates an error */
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Bzip2 compression failed:"
+ " BZ2_bzCompress() call returned status %d", r);
+ return (ARCHIVE_FATAL);
+ }
+}
+
+static int
+compression_end_bzip2(struct archive *a, struct la_zstream *lastrm)
+{
+ bz_stream *strm;
+ int r;
+
+ strm = (bz_stream *)lastrm->real_stream;
+ r = BZ2_bzCompressEnd(strm);
+ free(strm);
+ lastrm->real_stream = NULL;
+ lastrm->valid = 0;
+ if (r != BZ_OK) {
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Failed to clean up compressor");
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_OK);
+}
+
+#else
+static int
+compression_init_encoder_bzip2(struct archive *a,
+ struct la_zstream *lastrm, int level)
+{
+
+ (void) level; /* UNUSED */
+ if (lastrm->valid)
+ compression_end(a, lastrm);
+ return (compression_unsupported_encoder(a, lastrm, "bzip2"));
+}
+#endif
+
+#if defined(HAVE_LZMA_H)
+static int
+compression_init_encoder_lzma(struct archive *a,
+ struct la_zstream *lastrm, int level)
+{
+ static const lzma_stream lzma_init_data = LZMA_STREAM_INIT;
+ lzma_stream *strm;
+ lzma_options_lzma lzma_opt;
+ int r;
+
+ if (lastrm->valid)
+ compression_end(a, lastrm);
+ if (lzma_lzma_preset(&lzma_opt, level)) {
+ lastrm->real_stream = NULL;
+ archive_set_error(a, ENOMEM,
+ "Internal error initializing compression library");
+ return (ARCHIVE_FATAL);
+ }
+ strm = calloc(1, sizeof(*strm));
+ if (strm == NULL) {
+ archive_set_error(a, ENOMEM,
+ "Can't allocate memory for lzma stream");
+ return (ARCHIVE_FATAL);
+ }
+ *strm = lzma_init_data;
+ r = lzma_alone_encoder(strm, &lzma_opt);
+ switch (r) {
+ case LZMA_OK:
+ lastrm->real_stream = strm;
+ lastrm->valid = 1;
+ lastrm->code = compression_code_lzma;
+ lastrm->end = compression_end_lzma;
+ r = ARCHIVE_OK;
+ break;
+ case LZMA_MEM_ERROR:
+ free(strm);
+ lastrm->real_stream = NULL;
+ archive_set_error(a, ENOMEM,
+ "Internal error initializing compression library: "
+ "Cannot allocate memory");
+ r = ARCHIVE_FATAL;
+ break;
+ default:
+ free(strm);
+ lastrm->real_stream = NULL;
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Internal error initializing compression library: "
+ "It's a bug in liblzma");
+ r = ARCHIVE_FATAL;
+ break;
+ }
+ return (r);
+}
+
+static int
+compression_init_encoder_xz(struct archive *a,
+ struct la_zstream *lastrm, int level)
+{
+ static const lzma_stream lzma_init_data = LZMA_STREAM_INIT;
+ lzma_stream *strm;
+ lzma_filter *lzmafilters;
+ lzma_options_lzma lzma_opt;
+ int r;
+
+ if (lastrm->valid)
+ compression_end(a, lastrm);
+ strm = calloc(1, sizeof(*strm) + sizeof(*lzmafilters) * 2);
+ if (strm == NULL) {
+ archive_set_error(a, ENOMEM,
+ "Can't allocate memory for xz stream");
+ return (ARCHIVE_FATAL);
+ }
+ lzmafilters = (lzma_filter *)(strm+1);
+ if (level > 6)
+ level = 6;
+ if (lzma_lzma_preset(&lzma_opt, level)) {
+ lastrm->real_stream = NULL;
+ archive_set_error(a, ENOMEM,
+ "Internal error initializing compression library");
+ return (ARCHIVE_FATAL);
+ }
+ lzmafilters[0].id = LZMA_FILTER_LZMA2;
+ lzmafilters[0].options = &lzma_opt;
+ lzmafilters[1].id = LZMA_VLI_UNKNOWN;/* Terminate */
+
+ *strm = lzma_init_data;
+ r = lzma_stream_encoder(strm, lzmafilters, LZMA_CHECK_CRC64);
+ switch (r) {
+ case LZMA_OK:
+ lastrm->real_stream = strm;
+ lastrm->valid = 1;
+ lastrm->code = compression_code_lzma;
+ lastrm->end = compression_end_lzma;
+ r = ARCHIVE_OK;
+ break;
+ case LZMA_MEM_ERROR:
+ free(strm);
+ lastrm->real_stream = NULL;
+ archive_set_error(a, ENOMEM,
+ "Internal error initializing compression library: "
+ "Cannot allocate memory");
+ r = ARCHIVE_FATAL;
+ break;
+ default:
+ free(strm);
+ lastrm->real_stream = NULL;
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Internal error initializing compression library: "
+ "It's a bug in liblzma");
+ r = ARCHIVE_FATAL;
+ break;
+ }
+ return (r);
+}
+
+static int
+compression_code_lzma(struct archive *a,
+ struct la_zstream *lastrm, enum la_zaction action)
+{
+ lzma_stream *strm;
+ int r;
+
+ strm = (lzma_stream *)lastrm->real_stream;
+ strm->next_in = lastrm->next_in;
+ strm->avail_in = lastrm->avail_in;
+ strm->total_in = lastrm->total_in;
+ strm->next_out = lastrm->next_out;
+ strm->avail_out = lastrm->avail_out;
+ strm->total_out = lastrm->total_out;
+ r = lzma_code(strm,
+ (action == ARCHIVE_Z_FINISH)? LZMA_FINISH: LZMA_RUN);
+ lastrm->next_in = strm->next_in;
+ lastrm->avail_in = strm->avail_in;
+ lastrm->total_in = strm->total_in;
+ lastrm->next_out = strm->next_out;
+ lastrm->avail_out = strm->avail_out;
+ lastrm->total_out = strm->total_out;
+ switch (r) {
+ case LZMA_OK:
+ /* Non-finishing case */
+ return (ARCHIVE_OK);
+ case LZMA_STREAM_END:
+ /* This return can only occur in finishing case. */
+ return (ARCHIVE_EOF);
+ case LZMA_MEMLIMIT_ERROR:
+ archive_set_error(a, ENOMEM,
+ "lzma compression error:"
+ " %ju MiB would have been needed",
+ (uintmax_t)((lzma_memusage(strm) + 1024 * 1024 -1)
+ / (1024 * 1024)));
+ return (ARCHIVE_FATAL);
+ default:
+ /* Any other return value indicates an error */
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "lzma compression failed:"
+ " lzma_code() call returned status %d", r);
+ return (ARCHIVE_FATAL);
+ }
+}
+
+static int
+compression_end_lzma(struct archive *a, struct la_zstream *lastrm)
+{
+ lzma_stream *strm;
+
+ (void)a; /* UNUSED */
+ strm = (lzma_stream *)lastrm->real_stream;
+ lzma_end(strm);
+ free(strm);
+ lastrm->valid = 0;
+ lastrm->real_stream = NULL;
+ return (ARCHIVE_OK);
+}
+#else
+static int
+compression_init_encoder_lzma(struct archive *a,
+ struct la_zstream *lastrm, int level)
+{
+
+ (void) level; /* UNUSED */
+ if (lastrm->valid)
+ compression_end(a, lastrm);
+ return (compression_unsupported_encoder(a, lastrm, "lzma"));
+}
+static int
+compression_init_encoder_xz(struct archive *a,
+ struct la_zstream *lastrm, int level)
+{
+
+ (void) level; /* UNUSED */
+ if (lastrm->valid)
+ compression_end(a, lastrm);
+ return (compression_unsupported_encoder(a, lastrm, "xz"));
+}
+#endif
+
+static int
+xar_compression_init_encoder(struct archive_write *a)
+{
+ struct xar *xar;
+ int r;
+
+ xar = (struct xar *)a->format_data;
+ switch (xar->opt_compression) {
+ case GZIP:
+ r = compression_init_encoder_gzip(
+ &(a->archive), &(xar->stream),
+ xar->opt_compression_level, 1);
+ break;
+ case BZIP2:
+ r = compression_init_encoder_bzip2(
+ &(a->archive), &(xar->stream),
+ xar->opt_compression_level);
+ break;
+ case LZMA:
+ r = compression_init_encoder_lzma(
+ &(a->archive), &(xar->stream),
+ xar->opt_compression_level);
+ break;
+ case XZ:
+ r = compression_init_encoder_xz(
+ &(a->archive), &(xar->stream),
+ xar->opt_compression_level);
+ break;
+ default:
+ r = ARCHIVE_OK;
+ break;
+ }
+ if (r == ARCHIVE_OK) {
+ xar->stream.total_in = 0;
+ xar->stream.next_out = xar->wbuff;
+ xar->stream.avail_out = sizeof(xar->wbuff);
+ xar->stream.total_out = 0;
+ }
+
+ return (r);
+}
+
+static int
+compression_code(struct archive *a, struct la_zstream *lastrm,
+ enum la_zaction action)
+{
+ if (lastrm->valid)
+ return (lastrm->code(a, lastrm, action));
+ return (ARCHIVE_OK);
+}
+
+static int
+compression_end(struct archive *a, struct la_zstream *lastrm)
+{
+ if (lastrm->valid)
+ return (lastrm->end(a, lastrm));
+ return (ARCHIVE_OK);
+}
+
+
+static int
+save_xattrs(struct archive_write *a, struct file *file)
+{
+ struct xar *xar;
+ const char *name;
+ const void *value;
+ struct heap_data *heap;
+ size_t size;
+ int count, r;
+
+ xar = (struct xar *)a->format_data;
+ count = archive_entry_xattr_reset(file->entry);
+ if (count == 0)
+ return (ARCHIVE_OK);
+ while (count--) {
+ archive_entry_xattr_next(file->entry,
+ &name, &value, &size);
+ checksum_init(&(xar->a_sumwrk), xar->opt_sumalg);
+ checksum_init(&(xar->e_sumwrk), xar->opt_sumalg);
+
+ heap = calloc(1, sizeof(*heap));
+ if (heap == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for xattr");
+ return (ARCHIVE_FATAL);
+ }
+ heap->id = file->ea_idx++;
+ heap->temp_offset = xar->temp_offset;
+ heap->size = size;/* save a extracted size */
+ heap->compression = xar->opt_compression;
+ /* Get a extracted sumcheck value. */
+ checksum_update(&(xar->e_sumwrk), value, size);
+ checksum_final(&(xar->e_sumwrk), &(heap->e_sum));
+
+ /*
+ * Not compression to xattr is simple way.
+ */
+ if (heap->compression == NONE) {
+ checksum_update(&(xar->a_sumwrk), value, size);
+ checksum_final(&(xar->a_sumwrk), &(heap->a_sum));
+ if (write_to_temp(a, value, size)
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ heap->length = size;
+ /* Add heap to the tail of file->xattr. */
+ heap->next = NULL;
+ *file->xattr.last = heap;
+ file->xattr.last = &(heap->next);
+ /* Next xattr */
+ continue;
+ }
+
+ /*
+ * Init compression library.
+ */
+ r = xar_compression_init_encoder(a);
+ if (r != ARCHIVE_OK) {
+ free(heap);
+ return (ARCHIVE_FATAL);
+ }
+
+ xar->stream.next_in = (const unsigned char *)value;
+ xar->stream.avail_in = size;
+ for (;;) {
+ r = compression_code(&(a->archive),
+ &(xar->stream), ARCHIVE_Z_FINISH);
+ if (r != ARCHIVE_OK && r != ARCHIVE_EOF) {
+ free(heap);
+ return (ARCHIVE_FATAL);
+ }
+ size = sizeof(xar->wbuff) - xar->stream.avail_out;
+ checksum_update(&(xar->a_sumwrk),
+ xar->wbuff, size);
+ if (write_to_temp(a, xar->wbuff, size)
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ if (r == ARCHIVE_OK) {
+ xar->stream.next_out = xar->wbuff;
+ xar->stream.avail_out = sizeof(xar->wbuff);
+ } else {
+ checksum_final(&(xar->a_sumwrk),
+ &(heap->a_sum));
+ heap->length = xar->stream.total_out;
+ /* Add heap to the tail of file->xattr. */
+ heap->next = NULL;
+ *file->xattr.last = heap;
+ file->xattr.last = &(heap->next);
+ break;
+ }
+ }
+ /* Clean up compression library. */
+ r = compression_end(&(a->archive), &(xar->stream));
+ if (r != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+getalgsize(enum sumalg sumalg)
+{
+ switch (sumalg) {
+ default:
+ case CKSUM_NONE:
+ return (0);
+ case CKSUM_SHA1:
+ return (SHA1_SIZE);
+ case CKSUM_MD5:
+ return (MD5_SIZE);
+ }
+}
+
+static const char *
+getalgname(enum sumalg sumalg)
+{
+ switch (sumalg) {
+ default:
+ case CKSUM_NONE:
+ return (NULL);
+ case CKSUM_SHA1:
+ return (SHA1_NAME);
+ case CKSUM_MD5:
+ return (MD5_NAME);
+ }
+}
+
+#endif /* Support xar format */
+
diff --git a/libarchive/archive_write_set_format_zip.c b/libarchive/archive_write_set_format_zip.c
index 201152f3a9e7..f07a14f47f5a 100644
--- a/libarchive/archive_write_set_format_zip.c
+++ b/libarchive/archive_write_set_format_zip.c
@@ -1,6 +1,7 @@
/*-
* Copyright (c) 2008 Anselm Strauss
* Copyright (c) 2009 Joerg Sonnenberger
+ * Copyright (c) 2011 Michihiro NAKAJIMA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -52,7 +53,9 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_zip.c 201168 20
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
-#include <stdio.h>
+#ifdef HAVE_LANGINFO_H
+#include <langinfo.h>
+#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
@@ -66,6 +69,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_zip.c 201168 20
#include "archive.h"
#include "archive_endian.h"
#include "archive_entry.h"
+#include "archive_entry_locale.h"
#include "archive_private.h"
#include "archive_write_private.h"
@@ -78,10 +82,11 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_zip.c 201168 20
#define ZIP_SIGNATURE_FILE_HEADER 0x02014b50
#define ZIP_SIGNATURE_CENTRAL_DIRECTORY_END 0x06054b50
#define ZIP_SIGNATURE_EXTRA_TIMESTAMP 0x5455
-#define ZIP_SIGNATURE_EXTRA_UNIX 0x7855
+#define ZIP_SIGNATURE_EXTRA_NEW_UNIX 0x7875
#define ZIP_VERSION_EXTRACT 0x0014 /* ZIP version 2.0 is needed. */
#define ZIP_VERSION_BY 0x0314 /* Made by UNIX, using ZIP version 2.0. */
#define ZIP_FLAGS 0x08 /* Flagging bit 3 (count from 0) for using data descriptor. */
+#define ZIP_FLAGS_UTF8_NAME (1 << 11)
enum compression {
COMPRESSION_STORE = 0
@@ -91,11 +96,15 @@ enum compression {
#endif
};
-static ssize_t archive_write_zip_data(struct archive_write *, const void *buff, size_t s);
-static int archive_write_zip_finish(struct archive_write *);
-static int archive_write_zip_destroy(struct archive_write *);
+static ssize_t archive_write_zip_data(struct archive_write *,
+ const void *buff, size_t s);
+static int archive_write_zip_close(struct archive_write *);
+static int archive_write_zip_free(struct archive_write *);
static int archive_write_zip_finish_entry(struct archive_write *);
-static int archive_write_zip_header(struct archive_write *, struct archive_entry *);
+static int archive_write_zip_header(struct archive_write *,
+ struct archive_entry *);
+static int archive_write_zip_options(struct archive_write *,
+ const char *, const char *);
static unsigned int dos_time(const time_t);
static size_t path_length(struct archive_entry *);
static int write_path(struct archive_entry *, struct archive_write *);
@@ -148,8 +157,11 @@ struct zip_extra_data_local {
char ctime[4];
char unix_id[2];
char unix_size[2];
- char unix_uid[2];
- char unix_gid[2];
+ char unix_version;
+ char unix_uid_size;
+ char unix_uid[4];
+ char unix_gid_size;
+ char unix_gid[4];
};
struct zip_extra_data_central {
@@ -164,10 +176,11 @@ struct zip_extra_data_central {
struct zip_file_header_link {
struct zip_file_header_link *next;
struct archive_entry *entry;
- off_t offset;
+ int64_t offset;
unsigned long crc32;
- off_t compressed_size;
+ int64_t compressed_size;
enum compression compression;
+ int flags;
};
struct zip {
@@ -178,6 +191,10 @@ struct zip {
int64_t written_bytes;
int64_t remaining_data_bytes;
enum compression compression;
+ int flags;
+ struct archive_string_conv *opt_sconv;
+ struct archive_string_conv *sconv_default;
+ int init_default_conversion;
#ifdef HAVE_ZLIB_H
z_stream stream;
@@ -199,26 +216,45 @@ struct zip_central_directory_end {
static int
archive_write_zip_options(struct archive_write *a, const char *key,
- const char *value)
+ const char *val)
{
struct zip *zip = a->format_data;
+ int ret = ARCHIVE_FAILED;
if (strcmp(key, "compression") == 0) {
- if (strcmp(value, "deflate") == 0) {
+ if (val == NULL || val[0] == 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "%s: compression option needs a compression name",
+ a->format_name);
+ } else if (strcmp(val, "deflate") == 0) {
#ifdef HAVE_ZLIB_H
zip->compression = COMPRESSION_DEFLATE;
+ ret = ARCHIVE_OK;
#else
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"deflate compression not supported");
- return ARCHIVE_WARN;
#endif
- } else if (strcmp(value, "store") == 0)
+ } else if (strcmp(val, "store") == 0) {
zip->compression = COMPRESSION_STORE;
- else
- return (ARCHIVE_WARN);
- return (ARCHIVE_OK);
- }
- return (ARCHIVE_WARN);
+ ret = ARCHIVE_OK;
+ }
+ } else if (strcmp(key, "hdrcharset") == 0) {
+ if (val == NULL || val[0] == 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "%s: hdrcharset option needs a character-set name",
+ a->format_name);
+ } else {
+ zip->opt_sconv = archive_string_conversion_to_charset(
+ &a->archive, val, 0);
+ if (zip->opt_sconv != NULL)
+ ret = ARCHIVE_OK;
+ else
+ ret = ARCHIVE_FATAL;
+ }
+ } else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "%s: unknown keyword ``%s''", a->format_name, key);
+ return (ret);
}
int
@@ -227,13 +263,17 @@ archive_write_set_format_zip(struct archive *_a)
struct archive_write *a = (struct archive_write *)_a;
struct zip *zip;
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_zip");
+
/* If another format was already registered, unregister it. */
- if (a->format_destroy != NULL)
- (a->format_destroy)(a);
+ if (a->format_free != NULL)
+ (a->format_free)(a);
zip = (struct zip *) calloc(1, sizeof(*zip));
if (zip == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Can't allocate zip data");
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate zip data");
return (ARCHIVE_FATAL);
}
zip->central_directory = NULL;
@@ -247,7 +287,8 @@ archive_write_set_format_zip(struct archive *_a)
zip->len_buf = 65536;
zip->buf = malloc(zip->len_buf);
if (zip->buf == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Can't allocate compression buffer");
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate compression buffer");
return (ARCHIVE_FATAL);
}
#else
@@ -255,15 +296,13 @@ archive_write_set_format_zip(struct archive *_a)
#endif
a->format_data = zip;
-
- a->pad_uncompressed = 0; /* Actually not needed for now, since no compression support yet. */
a->format_name = "zip";
a->format_options = archive_write_zip_options;
a->format_write_header = archive_write_zip_header;
a->format_write_data = archive_write_zip_data;
a->format_finish_entry = archive_write_zip_finish_entry;
- a->format_finish = archive_write_zip_finish;
- a->format_destroy = archive_write_zip_destroy;
+ a->format_close = archive_write_zip_close;
+ a->format_free = archive_write_zip_free;
a->archive.archive_format = ARCHIVE_FORMAT_ZIP;
a->archive.archive_format_name = "ZIP";
@@ -274,6 +313,18 @@ archive_write_set_format_zip(struct archive *_a)
}
static int
+is_all_ascii(const char *p)
+{
+ const unsigned char *pp = (const unsigned char *)p;
+
+ while (*pp) {
+ if (*pp++ > 127)
+ return (0);
+ }
+ return (1);
+}
+
+static int
archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
{
struct zip *zip;
@@ -281,22 +332,44 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
struct zip_extra_data_local e;
struct zip_data_descriptor *d;
struct zip_file_header_link *l;
- int ret;
+ struct archive_string_conv *sconv;
+ int ret, ret2 = ARCHIVE_OK;
int64_t size;
mode_t type;
/* Entries other than a regular file or a folder are skipped. */
type = archive_entry_filetype(entry);
- if ((type != AE_IFREG) & (type != AE_IFDIR)) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Filetype not supported");
+ if (type != AE_IFREG && type != AE_IFDIR && type != AE_IFLNK) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Filetype not supported");
return ARCHIVE_FAILED;
- };
+ };
/* Directory entries should have a size of 0. */
if (type == AE_IFDIR)
archive_entry_set_size(entry, 0);
zip = a->format_data;
+ /* Setup default conversion. */
+ if (zip->opt_sconv == NULL && !zip->init_default_conversion) {
+ zip->sconv_default =
+ archive_string_default_conversion_for_write(&(a->archive));
+ zip->init_default_conversion = 1;
+ }
+
+ if (zip->flags == 0) {
+ /* Initialize the general purpose flags. */
+ zip->flags = ZIP_FLAGS;
+ if (zip->opt_sconv != NULL) {
+ if (strcmp(archive_string_conversion_charset_name(
+ zip->opt_sconv), "UTF-8") == 0)
+ zip->flags |= ZIP_FLAGS_UTF8_NAME;
+#if HAVE_NL_LANGINFO
+ } else if (strcmp(nl_langinfo(CODESET), "UTF-8") == 0) {
+ zip->flags |= ZIP_FLAGS_UTF8_NAME;
+#endif
+ }
+ }
d = &zip->data_descriptor;
size = archive_entry_size(entry);
zip->remaining_data_bytes = size;
@@ -304,14 +377,57 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
/* Append archive entry to the central directory data. */
l = (struct zip_file_header_link *) malloc(sizeof(*l));
if (l == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Can't allocate zip header data");
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate zip header data");
return (ARCHIVE_FATAL);
}
l->entry = archive_entry_clone(entry);
+ l->flags = zip->flags;
+ if (zip->opt_sconv != NULL)
+ sconv = zip->opt_sconv;
+ else
+ sconv = zip->sconv_default;
+ if (sconv != NULL) {
+ const char *p;
+ size_t len;
+
+ if (archive_entry_pathname_l(entry, &p, &len, sconv) != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate pathname '%s' to %s",
+ archive_entry_pathname(entry),
+ archive_string_conversion_charset_name(sconv));
+ ret2 = ARCHIVE_WARN;
+ }
+ if (len > 0)
+ archive_entry_set_pathname(l->entry, p);
+ }
+ /* If all character of a filename is ASCII, Reset UTF-8 Name flag. */
+ if ((l->flags & ZIP_FLAGS_UTF8_NAME) != 0 &&
+ is_all_ascii(archive_entry_pathname(l->entry)))
+ l->flags &= ~ZIP_FLAGS_UTF8_NAME;
+
/* Initialize the CRC variable and potentially the local crc32(). */
l->crc32 = crc32(0, NULL, 0);
- l->compression = zip->compression;
- l->compressed_size = 0;
+ if (type == AE_IFLNK) {
+ const char *p = archive_entry_symlink(l->entry);
+ if (p != NULL)
+ size = strlen(p);
+ else
+ size = 0;
+ zip->remaining_data_bytes = 0;
+ archive_entry_set_size(l->entry, size);
+ l->compression = COMPRESSION_STORE;
+ l->compressed_size = size;
+ } else {
+ l->compression = zip->compression;
+ l->compressed_size = 0;
+ }
l->next = NULL;
if (zip->central_directory == NULL) {
zip->central_directory = l;
@@ -320,22 +436,24 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
}
zip->central_directory_end = l;
- /* Store the offset of this header for later use in central directory. */
+ /* Store the offset of this header for later use in central
+ * directory. */
l->offset = zip->written_bytes;
memset(&h, 0, sizeof(h));
archive_le32enc(&h.signature, ZIP_SIGNATURE_LOCAL_FILE_HEADER);
archive_le16enc(&h.version, ZIP_VERSION_EXTRACT);
- archive_le16enc(&h.flags, ZIP_FLAGS);
- archive_le16enc(&h.compression, zip->compression);
+ archive_le16enc(&h.flags, l->flags);
+ archive_le16enc(&h.compression, l->compression);
archive_le32enc(&h.timedate, dos_time(archive_entry_mtime(entry)));
- archive_le16enc(&h.filename_length, (uint16_t)path_length(entry));
+ archive_le16enc(&h.filename_length, (uint16_t)path_length(l->entry));
- switch (zip->compression) {
+ switch (l->compression) {
case COMPRESSION_STORE:
- /* Setting compressed and uncompressed sizes even when specification says
- * to set to zero when using data descriptors. Otherwise the end of the
- * data for an entry is rather difficult to find. */
+ /* Setting compressed and uncompressed sizes even when
+ * specification says to set to zero when using data
+ * descriptors. Otherwise the end of the data for an
+ * entry is rather difficult to find. */
archive_le32enc(&h.compressed_size, size);
archive_le32enc(&h.uncompressed_size, size);
break;
@@ -348,9 +466,10 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
zip->stream.opaque = Z_NULL;
zip->stream.next_out = zip->buf;
zip->stream.avail_out = zip->len_buf;
- if (deflateInit2(&zip->stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
- -15, 8, Z_DEFAULT_STRATEGY) != Z_OK) {
- archive_set_error(&a->archive, ENOMEM, "Can't init deflate compressor");
+ if (deflateInit2(&zip->stream, Z_DEFAULT_COMPRESSION,
+ Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY) != Z_OK) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't init deflate compressor");
return (ARCHIVE_FATAL);
}
break;
@@ -366,29 +485,47 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
archive_le32enc(&e.mtime, archive_entry_mtime(entry));
archive_le32enc(&e.atime, archive_entry_atime(entry));
archive_le32enc(&e.ctime, archive_entry_ctime(entry));
-
- archive_le16enc(&e.unix_id, ZIP_SIGNATURE_EXTRA_UNIX);
- archive_le16enc(&e.unix_size, sizeof(e.unix_uid) + sizeof(e.unix_gid));
- archive_le16enc(&e.unix_uid, archive_entry_uid(entry));
- archive_le16enc(&e.unix_gid, archive_entry_gid(entry));
+
+ archive_le16enc(&e.unix_id, ZIP_SIGNATURE_EXTRA_NEW_UNIX);
+ archive_le16enc(&e.unix_size, sizeof(e.unix_version) +
+ sizeof(e.unix_uid_size) + sizeof(e.unix_uid) +
+ sizeof(e.unix_gid_size) + sizeof(e.unix_gid));
+ e.unix_version = 1;
+ e.unix_uid_size = 4;
+ archive_le32enc(&e.unix_uid, archive_entry_uid(entry));
+ e.unix_gid_size = 4;
+ archive_le32enc(&e.unix_gid, archive_entry_gid(entry));
archive_le32enc(&d->uncompressed_size, size);
- ret = (a->compressor.write)(a, &h, sizeof(h));
+ ret = __archive_write_output(a, &h, sizeof(h));
if (ret != ARCHIVE_OK)
return (ARCHIVE_FATAL);
zip->written_bytes += sizeof(h);
- ret = write_path(entry, a);
+ ret = write_path(l->entry, a);
if (ret <= ARCHIVE_OK)
return (ARCHIVE_FATAL);
zip->written_bytes += ret;
- ret = (a->compressor.write)(a, &e, sizeof(e));
+ ret = __archive_write_output(a, &e, sizeof(e));
if (ret != ARCHIVE_OK)
return (ARCHIVE_FATAL);
zip->written_bytes += sizeof(e);
+ if (type == AE_IFLNK) {
+ const unsigned char *p;
+
+ p = (const unsigned char *)archive_entry_symlink(l->entry);
+ ret = __archive_write_output(a, p, size);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ zip->written_bytes += size;
+ l->crc32 = crc32(l->crc32, p, size);
+ }
+
+ if (ret2 != ARCHIVE_OK)
+ return (ret2);
return (ARCHIVE_OK);
}
@@ -404,9 +541,9 @@ archive_write_zip_data(struct archive_write *a, const void *buff, size_t s)
if (s == 0) return 0;
- switch (zip->compression) {
+ switch (l->compression) {
case COMPRESSION_STORE:
- ret = (a->compressor.write)(a, buff, s);
+ ret = __archive_write_output(a, buff, s);
if (ret != ARCHIVE_OK) return (ret);
zip->written_bytes += s;
zip->remaining_data_bytes -= s;
@@ -422,7 +559,8 @@ archive_write_zip_data(struct archive_write *a, const void *buff, size_t s)
if (ret == Z_STREAM_ERROR)
return (ARCHIVE_FATAL);
if (zip->stream.avail_out == 0) {
- ret = (a->compressor.write)(a, zip->buf, zip->len_buf);
+ ret = __archive_write_output(a, zip->buf,
+ zip->len_buf);
if (ret != ARCHIVE_OK)
return (ret);
l->compressed_size += zip->len_buf;
@@ -456,7 +594,7 @@ archive_write_zip_finish_entry(struct archive_write *a)
size_t reminder;
#endif
- switch(zip->compression) {
+ switch(l->compression) {
case COMPRESSION_STORE:
break;
#if HAVE_ZLIB_H
@@ -466,7 +604,7 @@ archive_write_zip_finish_entry(struct archive_write *a)
if (ret == Z_STREAM_ERROR)
return (ARCHIVE_FATAL);
reminder = zip->len_buf - zip->stream.avail_out;
- ret = (a->compressor.write)(a, zip->buf, reminder);
+ ret = __archive_write_output(a, zip->buf, reminder);
if (ret != ARCHIVE_OK)
return (ret);
l->compressed_size += reminder;
@@ -483,7 +621,7 @@ archive_write_zip_finish_entry(struct archive_write *a)
archive_le32enc(&d->crc32, l->crc32);
archive_le32enc(&d->compressed_size, l->compressed_size);
- ret = (a->compressor.write)(a, d, sizeof(*d));
+ ret = __archive_write_output(a, d, sizeof(*d));
if (ret != ARCHIVE_OK)
return (ARCHIVE_FATAL);
zip->written_bytes += sizeof(*d);
@@ -491,25 +629,23 @@ archive_write_zip_finish_entry(struct archive_write *a)
}
static int
-archive_write_zip_finish(struct archive_write *a)
+archive_write_zip_close(struct archive_write *a)
{
struct zip *zip;
struct zip_file_header_link *l;
struct zip_file_header h;
struct zip_central_directory_end end;
struct zip_extra_data_central e;
- off_t offset_start, offset_end;
+ int64_t offset_start, offset_end;
int entries;
int ret;
- if (a->compressor.write == NULL)
- return (ARCHIVE_OK);
-
zip = a->format_data;
l = zip->central_directory;
/*
- * Formatting central directory file header fields that are fixed for all entries.
+ * Formatting central directory file header fields that are
+ * fixed for all entries.
* Fields not used (and therefor 0) are:
*
* - comment_length
@@ -520,7 +656,6 @@ archive_write_zip_finish(struct archive_write *a)
archive_le32enc(&h.signature, ZIP_SIGNATURE_FILE_HEADER);
archive_le16enc(&h.version_by, ZIP_VERSION_BY);
archive_le16enc(&h.version_extract, ZIP_VERSION_EXTRACT);
- archive_le16enc(&h.flags, ZIP_FLAGS);
entries = 0;
offset_start = zip->written_bytes;
@@ -528,25 +663,31 @@ archive_write_zip_finish(struct archive_write *a)
/* Formatting individual header fields per entry and
* writing each entry. */
while (l != NULL) {
+ archive_le16enc(&h.flags, l->flags);
archive_le16enc(&h.compression, l->compression);
- archive_le32enc(&h.timedate, dos_time(archive_entry_mtime(l->entry)));
+ archive_le32enc(&h.timedate,
+ dos_time(archive_entry_mtime(l->entry)));
archive_le32enc(&h.crc32, l->crc32);
archive_le32enc(&h.compressed_size, l->compressed_size);
- archive_le32enc(&h.uncompressed_size, archive_entry_size(l->entry));
- archive_le16enc(&h.filename_length, (uint16_t)path_length(l->entry));
+ archive_le32enc(&h.uncompressed_size,
+ archive_entry_size(l->entry));
+ archive_le16enc(&h.filename_length,
+ (uint16_t)path_length(l->entry));
archive_le16enc(&h.extra_length, sizeof(e));
- archive_le16enc(&h.attributes_external[2], archive_entry_mode(l->entry));
+ archive_le16enc(&h.attributes_external[2],
+ archive_entry_mode(l->entry));
archive_le32enc(&h.offset, l->offset);
/* Formatting extra data. */
archive_le16enc(&e.time_id, ZIP_SIGNATURE_EXTRA_TIMESTAMP);
- archive_le16enc(&e.time_size, sizeof(e.mtime) + sizeof(e.time_flag));
+ archive_le16enc(&e.time_size,
+ sizeof(e.mtime) + sizeof(e.time_flag));
e.time_flag[0] = 0x07;
archive_le32enc(&e.mtime, archive_entry_mtime(l->entry));
- archive_le16enc(&e.unix_id, ZIP_SIGNATURE_EXTRA_UNIX);
+ archive_le16enc(&e.unix_id, ZIP_SIGNATURE_EXTRA_NEW_UNIX);
archive_le16enc(&e.unix_size, 0x0000);
- ret = (a->compressor.write)(a, &h, sizeof(h));
+ ret = __archive_write_output(a, &h, sizeof(h));
if (ret != ARCHIVE_OK)
return (ARCHIVE_FATAL);
zip->written_bytes += sizeof(h);
@@ -556,7 +697,7 @@ archive_write_zip_finish(struct archive_write *a)
return (ARCHIVE_FATAL);
zip->written_bytes += ret;
- ret = (a->compressor.write)(a, &e, sizeof(e));
+ ret = __archive_write_output(a, &e, sizeof(e));
if (ret != ARCHIVE_OK)
return (ARCHIVE_FATAL);
zip->written_bytes += sizeof(e);
@@ -575,7 +716,7 @@ archive_write_zip_finish(struct archive_write *a)
archive_le32enc(&end.offset, offset_start);
/* Writing end of central directory. */
- ret = (a->compressor.write)(a, &end, sizeof(end));
+ ret = __archive_write_output(a, &end, sizeof(end));
if (ret != ARCHIVE_OK)
return (ARCHIVE_FATAL);
zip->written_bytes += sizeof(end);
@@ -583,7 +724,7 @@ archive_write_zip_finish(struct archive_write *a)
}
static int
-archive_write_zip_destroy(struct archive_write *a)
+archive_write_zip_free(struct archive_write *a)
{
struct zip *zip;
struct zip_file_header_link *l;
@@ -614,14 +755,23 @@ dos_time(const time_t unix_time)
* on two systems with different time zones. */
t = localtime(&unix_time);
- dt = 0;
- dt += ((t->tm_year - 80) & 0x7f) << 9;
- dt += ((t->tm_mon + 1) & 0x0f) << 5;
- dt += (t->tm_mday & 0x1f);
- dt <<= 16;
- dt += (t->tm_hour & 0x1f) << 11;
- dt += (t->tm_min & 0x3f) << 5;
- dt += (t->tm_sec & 0x3e) >> 1; /* Only counting every 2 seconds. */
+ /* MSDOS-style date/time is only between 1980-01-01 and 2107-12-31 */
+ if (t->tm_year < 1980 - 1900)
+ /* Set minimum date/time '1980-01-01 00:00:00'. */
+ dt = 0x00210000U;
+ else if (t->tm_year > 2107 - 1900)
+ /* Set maximum date/time '2107-12-31 23:59:58'. */
+ dt = 0xff9fbf7dU;
+ else {
+ dt = 0;
+ dt += ((t->tm_year - 80) & 0x7f) << 9;
+ dt += ((t->tm_mon + 1) & 0x0f) << 5;
+ dt += (t->tm_mday & 0x1f);
+ dt <<= 16;
+ dt += (t->tm_hour & 0x1f) << 11;
+ dt += (t->tm_min & 0x3f) << 5;
+ dt += (t->tm_sec & 0x3e) >> 1; /* Only counting every 2 seconds. */
+ }
return dt;
}
@@ -653,14 +803,14 @@ write_path(struct archive_entry *entry, struct archive_write *archive)
type = archive_entry_filetype(entry);
written_bytes = 0;
- ret = (archive->compressor.write)(archive, path, strlen(path));
+ ret = __archive_write_output(archive, path, strlen(path));
if (ret != ARCHIVE_OK)
return (ARCHIVE_FATAL);
written_bytes += strlen(path);
/* Folders are recognized by a traling slash. */
if ((type == AE_IFDIR) & (path[strlen(path) - 1] != '/')) {
- ret = (archive->compressor.write)(archive, "/", 1);
+ ret = __archive_write_output(archive, "/", 1);
if (ret != ARCHIVE_OK)
return (ARCHIVE_FATAL);
written_bytes += 1;
diff --git a/libarchive/archive_write_set_options.3 b/libarchive/archive_write_set_options.3
new file mode 100644
index 000000000000..9a8ea3dbf92c
--- /dev/null
+++ b/libarchive/archive_write_set_options.3
@@ -0,0 +1,437 @@
+.\" Copyright (c) 2003-2010 Tim Kientzle
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD: head/lib/libarchive/archive_write.3 201110 2009-12-28 03:31:29Z kientzle $
+.\"
+.Dd Feb 27, 2010
+.Dt ARCHIVE_WRITE_OPTIONS 3
+.Os
+.Sh NAME
+.Nm archive_write_set_filter_option ,
+.Nm archive_write_set_format_option ,
+.Nm archive_write_set_option ,
+.Nm archive_write_set_options
+.Nd functions controlling options for reading archives
+.Sh SYNOPSIS
+.\"
+.Sh SYNOPSIS
+.Ft int
+.Fo archive_write_set_filter_option
+.Fa "struct archive *"
+.Fa "const char *module"
+.Fa "const char *option"
+.Fa "const char *value"
+.Fc
+.Ft int
+.Fo archive_write_set_format_option
+.Fa "struct archive *"
+.Fa "const char *module"
+.Fa "const char *option"
+.Fa "const char *value"
+.Fc
+.Ft int
+.Fo archive_write_set_option
+.Fa "struct archive *"
+.Fa "const char *module"
+.Fa "const char *option"
+.Fa "const char *value"
+.Fc
+.Ft int
+.Fo archive_write_set_options
+.Fa "struct archive *"
+.Fa "const char *options"
+.Fc
+.Sh DESCRIPTION
+These functions provide a way for libarchive clients to configure
+specific write modules.
+.Bl -tag -width indent
+.It Xo
+.Fn archive_write_set_filter_option ,
+.Fn archive_write_set_format_option
+.Xc
+Specifies an option that will be passed to currently-registered
+filters (including decompression filters) or format readers.
+.Pp
+If
+.Ar option
+and
+.Ar value
+are both
+.Dv NULL ,
+these functions will do nothing and
+.Cm ARCHIVE_OK
+will be returned.
+If
+.Ar option
+is
+.Dv NULL
+but
+.Ar value
+is not, these functions will do nothing and
+.Cm ARCHIVE_FAILED
+will be returned.
+.Pp
+If
+.Ar module
+is not
+.Dv NULL ,
+.Ar option
+and
+.Ar value
+will be provided to the filter or reader named
+.Ar module .
+The return value will be that of the module.
+If there is no such module,
+.Cm ARCHIVE_FAILED
+will be returned.
+.Pp
+If
+.Ar module
+is
+.Dv NULL ,
+.Ar option
+and
+.Ar value
+will be provided to every registered module.
+If any module returns
+.Cm ARCHIVE_FATAL ,
+this value will be returned immediately.
+Otherwise,
+.Cm ARCHIVE_OK
+will be returned if any module accepts the option, and
+.Cm ARCHIVE_FAILED
+in all other cases.
+.\"
+.It Xo
+.Fn archive_write_set_option
+.Xc
+Calls
+.Fn archive_write_set_format_option ,
+then
+.Fn archive_write_set_filter_option .
+If either function returns
+.Cm ARCHIVE_FATAL ,
+.Cm ARCHIVE_FATAL
+will be returned
+immediately.
+Otherwise, greater of the two values will be returned.
+.\"
+.It Xo
+.Fn archive_write_set_options
+.Xc
+.Ar options
+is a comma-separated list of options.
+If
+.Ar options
+is
+.Dv NULL
+or empty,
+.Cm ARCHIVE_OK
+will be returned immediately.
+.Pp
+Individual options have one of the following forms:
+.Bl -tag -compact -width indent
+.It Ar option=value
+The option/value pair will be provided to every module.
+Modules that do not accept an option with this name will ignore it.
+.It Ar option
+The option will be provided to every module with a value of
+.Dq 1 .
+.It Ar !option
+The option will be provided to every module with a NULL value.
+.It Ar module:option=value , Ar module:option , Ar module:!option
+As above, but the corresponding option and value will be provided
+only to modules whose name matches
+.Ar module .
+.El
+.El
+.\"
+.Sh OPTIONS
+.Bl -tag -compact -width indent
+.It Filter gzip
+.Bl -tag -compact -width indent
+.It Cm compression-level
+The value is interpreted as a decimal integer specifying the
+gzip compression level.
+.El
+.It Filter xz
+.Bl -tag -compact -width indent
+.It Cm compression-level
+The value is interpreted as a decimal integer specifying the
+compression level.
+.El
+.It Format mtree
+.Bl -tag -compact -width indent
+.It Cm cksum , Cm device , Cm flags , Cm gid , Cm gname , Cm indent , Cm link , Cm md5 , Cm mode , Cm nlink , Cm rmd160 , Cm sha1 , Cm sha256 , Cm sha384 , Cm sha512 , Cm size , Cm time , Cm uid , Cm uname
+Enable a particular keyword in the mtree output.
+Prefix with an exclamation mark to disable the corresponding keyword.
+The default is equivalent to
+.Dq device, flags, gid, gname, link, mode, nlink, size, time, type, uid, uname .
+.It Cm all
+Enables all of the above keywords.
+.It Cm use-set
+Enables generation of
+.Cm /set
+lines that specify default values for the following files and/or directories.
+.It Cm indent
+XXX needs explanation XXX
+.El
+.It Format iso9660 - volume metadata
+These options are used to set standard ISO9660 metadata.
+.Bl -tag -compact -width indent
+.It Cm abstract-file Ns = Ns Ar filename
+The file with the specified name will be identified in the ISO9660 metadata
+as holding the abstract for this volume. Default: none.
+.It Cm application-id Ns = Ns Ar filename
+The file with the specified name will be identified in the ISO9660 metadata
+as holding the application identifier for this volume. Default: none.
+.It Cm biblio-file Ns = Ns Ar filename
+The file with the specified name will be identified in the ISO9660 metadata
+as holding the bibliography for this volume. Default: none.
+.It Cm copyright-file Ns = Ns Ar filename
+The file with the specified name will be identified in the ISO9660 metadata
+as holding the copyright for this volume. Default: none.
+.It Cm publisher Ns = Ns Ar filename
+The file with the specified name will be identified in the ISO9660 metadata
+as holding the publisher information for this volume. Default: none.
+.It Cm volume-id Ns = Ns Ar string
+The specified string will be used as the Volume Identifier in the ISO9660 metadata.
+It is limited to 32 bytes. Default: none.
+.El
+.It Format iso9660 - boot support
+These options are used to make an ISO9660 image that can be directly
+booted on various systems.
+.Bl -tag -compact -width indent
+.It Cm boot Ns = Ns Ar filename
+The file matching this name will be used as the El Torito boot image file.
+.It Cm boot-catalog Ns = Ns Ar name
+The name that will be used for the El Torito boot catalog.
+Default:
+.Ar boot.catalog
+.It Cm boot-info-table
+The boot image file provided by the
+.Cm boot Ns = Ns Ar filename
+option will be edited with appropriate boot information in bytes 8 through 64.
+Default: disabled
+.It Cm boot-load-seg Ns = Ns Ar hexadecimal-number
+The load segment for a no-emulation boot image.
+.It Cm boot-load-size Ns = Ns Ar decimal-number
+The number of "virtual" 512-byte sectors to be loaded from a no-emulation boot image.
+Some very old BIOSes can only load very small images, setting this
+value to 4 will often allow such BIOSes to load the first part of
+the boot image (which will then need to be intelligent enough to
+load the rest of itself).
+This should not be needed unless you are trying to support systems with very old BIOSes.
+This defaults to the full size of the image.
+.It Cm boot-type Ns = Ns Ar value
+Specifies the boot semantics used by the El Torito boot image:
+If the
+.Ar value
+is
+.Cm fd ,
+then the boot image is assumed to be a bootable floppy image.
+If the
+.Ar value
+is
+.Cm hd ,
+then the the boot image is assumed to be a bootable hard disk image.
+If the
+.Ar value
+is
+.Cm no-emulation ,
+the boot image is used without floppy or hard disk emulation.
+If the boot image is exactly 1.2MB, 1.44MB, or 2.88MB, then
+the default is
+.Cm fd ,
+otherwise the default is
+.Cm no-emulation.
+.El
+.It Format iso9660 - filename and size extensions
+Various extensions to the base ISO9660 format.
+.Bl -tag -compact -width indent
+.It Cm allow-ldots
+If enabled, allows filenames to begin with a leading period.
+If disabled, filenames that begin with a leading period will have
+that period replaced by an underscore character in the standard ISO9660
+namespace.
+This does not impact names stored in the Rockridge or Joliet extension area.
+Default: disabled.
+.It Cm allow-lowercase
+If enabled, allows filenames to contain lowercase characters.
+If disabled, filenames will be forced to uppercase.
+This does not impact names stored in the Rockridge or Joliet extension area.
+Default: disabled.
+.It Cm allow-multidot
+If enabled, allows filenames to contain multiple period characters, in violation of the ISO9660 specification.
+If disabled, additional periods will be converted to underscore characters.
+This does not impact names stored in the Rockridge or Joliet extension area.
+Default: disabled.
+.It Cm allow-period
+If enabled, allows filenames to contain trailing period characters, in violation of the ISO9660 specification.
+If disabled,trailing periods will be converted to underscore characters.
+This does not impact names stored in the Rockridge or Joliet extension area.
+Default: disabled.
+.It Cm allow-pvd-lowercase
+If enabled, the Primary Volume Descriptor may contain lowercase ASCII characters, in violation of the ISO9660 specification.
+If disabled, characters will be converted to uppercase ASCII.
+Default: disabled.
+.It Cm allow-sharp-tilde
+If enabled, sharp and tilde characters will be permitted in filenames, in violation if the ISO9660 specification.
+If disabled, such characters will be converted to underscore characters.
+Default: disabled.
+.It Cm allow-vernum
+If enabled, version numbers will be included with files.
+If disabled, version numbers will be suppressed, in violation of the ISO9660 standard.
+This does not impact names stored in the Rockridge or Joliet extension area.
+Default: enabled.
+.It Cm iso-level
+This enables support for file size and file name extensions in the
+core ISO9660 area.
+The name extensions specified here do not affect the names stored in the Rockridge or Joliet extension areas.
+.Bl -tag -compact -width indent
+.It Cm iso-level=1
+The most compliant form of ISO9660 image.
+Filenames are limited to 8.3 uppercase format,
+directory names are limited to 8 uppercase characters,
+files are limited to 4 GiB,
+the complete ISO9660 image cannot exceed 4 GiB.
+.It Cm iso-level=2
+Filenames are limited to 30 uppercase characters with a 30-character extension,
+directory names are limited to 30 characters,
+files are limited to 4 GiB.
+.It Cm iso-level=3
+As with
+.Cm iso-level=2 ,
+except that files may exceed 4 GiB.
+.It Cm iso-level=4
+As with
+.Cm iso-level=3 ,
+except that filenames may be up to 193 characters
+and may include arbitrary 8-bit characters.
+.El
+.It Cm joliet
+Microsoft's Joliet extensions store a completely separate set of directory information about each file.
+In particular, this information includes Unicode filenames of up to 255 characters.
+Default: enabled.
+.It Cm limit-depth
+If enabled, libarchive will use directory relocation records to ensure that
+no pathname exceeds the ISO9660 limit of 8 directory levels.
+If disabled, no relocation will occur.
+Default: enabled.
+.It Cm limit-dirs
+If enabled, libarchive will cause an error if there are more than
+65536 directories.
+If disabled, there is no limit on the number of directories.
+Default: enabled
+.It Cm pad
+If enabled, 300 kiB of zero bytes will be appended to the end of the archive.
+Default: enabled
+.It Cm relaxed-filenames
+If enabled, all 7-bit ASCII characters are permitted in filenames
+(except lowercase characters unless
+.Cm allow-lowercase
+is also specified).
+This violates ISO9660 standards.
+This does not impact names stored in the Rockridge or Joliet extension area.
+Default: disabled.
+.It Cm rockridge
+The Rockridge extensions store an additional set of POSIX-style file
+information with each file, including mtime, atime, ctime, permissions,
+and long filenames with arbitrary 8-bit characters.
+These extensions also support symbolic links and other POSIX file types.
+Default: enabled.
+.El
+.It Format iso9660 - zisofs support
+The zisofs extensions permit each file to be independently compressed
+using a gzip-compatible compression.
+This can provide significant size savings, but requires the reading
+system to have support for these extensions.
+These extensions are disabled by default.
+.Bl -tag -compact -width indent
+.It Cm compression-level Ns = Ns number
+The compression level used by the deflate compressor.
+Ranges from 0 (least effort) to 9 (most effort).
+Default: 6
+.It Cm zisofs
+Synonym for
+.Cm zisofs=direct .
+.It Cm zisofs=direct
+Compress each file in the archive.
+Unlike
+.Cm zisofs=indirect ,
+this is handled entirely within libarchive and does not require a
+separate utility.
+For best results, libarchive tests each file and will store
+the file uncompressed if the compression does not actually save any space.
+In particular, files under 2k will never be compressed.
+Note that boot image files are never compressed.
+.It Cm zisofs=indirect
+Recognizes files that have already been compressed with the
+.Cm mkzftree
+utility and sets up the necessary file metadata so that
+readers will correctly identify these as zisofs-compressed files.
+.It Cm zisofs-exclude Ns = Ns Ar filename
+Specifies a filename that should not be compressed when using
+.Cm zisofs=direct .
+This option can be provided multiple times to suppress compression
+on many files.
+.El
+.El
+.Sh EXAMPLES
+The following example creates an archive write handle to
+create a gzip-compressed ISO9660 format image.
+The two options here specify that the ISO9660 archive will use
+.Ar kernel.img
+as the boot image for El Torito booting, and that the gzip
+compressor should use the maximum compression level.
+.Bd -literal -offset indent
+a = archive_write_new();
+archive_write_add_filter_gzip(a);
+archive_write_set_format_iso9660(a);
+archive_write_set_options(a, "boot=kernel.img,compression=9");
+archive_write_open_filename(a, filename, blocksize);
+.Ed
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.\"
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_read_set_options 3 ,
+.Xr archive_write 3
+.Sh HISTORY
+The
+.Nm libarchive
+library first appeared in
+.Fx 5.3 .
+.Sh AUTHORS
+.An -nosplit
+The options support for libarchive was originally implemented by
+.An Michihiro NAKAJIMA .
+.Sh BUGS
diff --git a/libarchive/archive_write_set_options.c b/libarchive/archive_write_set_options.c
new file mode 100644
index 000000000000..a8c2d23dd73d
--- /dev/null
+++ b/libarchive/archive_write_set_options.c
@@ -0,0 +1,124 @@
+/*-
+ * Copyright (c) 2003-2010 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+__FBSDID("$FreeBSD$");
+
+#include "archive_write_private.h"
+#include "archive_options_private.h"
+
+static int archive_set_format_option(struct archive *a,
+ const char *m, const char *o, const char *v);
+static int archive_set_filter_option(struct archive *a,
+ const char *m, const char *o, const char *v);
+static int archive_set_option(struct archive *a,
+ const char *m, const char *o, const char *v);
+
+int
+archive_write_set_format_option(struct archive *a, const char *m, const char *o,
+ const char *v)
+{
+ return _archive_set_option(a, m, o, v,
+ ARCHIVE_WRITE_MAGIC, "archive_write_set_format_option",
+ archive_set_format_option);
+}
+
+int
+archive_write_set_filter_option(struct archive *a, const char *m, const char *o,
+ const char *v)
+{
+ return _archive_set_option(a, m, o, v,
+ ARCHIVE_WRITE_MAGIC, "archive_write_set_filter_option",
+ archive_set_filter_option);
+}
+
+int
+archive_write_set_option(struct archive *a, const char *m, const char *o,
+ const char *v)
+{
+ return _archive_set_option(a, m, o, v,
+ ARCHIVE_WRITE_MAGIC, "archive_write_set_option",
+ archive_set_option);
+}
+
+int
+archive_write_set_options(struct archive *a, const char *options)
+{
+ return _archive_set_options(a, options,
+ ARCHIVE_WRITE_MAGIC, "archive_write_set_options",
+ archive_set_option);
+}
+
+static int
+archive_set_format_option(struct archive *_a, const char *m, const char *o,
+ const char *v)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+
+ if (a->format_name == NULL)
+ return (ARCHIVE_FAILED);
+ if (m != NULL && strcmp(m, a->format_name) != 0)
+ return (ARCHIVE_FAILED);
+ if (a->format_options == NULL)
+ return (ARCHIVE_FAILED);
+ return a->format_options(a, o, v);
+}
+
+static int
+archive_set_filter_option(struct archive *_a, const char *m, const char *o,
+ const char *v)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ struct archive_write_filter *filter;
+ int r, rv = ARCHIVE_FAILED;
+
+ for (filter = a->filter_first; filter != NULL; filter = filter->next_filter) {
+ if (filter->options == NULL)
+ continue;
+ if (m != NULL && strcmp(filter->name, m) != 0)
+ continue;
+
+ r = filter->options(filter, o, v);
+
+ if (r == ARCHIVE_FATAL)
+ return (ARCHIVE_FATAL);
+
+ if (m != NULL)
+ return (r);
+
+ if (r == ARCHIVE_OK)
+ rv = ARCHIVE_OK;
+ }
+ return (rv);
+}
+
+static int
+archive_set_option(struct archive *a, const char *m, const char *o,
+ const char *v)
+{
+ return _archive_set_either_option(a, m, o, v,
+ archive_set_format_option,
+ archive_set_filter_option);
+}
diff --git a/libarchive/config_freebsd.h b/libarchive/config_freebsd.h
index fad408714158..2073431635e9 100644
--- a/libarchive/config_freebsd.h
+++ b/libarchive/config_freebsd.h
@@ -77,7 +77,9 @@
#define HAVE_FTRUNCATE 1
#define HAVE_FUTIMES 1
#define HAVE_GETEUID 1
+#define HAVE_GETGRGID_R 1
#define HAVE_GETPID 1
+#define HAVE_GETPWUID_R 1
#define HAVE_GRP_H 1
#define HAVE_INTTYPES_H 1
#define HAVE_LCHFLAGS 1
@@ -121,14 +123,18 @@
#define HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC 1
#define HAVE_STRUCT_STAT_ST_FLAGS 1
#define HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC 1
+#define HAVE_STRUCT_TM_TM_GMTOFF 1
#define HAVE_SYMLINK 1
#define HAVE_SYS_CDEFS_H 1
#define HAVE_SYS_IOCTL_H 1
+#define HAVE_SYS_MOUNT_H 1
+#define HAVE_SYS_PARAM_H 1
#define HAVE_SYS_SELECT_H 1
#define HAVE_SYS_STAT_H 1
#define HAVE_SYS_TIME_H 1
#define HAVE_SYS_TYPES_H 1
#undef HAVE_SYS_UTIME_H
+#define HAVE_SYS_UTSNAME_H 1
#define HAVE_SYS_WAIT_H 1
#define HAVE_TIMEGM 1
#define HAVE_TZSET 1
diff --git a/libarchive/filter_fork_windows.c b/libarchive/filter_fork_windows.c
index 38b7097ee996..8d8beb01eb25 100644
--- a/libarchive/filter_fork_windows.c
+++ b/libarchive/filter_fork_windows.c
@@ -32,69 +32,73 @@
pid_t
__archive_create_child(const char *path, int *child_stdin, int *child_stdout)
{
- HANDLE childStdout[2], childStdin[2], childStdinWr, childStdoutRd;
+ HANDLE childStdout[2], childStdin[2],childStderr;
SECURITY_ATTRIBUTES secAtts;
STARTUPINFO staInfo;
PROCESS_INFORMATION childInfo;
char cmd[MAX_PATH];
- DWORD mode;
secAtts.nLength = sizeof(SECURITY_ATTRIBUTES);
secAtts.bInheritHandle = TRUE;
secAtts.lpSecurityDescriptor = NULL;
if (CreatePipe(&childStdout[0], &childStdout[1], &secAtts, 0) == 0)
goto fail;
- if (DuplicateHandle(GetCurrentProcess(), childStdout[0],
- GetCurrentProcess(), &childStdoutRd, 0, FALSE,
- DUPLICATE_SAME_ACCESS) == 0) {
+ if (!SetHandleInformation(childStdout[0], HANDLE_FLAG_INHERIT, 0))
+ {
CloseHandle(childStdout[0]);
CloseHandle(childStdout[1]);
goto fail;
}
- CloseHandle(childStdout[0]);
-
if (CreatePipe(&childStdin[0], &childStdin[1], &secAtts, 0) == 0) {
- CloseHandle(childStdoutRd);
+ CloseHandle(childStdout[0]);
CloseHandle(childStdout[1]);
goto fail;
}
-
- if (DuplicateHandle(GetCurrentProcess(), childStdin[1],
- GetCurrentProcess(), &childStdinWr, 0, FALSE,
+ if (!SetHandleInformation(childStdin[1], HANDLE_FLAG_INHERIT, 0))
+ {
+ CloseHandle(childStdout[0]);
+ CloseHandle(childStdout[1]);
+ CloseHandle(childStdin[0]);
+ CloseHandle(childStdin[1]);
+ goto fail;
+ }
+ if (DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_ERROR_HANDLE),
+ GetCurrentProcess(), &childStderr, 0, TRUE,
DUPLICATE_SAME_ACCESS) == 0) {
- CloseHandle(childStdoutRd);
+ CloseHandle(childStdout[0]);
CloseHandle(childStdout[1]);
CloseHandle(childStdin[0]);
CloseHandle(childStdin[1]);
goto fail;
}
- CloseHandle(childStdin[1]);
memset(&staInfo, 0, sizeof(staInfo));
staInfo.cb = sizeof(staInfo);
+ staInfo.hStdError = childStderr;
staInfo.hStdOutput = childStdout[1];
staInfo.hStdInput = childStdin[0];
staInfo.wShowWindow = SW_HIDE;
- staInfo.dwFlags = STARTF_USEFILLATTRIBUTE | STARTF_USECOUNTCHARS |
- STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
+ staInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
strncpy(cmd, path, sizeof(cmd)-1);
cmd[sizeof(cmd)-1] = '\0';
if (CreateProcessA(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL,
&staInfo, &childInfo) == 0) {
- CloseHandle(childStdoutRd);
+ CloseHandle(childStdout[0]);
CloseHandle(childStdout[1]);
CloseHandle(childStdin[0]);
- CloseHandle(childStdinWr);
+ CloseHandle(childStdin[1]);
+ CloseHandle(childStderr);
goto fail;
}
WaitForInputIdle(childInfo.hProcess, INFINITE);
CloseHandle(childInfo.hProcess);
CloseHandle(childInfo.hThread);
- mode = PIPE_NOWAIT;
- SetNamedPipeHandleState(childStdoutRd, &mode, NULL, NULL);
- *child_stdout = _open_osfhandle((intptr_t)childStdoutRd, _O_RDONLY);
- *child_stdin = _open_osfhandle((intptr_t)childStdinWr, _O_WRONLY);
+ *child_stdout = _open_osfhandle((intptr_t)childStdout[0], _O_RDONLY);
+ *child_stdin = _open_osfhandle((intptr_t)childStdin[1], _O_WRONLY);
+
+ CloseHandle(childStdout[1]);
+ CloseHandle(childStdin[0]);
return (childInfo.dwProcessId);
@@ -105,8 +109,8 @@ fail:
void
__archive_check_child(int in, int out)
{
- (void)in; /* UNSED */
- (void)out; /* UNSED */
+ (void)in; /* UNUSED */
+ (void)out; /* UNUSED */
Sleep(100);
}
diff --git a/libarchive/libarchive-formats.5 b/libarchive/libarchive-formats.5
index 0bc275b5189d..d223bf853013 100644
--- a/libarchive/libarchive-formats.5
+++ b/libarchive/libarchive-formats.5
@@ -342,6 +342,12 @@ using libarchive.
If it cannot locate and open the file on disk, libarchive
will return an error for any attempt to read the entry
body.
+.Ss RAR
+libarchive has limited support to read files in RAR format. Currently,
+libarchive can read single RAR files in RARv3 format which have been either
+created uncompressed, or compressed using any of the compression methods
+supported by the RARv3 format. libarchive can also extract RAR files which have
+been created as self-extracting RAR files.
.Sh SEE ALSO
.Xr ar 1 ,
.Xr cpio 1 ,
diff --git a/libarchive/libarchive.3 b/libarchive/libarchive.3
index bdab54b43dc1..d655404b8995 100644
--- a/libarchive/libarchive.3
+++ b/libarchive/libarchive.3
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD: src/lib/libarchive/libarchive.3,v 1.11 2007/01/09 08:05:56 kientzle Exp $
.\"
-.Dd July 17, 2010
+.Dd February 6, 2010
.Dt LIBARCHIVE 3
.Os
.Sh NAME
@@ -36,10 +36,13 @@
The
.Nm
library provides a flexible interface for reading and writing
-streaming archive files such as tar and cpio.
+archives in various formats such as tar and cpio.
+.Nm
+also supports reading and writing archives compressed using
+various compression filters such as gzip and bzip2.
The library is inherently stream-oriented; readers serially iterate through
the archive, writers serially add things to the archive.
-In particular, note that there is no built-in support for
+In particular, note that there is currently no built-in support for
random access nor for in-place modification.
.Pp
When reading an archive, the library automatically detects the
@@ -114,131 +117,15 @@ The rest of this manual page provides an overview of the library
operation.
More detailed information can be found in the individual manual
pages for each API or utility function.
+.\"
.Sh READING AN ARCHIVE
-To read an archive, you must first obtain an initialized
-.Tn struct archive
-object from
-.Fn archive_read_new .
-You can then modify this object for the desired operations with the
-various
-.Fn archive_read_set_XXX
-and
-.Fn archive_read_support_XXX
-functions.
-In particular, you will need to invoke appropriate
-.Fn archive_read_support_XXX
-functions to enable the corresponding compression and format
-support.
-Note that these latter functions perform two distinct operations:
-they cause the corresponding support code to be linked into your
-program, and they enable the corresponding auto-detect code.
-Unless you have specific constraints, you will generally want
-to invoke
-.Fn archive_read_support_compression_all
-and
-.Fn archive_read_support_format_all
-to enable auto-detect for all formats and compression types
-currently supported by the library.
-.Pp
-Once you have prepared the
-.Tn struct archive
-object, you call
-.Fn archive_read_open
-to actually open the archive and prepare it for reading.
-There are several variants of this function;
-the most basic expects you to provide pointers to several
-functions that can provide blocks of bytes from the archive.
-There are convenience forms that allow you to
-specify a filename, file descriptor,
-.Ft "FILE *"
-object, or a block of memory from which to read the archive data.
-Note that the core library makes no assumptions about the
-size of the blocks read;
-callback functions are free to read whatever block size is
-most appropriate for the medium.
-.Pp
-Each archive entry consists of a header followed by a certain
-amount of data.
-You can obtain the next header with
-.Fn archive_read_next_header ,
-which returns a pointer to an
-.Tn struct archive_entry
-structure with information about the current archive element.
-If the entry is a regular file, then the header will be followed
-by the file data.
-You can use
-.Fn archive_read_data
-(which works much like the
-.Xr read 2
-system call)
-to read this data from the archive, or
-.Fn archive_read_data_block
-which provides a slightly more efficient interface.
-You may prefer to use the higher-level
-.Fn archive_read_data_skip ,
-which reads and discards the data for this entry,
-.Fn archive_read_data_to_file ,
-which copies the data to the provided file descriptor, or
-.Fn archive_read_extract ,
-which recreates the specified entry on disk and copies data
-from the archive.
-In particular, note that
-.Fn archive_read_extract
-uses the
-.Tn struct archive_entry
-structure that you provide it, which may differ from the
-entry just read from the archive.
-In particular, many applications will want to override the
-pathname, file permissions, or ownership.
-.Pp
-Once you have finished reading data from the archive, you
-should call
-.Fn archive_read_close
-to close the archive, then call
-.Fn archive_read_free
-to release all resources, including all memory allocated by the library.
-.Pp
-The
-.Xr archive_read 3
-manual page provides more detailed calling information for this API.
+See
+.Xr libarchive_read 3 .
+.\"
.Sh WRITING AN ARCHIVE
-You use a similar process to write an archive.
-The
-.Fn archive_write_new
-function creates an archive object useful for writing,
-the various
-.Fn archive_write_set_XXX
-functions are used to set parameters for writing the archive, and
-.Fn archive_write_open
-completes the setup and opens the archive for writing.
-.Pp
-Individual archive entries are written in a three-step
-process:
-You first initialize a
-.Tn struct archive_entry
-structure with information about the new entry.
-At a minimum, you should set the pathname of the
-entry and provide a
-.Va struct stat
-with a valid
-.Va st_mode
-field, which specifies the type of object and
-.Va st_size
-field, which specifies the size of the data portion of the object.
-The
-.Fn archive_write_header
-function actually writes the header data to the archive.
-You can then use
-.Fn archive_write_data
-to write the actual data.
-.Pp
-After all entries have been written, use the
-.Fn archive_write_free
-function to release all resources.
-.Pp
-The
-.Xr archive_write 3
-manual page provides more detailed calling information for this API.
+See
+.Xr libarchive_write 3 .
+.\"
.Sh WRITING ENTRIES TO DISK
The
.Xr archive_write_disk 3
diff --git a/libarchive/libarchive_changes.3 b/libarchive/libarchive_changes.3
new file mode 100644
index 000000000000..6ee6af245a8a
--- /dev/null
+++ b/libarchive/libarchive_changes.3
@@ -0,0 +1,341 @@
+.\" Copyright (c) 2011 Tim Kientzle
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd March 27, 2011
+.Dt LIBARCHIVE_CHANGES 3
+.Os
+.Sh NAME
+.Nm changes in libarchive interface
+.\"
+.Sh CHANGES IN LIBARCHIVE 3
+This page describes user-visible changes in libarchive3, and lists
+public functions and other symbols changed, deprecated or removed
+in libarchive3, along with their replacements if any.
+.Pp
+.\"
+.Ss Multiple Filters
+.\"
+Libarchive2 permitted a single (input or output) filter active
+on an archive.
+Libarchive3 extends this into a variable-length stack.
+Where
+.Fn archive_write_set_compression_XXX
+would replace any existing filter,
+.Fn archive_write_add_filter_XXX
+extends the write pipeline with another filter.
+.\"
+.Ss Character Set Handling
+.\"
+Libarchive2 assumed that the local platform uses
+.Tn Unicode
+as the native
+.Tn wchar_t
+encoding, which is true on
+.Tn Windows ,
+modern
+.Tn Linux ,
+and a few other systems, but is certainly not universal.
+As a result, pax format archives were written incorrectly on some
+systems, since pax format requires
+.Tn UTF-8
+and libarchive 2 incorrectly
+assumed that
+.Tn wchar_t
+strings can be easily converted to
+.Tn UTF-8 .
+.Pp
+Libarchive3 uses the standard iconv library to convert between character
+sets and is introducing the notion of a
+.Dq default character set for the archive .
+To support this,
+.Tn archive_entry
+objects can now be bound to a particular archive when they are created.
+The automatic character set conversions performed by
+.Tn archive_entry
+objects when reading and writing filenames, usernames, and other strings
+will now use an appropriate default character set:
+.Pp
+If the
+.Tn archive_entry
+object is bound to an archive, it will use the
+default character set for that archive.
+.Pp
+The platform default character encoding (as returned by
+.Fn nl_langinfo CHARSET )
+will be used if nothing else is specified.
+.Pp
+Libarchive3 also introduces charset options to many of the archive
+readers and writers to control the character set that will be used for
+filenames written in those archives.
+When possible, this will be set automatically based on information in
+the archive itself.
+Combining this with the notion of a default character set for the
+archive should allow you to configure libarchive to read archives from
+other platforms and have the filenames and other information
+transparently converted to the character encoding suitable for your
+application.
+.\"
+.Ss Prototype Changes
+.\"
+These changes break binary compatibility; libarchive3 has a new shared
+library version to reflect these changes.
+The library now uses portable wide types such as
+.Tn int64_t
+instead of less-portable types such as
+.Tn off_t ,
+.Tn gid_t ,
+.Tn uid_t ,
+and
+.Tn ino_t .
+.Pp
+There are a few cases where these changes will affect your source code:
+.Bl -bullet -width ind
+.It
+In some cases, libarchive's wider types will introduce the possibility
+of truncation: for example, on a system with a 16-bit
+.Tn uid_t , you risk having uid
+.Li 65536
+be truncated to uid
+.Li 0 ,
+which can cause serious security problems.
+.It
+Typedef function pointer types will be incompatible.
+For example, if you define custom skip callbacks, you may have to use
+code similar to the following if you want to support building against
+libarchive2 and libarchive3:
+.Bd -literal
+#if ARCHIVE_VERSION_NUMBER < 3000000
+typedef off_t myoff_t;
+#else
+typedef int64_t myoff_t;
+#endif
+
+myoff_t
+my_skip_function(struct archive *a, void *v, myoff_t o)
+{
+ ... implementation ...
+}
+.Ed
+.El
+.Pp
+Affected functions:
+.Pp
+.Bl -bullet -compact
+.It
+.Xo
+.Fn archive_entry_gid ,
+.Fn archive_entry_set_gid
+.Xc
+.It
+.Xo
+.Fn archive_entry_uid ,
+.Fn archive_entry_set_uid
+.Xc
+.It
+.Xo
+.Fn archive_entry_ino ,
+.Fn archive_entry_set_ino
+.Xc
+.It
+.Xo
+.Fn archive_read_data_block ,
+.Fn archive_write_data_block
+.Xc
+.It
+.Xo
+.Fn archive_read_disk_gname ,
+.Fn archive_read_disk_uname
+.Xc
+.It
+.Xo
+.Fn archive_read_disk_set_gname_lookup ,
+.Fn archive_read_disk_set_group_lookup ,
+.Fn archive_read_disk_set_uname_lookup ,
+.Fn archive_read_disk_set_user_lookup
+.Xc
+.It
+.Fn archive_skip_callback
+.It
+.Xo
+.Fn archive_read_extract_set_skip_file ,
+.Fn archive_write_disk_set_skip_file ,
+.Fn archive_write_set_skip_file
+.Xc
+.It
+.Xo
+.Fn archive_write_disk_set_group_lookup ,
+.Fn archive_write_disk_set_user_lookup
+.Xc
+.El
+.Pp
+Where these functions or their arguments took or returned
+.Tn gid_t ,
+.Tn ino_t ,
+.Tn off_t ,
+or
+.Tn uid_t
+they now take or return
+.Tn int64_t
+or equivalent.
+.\"
+.Ss Deprecated Symbols
+.\"
+Symbols deprecated in libarchive3 will be removed in libarchive4.
+These symbols, along with their replacements if any, are listed below:
+.\"
+.Bl -tag -width ind
+.It Fn archive_position_compressed , Fn archive_position_uncompressed
+.Fn archive_filter_bytes
+.It Fn archive_compression
+.Fn archive_filter_code
+.It Fn archive_compression_name
+.Fn archive_filter_name
+.It Fn archive_read_finish , Fn archive_write_finish
+.Fn archive_read_free ,
+.Fn archive_write_free
+.It Fn archive_read_open_file , Fn archive_write_open_file
+.Fn archive_read_open_filename ,
+.Fn archive_write_open_filename
+.It Fn archive_read_support_compression_all
+.\" archive_read_support_compression_* -> archive_read_support_filter_*
+.Fn archive_read_support_filter_all
+.It Fn archive_read_support_compression_bzip2
+.Fn archive_read_support_filter_bzip2
+.It Fn archive_read_support_compression_compress
+.Fn archive_read_support_filter_compress
+.It Fn archive_read_support_compression_gzip
+.Fn archive_read_support_filter_gzip
+.It Fn archive_read_support_compression_lzip
+.Fn archive_read_support_filter_lzip
+.It Fn archive_read_support_compression_lzma
+.Fn archive_read_support_filter_lzma
+.It Fn archive_read_support_compression_none
+.Fn archive_read_support_filter_none
+.It Fn archive_read_support_compression_program
+.Fn archive_read_support_filter_program
+.It Fn archive_read_support_compression_program_signature
+.Fn archive_read_support_filter_program_signature
+.It Fn archive_read_support_compression_rpm
+.Fn archive_read_support_filter_rpm
+.It Fn archive_read_support_compression_uu
+.Fn archive_read_support_filter_uu
+.It Fn archive_read_support_compression_xz
+.Fn archive_read_support_filter_xz
+.\" archive_write_set_compression_* -> archive_write_add_filter_*
+.It Fn archive_write_set_compression_bzip2
+.Fn archive_write_add_filter_bzip2
+.It Fn archive_write_set_compression_compress
+.Fn archive_write_add_filter_compress
+.It Fn archive_write_set_compression_gzip
+.Fn archive_write_add_filter_gzip
+.It Fn archive_write_set_compression_lzip
+.Fn archive_write_add_filter_lzip
+.It Fn archive_write_set_compression_lzma
+.Fn archive_write_add_filter_lzma
+.It Fn archive_write_set_compression_none
+.Fn archive_write_add_filter_none
+.It Fn archive_write_set_compression_program
+.Fn archive_write_add_filter_program
+.It Fn archive_write_set_compression_filter
+.Fn archive_write_add_filter_filter
+.El
+.\"
+.Ss Removed Symbols
+.\"
+These symbols, listed below along with their replacements if any,
+were deprecated in libarchive2, and are not part of libarchive3.
+.\"
+.Bl -tag -width ind
+.It Fn archive_api_feature
+.Fn archive_version_number
+.It Fn archive_api_version
+.Fn archive_version_number
+.It Fn archive_version
+.Fn archive_version_string
+.It Fn archive_version_stamp
+.Fn archive_version_number
+.It Fn archive_read_set_filter_options
+.Fn archive_read_set_options
+or
+.Fn archive_read_set_filter_option
+.It Fn archive_read_set_format_options
+.Fn archive_read_set_options
+or
+.Fn archive_read_set_format_option
+.It Fn archive_write_set_filter_options
+.Fn archive_write_set_options
+or
+.Fn archive_write_set_filter_option
+.It Fn archive_write_set_format_options
+.Fn archive_write_set_options
+or
+.Fn archive_write_set_format_option
+.It Dv ARCHIVE_API_FEATURE
+.Dv ARCHIVE_VERSION_NUMBER
+.It Dv ARCHIVE_API_VERSION
+.Dv ARCHIVE_VERSION_NUMBER
+.It Dv ARCHIVE_VERSION_STAMP
+.Dv ARCHIVE_VERSION_NUMBER
+.It Dv ARCHIVE_LIBRARY_VERSION
+.Dv ARCHIVE_VERSION_STRING
+.\"
+.It Dv ARCHIVE_COMPRESSION_NONE
+.Dv ARCHIVE_FILTER_NONE
+.It Dv ARCHIVE_COMPRESSION_GZIP
+.Dv ARCHIVE_FILTER_GZIP
+.It Dv ARCHIVE_COMPRESSION_BZIP2
+.Dv ARCHIVE_FILTER_BZIP2
+.It Dv ARCHIVE_COMPRESSION_COMPRESS
+.Dv ARCHIVE_FILTER_COMPRESS
+.It Dv ARCHIVE_COMPRESSION_PROGRAM
+.Dv ARCHIVE_FILTER_PROGRAM
+.It Dv ARCHIVE_COMPRESSION_LZMA
+.Dv ARCHIVE_FILTER_LZMA
+.It Dv ARCHIVE_COMPRESSION_XZ
+.Dv ARCHIVE_FILTER_XZ
+.It Dv ARCHIVE_COMPRESSION_UU
+.Dv ARCHIVE_FILTER_UU
+.It Dv ARCHIVE_COMPRESSION_RPM
+.Dv ARCHIVE_FILTER_RPM
+.It Dv ARCHIVE_COMPRESSION_LZIP
+.Dv ARCHIVE_FILTER_LZIP
+.\"
+.It Dv ARCHIVE_BYTES_PER_RECORD
+.Li 512
+.It Dv ARCHIVE_DEFAULT_BYTES_PER_BLOCK
+.Li 10240
+.El
+.Sh SEE ALSO
+.Xr libarchive 3 ,
+.Xr archive_read 3 ,
+.Xr archive_read_filter 3 ,
+.Xr archive_read_format 3 ,
+.Xr archive_read_set_options 3 ,
+.Xr archive_write 3 ,
+.Xr archive_write_filter 3 ,
+.Xr archive_write_format 3 ,
+.Xr archive_write_set_options 3 ,
+.Xr archive_util 3
diff --git a/libarchive/libarchive_internals.3 b/libarchive/libarchive_internals.3
index 50ddef3bbdb7..776f4c35171c 100644
--- a/libarchive/libarchive_internals.3
+++ b/libarchive/libarchive_internals.3
@@ -41,15 +41,15 @@ make it easy to add new archive and compression formats.
Externally, libarchive exposes most operations through an
opaque, object-style interface.
The
-.Xr archive_entry 1
+.Xr archive_entry 3
objects store information about a single filesystem object.
The rest of the library provides facilities to write
-.Xr archive_entry 1
+.Xr archive_entry 3
objects to archive files,
read them from archive files,
and write them to disk.
(There are plans to add a facility to read
-.Xr archive_entry 1
+.Xr archive_entry 3
objects from disk as well.)
.Pp
The read and write APIs each have four layers: a public API
diff --git a/libarchive/tar.5 b/libarchive/tar.5
index 143d3508328f..65875bd61155 100644
--- a/libarchive/tar.5
+++ b/libarchive/tar.5
@@ -171,9 +171,9 @@ These archives generally follow the POSIX ustar
format described below with the following variations:
.Bl -bullet -compact -width indent
.It
-The magic value is
-.Dq ustar\ \&
-(note the following space).
+The magic value consists of the five characters
+.Dq ustar
+followed by a space.
The version field contains a space character followed by a null.
.It
The numeric fields are generally filled with leading spaces
@@ -322,6 +322,39 @@ characters.
Currently, most tar implementations comply with the ustar
format, occasionally extending it by adding new fields to the
blank area at the end of the header record.
+.Ss Numeric Extensions
+There have been several attempts to extend the range of sizes
+or times supported by modifying how numbers are stored in the
+header.
+.Pp
+One obvious extension to increase the size of files is to
+eliminate the terminating characters from the various
+numeric fields.
+For example, the standard only allows the size field to contain
+11 octal digits, reserving the twelfth byte for a trailing
+NUL character.
+Allowing 12 octal digits allows file sizes up to 64 GB.
+.Pp
+Another extension, utilized by GNU tar, star, and other newer
+.Nm
+implementations, permits binary numbers in the standard numeric fields.
+This is flagged by setting the high bit of the first byte.
+The remainder of the field is treated as a signed twos-complement
+value.
+This permits 95-bit values for the length and time fields
+and 63-bit values for the uid, gid, and device numbers.
+In particular, this provides a consistent way to handle
+negative time values.
+GNU tar supports this extension for the
+length, mtime, ctime, and atime fields.
+Joerg Schilling's star program and the libarchive library support
+this extension for all numeric fields.
+Note that this extension is largely obsoleted by the extended
+attribute record provided by the pax interchange format.
+.Pp
+Another early GNU extension allowed base-64 values rather than octal.
+This extension was short-lived and is no longer supported by any
+implementation.
.Ss Pax Interchange Format
There are many attributes that cannot be portably stored in a
POSIX ustar archive.
@@ -365,6 +398,27 @@ A description of some common keys follows:
.It Cm atime , Cm ctime , Cm mtime
File access, inode change, and modification times.
These fields can be negative or include a decimal point and a fractional value.
+.It Cm hdrcharset
+The character set used by the pax extension values.
+By default, all textual values in the pax extended attributes
+are assumed to be in UTF-8, including pathnames, user names,
+and group names.
+In some cases, it is not possible to translate local
+conventions into UTF-8.
+If this key is present and the value is the six-character ASCII string
+.Dq BINARY ,
+then all textual values are assumed to be in a platform-dependent
+multi-byte encoding.
+Note that there are only two valid values for this key:
+.Dq BINARY
+or
+.Dq ISO-IR\ 10646\ 2000\ UTF-8 .
+No other values are permitted by the standard, and
+the latter value should generally not be used as it is the
+default when this key is not specified.
+In particular, this flag should not be used as a general
+mechanism to allow filenames to be stored in arbitrary
+encodings.
.It Cm uname , Cm uid , Cm gname , Cm gid
User name, group name, and numeric UID and GID values.
The user name and group name stored here are encoded in UTF8
@@ -408,6 +462,16 @@ Schilling's
.Cm SCHILY.*
extensions can store all of the data from
.Va struct stat .
+.It Cm LIBARCHIVE.*
+Vendor-specific attributes used by the
+.Nm libarchive
+library and programs that use it.
+.It Cm LIBARCHIVE.creationtime
+The time when the file was created.
+(This should not be confused with the POSIX
+.Dq ctime
+attribute, which refers to the time when the file
+metadata was last changed.)
.It Cm LIBARCHIVE.xattr. Ns Ar namespace Ns . Ns Ar key
Libarchive stores POSIX.1e-style extended attributes using
keys of this form.
@@ -659,8 +723,11 @@ GNU tar 1.14 (XXX check this XXX) and later will write
pax interchange format archives when you specify the
.Fl -posix
flag.
-This format uses custom keywords to store sparse file information.
-There have been three iterations of this support, referred to
+This format follows the pax interchange format closely,
+using some
+.Cm SCHILY
+tags and introducing new keywords to store sparse file information.
+There have been three iterations of the sparse file support, referred to
as
.Dq 0.0 ,
.Dq 0.1 ,
@@ -735,7 +802,7 @@ entry.
.It
An additional
.Cm A
-entry is used to store an ACL for the following regular entry.
+header is used to store an ACL for the following regular entry.
The body of this entry contains a seven-digit octal number
followed by a zero byte, followed by the
textual ACL description.
@@ -745,46 +812,95 @@ for POSIX.1e ACLs and 03000000 for NFSv4 ACLs.
.El
.Ss AIX Tar
XXX More details needed XXX
+.Pp
+AIX Tar uses a ustar-formatted header with the type
+.Cm A
+for storing coded ACL information.
+Unlike the Solaris format, AIX tar writes this header after the
+regular file body to which it applies.
+The pathname in this header is either
+.Cm NFS4
+or
+.Cm AIXC
+to indicate the type of ACL stored.
+The actual ACL is stored in platform-specific binary format.
.Ss Mac OS X Tar
The tar distributed with Apple's Mac OS X stores most regular files
-as two separate entries in the tar archive.
-The two entries have the same name except that the first
+as two separate files in the tar archive.
+The two files have the same name except that the first
one has
.Dq ._
-added to the beginning of the name.
-This first entry stores the
-.Dq resource fork
-with additional attributes for the file.
-The Mac OS X
-.Fn CopyFile
-API is used to separate a file on disk into separate
-resource and data streams and to reassemble those separate
-streams when the file is restored to disk.
-.Ss Other Extensions
-One obvious extension to increase the size of files is to
-eliminate the terminating characters from the various
-numeric fields.
-For example, the standard only allows the size field to contain
-11 octal digits, reserving the twelfth byte for a trailing
-NUL character.
-Allowing 12 octal digits allows file sizes up to 64 GB.
-.Pp
-Another extension, utilized by GNU tar, star, and other newer
-.Nm
-implementations, permits binary numbers in the standard numeric fields.
-This is flagged by setting the high bit of the first byte.
-This permits 95-bit values for the length and time fields
-and 63-bit values for the uid, gid, and device numbers.
-GNU tar supports this extension for the
-length, mtime, ctime, and atime fields.
-Joerg Schilling's star program supports this extension for
-all numeric fields.
-Note that this extension is largely obsoleted by the extended attribute
-record provided by the pax interchange format.
+prepended to the last path element.
+This special file stores an AppleDouble-encoded
+binary blob with additional metadata about the second file,
+including ACL, extended attributes, and resources.
+To recreate the original file on disk, each
+separate file can be extracted and the Mac OS X
+.Fn copyfile
+function can be used to unpack the separate
+metadata file and apply it to th regular file.
+Conversely, the same function provides a
+.Dq pack
+option to encode the extended metadata from
+a file into a separate file whose contents
+can then be put into a tar archive.
.Pp
-Another early GNU extension allowed base-64 values rather than octal.
-This extension was short-lived and is no longer supported by any
-implementation.
+Note that the Apple extended attributes interact
+badly with long filenames.
+Since each file is stored with the full name,
+a separate set of extensions needs to be included
+in the archive for each one, doubling the overhead
+required for files with long names.
+.Ss Summary of tar type codes
+The following list is a condensed summary of the type codes
+used in tar header records generated by different tar implementations.
+More details about specific implementations can be found above:
+.Bl -tag -compact -width XXX
+.It NUL
+Early tar programs stored a zero byte for regular files.
+.It Cm 0
+POSIX standard type code for a regular file.
+.It Cm 1
+POSIX standard type code for a hard link description.
+.It Cm 2
+POSIX standard type code for a symbolic link description.
+.It Cm 3
+POSIX standard type code for a character device node.
+.It Cm 4
+POSIX standard type code for a block device node.
+.It Cm 5
+POSIX standard type code for a directory.
+.It Cm 6
+POSIX standard type code for a FIFO.
+.It Cm 7
+POSIX reserved.
+.It Cm 7
+GNU tar used for pre-allocated files on some systems.
+.It Cm A
+Solaris tar ACL description stored prior to a regular file header.
+.It Cm A
+AIX tar ACL description stored after the file body.
+.It Cm D
+GNU tar directory dump.
+.It Cm K
+GNU tar long linkname for the following header.
+.It Cm L
+GNU tar long pathname for the following header.
+.It Cm M
+GNU tar multivolume marker, indicating the file is a continuation of a file from the previous volume.
+.It Cm N
+GNU tar long filename support. Deprecated.
+.It Cm S
+GNU tar sparse regular file.
+.It Cm V
+GNU tar tape/volume header name.
+.It Cm X
+Solaris tar general-purpose extension header.
+.It Cm g
+POSIX pax interchange format global extensions.
+.It Cm x
+POSIX pax interchange format per-file extensions.
+.El
.Sh SEE ALSO
.Xr ar 1 ,
.Xr pax 1 ,
diff --git a/libarchive/test/CMakeLists.txt b/libarchive/test/CMakeLists.txt
index 07ee2e364b75..de98e6bdb85a 100644
--- a/libarchive/test/CMakeLists.txt
+++ b/libarchive/test/CMakeLists.txt
@@ -4,26 +4,46 @@
#
############################################
IF(ENABLE_TEST)
- FOREACH (_src ${libarchive_SOURCES})
- LIST(APPEND parent_libarchive_SOURCES "../${_src}")
- ENDFOREACH(_src)
-
SET(libarchive_test_SOURCES
- ${parent_libarchive_SOURCES}
- main.c
+ main.c
read_open_memory.c
test.h
- test_acl_basic.c
test_acl_freebsd.c
+ test_acl_nfs4.c
test_acl_pax.c
+ test_acl_posix1e.c
test_archive_api_feature.c
+ test_archive_clear_error.c
+ test_archive_crypto.c
+ test_archive_read_close_twice.c
+ test_archive_read_close_twice_open_fd.c
+ test_archive_read_close_twice_open_filename.c
+ test_archive_read_next_header_empty.c
+ test_archive_read_next_header_raw.c
+ test_archive_read_open2.c
+ test_archive_read_set_filter_option.c
+ test_archive_read_set_format_option.c
+ test_archive_read_set_option.c
+ test_archive_read_set_options.c
+ test_archive_read_support.c
+ test_archive_set_error.c
+ test_archive_string.c
+ test_archive_string_conversion.c
+ test_archive_write_set_filter_option.c
+ test_archive_write_set_format_option.c
+ test_archive_write_set_option.c
+ test_archive_write_set_options.c
test_bad_fd.c
test_compat_bzip2.c
test_compat_cpio.c
test_compat_gtar.c
test_compat_gzip.c
+ test_compat_lzip.c
test_compat_lzma.c
+ test_compat_mac.c
+ test_compat_pax_libarchive_2x.c
test_compat_solaris_tar_acl.c
+ test_compat_solaris_pax_sparse.c
test_compat_tar_hardlink.c
test_compat_xz.c
test_compat_zip.c
@@ -31,7 +51,9 @@ IF(ENABLE_TEST)
test_entry.c
test_entry_strmode.c
test_extattr_freebsd.c
+ test_filter_count.c
test_fuzz.c
+ test_gnutar_filename_encoding.c
test_link_resolver.c
test_open_failure.c
test_open_fd.c
@@ -41,92 +63,125 @@ IF(ENABLE_TEST)
test_read_compress_program.c
test_read_data_large.c
test_read_disk.c
+ test_read_disk_directory_traversals.c
test_read_disk_entry_from_file.c
test_read_extract.c
test_read_file_nonexistent.c
+ test_read_format_7zip.c
test_read_format_ar.c
+ test_read_format_cab.c
+ test_read_format_cab_filename.c
+ test_read_format_cpio_afio.c
test_read_format_cpio_bin.c
test_read_format_cpio_bin_Z.c
test_read_format_cpio_bin_be.c
test_read_format_cpio_bin_bz2.c
test_read_format_cpio_bin_gz.c
+ test_read_format_cpio_bin_lzip.c
test_read_format_cpio_bin_lzma.c
test_read_format_cpio_bin_xz.c
+ test_read_format_cpio_filename.c
test_read_format_cpio_odc.c
test_read_format_cpio_svr4_bzip2_rpm.c
test_read_format_cpio_svr4_gzip.c
test_read_format_cpio_svr4_gzip_rpm.c
test_read_format_cpio_svr4c_Z.c
test_read_format_empty.c
+ test_read_format_gtar_filename.c
test_read_format_gtar_gz.c
test_read_format_gtar_lzma.c
test_read_format_gtar_sparse.c
test_read_format_iso_Z.c
test_read_format_iso_multi_extent.c
+ test_read_format_iso_xorriso.c
test_read_format_isojoliet_bz2.c
test_read_format_isojoliet_long.c
test_read_format_isojoliet_rr.c
+ test_read_format_isojoliet_versioned.c
test_read_format_isorr_bz2.c
test_read_format_isorr_ce.c
test_read_format_isorr_new_bz2.c
test_read_format_isorr_rr_moved.c
test_read_format_isozisofs_bz2.c
+ test_read_format_lha.c
+ test_read_format_lha_filename.c
test_read_format_mtree.c
test_read_format_pax_bz2.c
+ test_read_format_rar.c
test_read_format_raw.c
test_read_format_tar.c
test_read_format_tar_empty_filename.c
+ test_read_format_tar_filename.c
test_read_format_tbz.c
test_read_format_tgz.c
test_read_format_tlz.c
test_read_format_txz.c
test_read_format_tz.c
+ test_read_format_ustar_filename.c
test_read_format_xar.c
test_read_format_zip.c
+ test_read_format_zip_filename.c
test_read_large.c
test_read_pax_truncated.c
test_read_position.c
test_read_truncated.c
+ test_read_truncated_filter.c
test_read_uu.c
+ test_sparse_basic.c
test_tar_filenames.c
test_tar_large.c
test_ustar_filenames.c
+ test_ustar_filename_encoding.c
test_write_compress.c
test_write_compress_bzip2.c
test_write_compress_gzip.c
+ test_write_compress_lzip.c
test_write_compress_lzma.c
test_write_compress_program.c
test_write_compress_xz.c
test_write_disk.c
test_write_disk_failures.c
test_write_disk_hardlink.c
+ test_write_disk_lookup.c
test_write_disk_perms.c
test_write_disk_secure.c
test_write_disk_sparse.c
test_write_disk_symlink.c
test_write_disk_times.c
+ test_write_format_7zip.c
test_write_format_ar.c
test_write_format_cpio.c
test_write_format_cpio_empty.c
- test_write_format_cpio_odc.c
test_write_format_cpio_newc.c
+ test_write_format_cpio_odc.c
+ test_write_format_gnutar.c
+ test_write_format_iso9660.c
+ test_write_format_iso9660_boot.c
+ test_write_format_iso9660_empty.c
+ test_write_format_iso9660_filename.c
+ test_write_format_iso9660_zisofs.c
test_write_format_mtree.c
+ test_write_format_mtree_fflags.c
test_write_format_pax.c
test_write_format_shar_empty.c
test_write_format_tar.c
test_write_format_tar_empty.c
+ test_write_format_tar_sparse.c
test_write_format_tar_ustar.c
+ test_write_format_xar.c
+ test_write_format_xar_empty.c
test_write_format_zip.c
test_write_format_zip_empty.c
test_write_format_zip_no_compression.c
test_write_open_memory.c
+ test_zip_filename_encoding.c
)
#
# Register target
#
ADD_EXECUTABLE(libarchive_test ${libarchive_test_SOURCES})
- TARGET_LINK_LIBRARIES(libarchive_test ${ADDITIONAL_LIBS})
+ TARGET_LINK_LIBRARIES(libarchive_test archive_static ${ADDITIONAL_LIBS})
SET_PROPERTY(TARGET libarchive_test PROPERTY COMPILE_DEFINITIONS
LIBARCHIVE_STATIC LIST_H)
@@ -142,7 +197,7 @@ IF(ENABLE_TEST)
# test. We can use that to define the tests for cmake by
# defining a DEFINE_TEST macro and reading list.h in.
MACRO (DEFINE_TEST _testname)
- ADD_TEST_28(
+ ADD_TEST(
NAME libarchive_${_testname}
COMMAND libarchive_test -vv
-r ${CMAKE_CURRENT_SOURCE_DIR}
diff --git a/libarchive/test/main.c b/libarchive/test/main.c
index f67bbc354650..3d7ead581ff3 100644
--- a/libarchive/test/main.c
+++ b/libarchive/test/main.c
@@ -24,8 +24,18 @@
*/
#include "test.h"
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
#include <errno.h>
+#ifdef HAVE_ICONV_H
+#include <iconv.h>
+#endif
+#include <limits.h>
#include <locale.h>
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
#include <stdarg.h>
#include <time.h>
@@ -42,7 +52,8 @@ __FBSDID("$FreeBSD: head/lib/libarchive/test/main.c 201247 2009-12-30 05:59:21Z
#undef PROGRAM /* Testing a library, not a program. */
#define LIBRARY "libarchive"
#define EXTRA_DUMP(x) archive_error_string((struct archive *)(x))
-#define EXTRA_VERSION archive_version()
+#define EXTRA_ERRNO(x) archive_errno((struct archive *)(x))
+#define EXTRA_VERSION archive_version_string()
/*
*
@@ -77,6 +88,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/test/main.c 201247 2009-12-30 05:59:21Z
#endif
#if !defined(__BORLANDC__)
#define access _access
+#undef chdir
#define chdir _chdir
#endif
#ifndef fileno
@@ -149,7 +161,7 @@ my_GetFileInformationByName(const char *path, BY_HANDLE_FILE_INFORMATION *bhfi)
memset(bhfi, 0, sizeof(*bhfi));
h = CreateFile(path, FILE_READ_ATTRIBUTES, 0, NULL,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (h == INVALID_HANDLE_VALUE)
return (0);
r = GetFileInformationByHandle(h, bhfi);
@@ -178,6 +190,8 @@ invalid_parameter_handler(const wchar_t * expression,
static int dump_on_failure = 0;
/* Default is to remove temp dirs and log data for successful tests. */
static int keep_temp_files = 0;
+/* Default is to run the specified tests once and report errors. */
+static int until_failure = 0;
/* Default is to just report pass/fail for each test. */
static int verbosity = 0;
#define VERBOSITY_SUMMARY_ONLY -1 /* -q */
@@ -235,10 +249,14 @@ void
failure(const char *fmt, ...)
{
va_list ap;
- va_start(ap, fmt);
- vsprintf(msgbuff, fmt, ap);
- va_end(ap);
- nextmsg = msgbuff;
+ if (fmt == NULL) {
+ nextmsg = NULL;
+ } else {
+ va_start(ap, fmt);
+ vsprintf(msgbuff, fmt, ap);
+ va_end(ap);
+ nextmsg = msgbuff;
+ }
}
/*
@@ -250,15 +268,14 @@ failure(const char *fmt, ...)
* pass __FILE__, __LINE__ directly into the function instead of using
* this hook. I suspect this machinery is used so rarely that we
* would be better off just removing it entirely. That would simplify
- * the code here noticably.
+ * the code here noticeably.
*/
-static const char *test_filename;
-static int test_line;
-static void *test_extra;
-void assertion_setup(const char *filename, int line)
+static const char *skipping_filename;
+static int skipping_line;
+void skipping_setup(const char *filename, int line)
{
- test_filename = filename;
- test_line = line;
+ skipping_filename = filename;
+ skipping_line = line;
}
/* Called at the beginning of each assert() function. */
@@ -285,6 +302,7 @@ static struct line {
int count;
int skip;
} failed_lines[10000];
+const char *failed_filename;
/* Count this failure, setup up log destination and handle initial report. */
static void
@@ -294,7 +312,7 @@ failure_start(const char *filename, int line, const char *fmt, ...)
/* Record another failure for this line. */
++failures;
- /* test_filename = filename; */
+ failed_filename = filename;
failed_lines[line].count++;
/* Determine whether to log header to console. */
@@ -339,8 +357,10 @@ failure_finish(void *extra)
{
(void)extra; /* UNUSED (maybe) */
#ifdef EXTRA_DUMP
- if (extra != NULL)
+ if (extra != NULL) {
+ logprintf(" errno: %d\n", EXTRA_ERRNO(extra));
logprintf(" detail: %s\n", EXTRA_DUMP(extra));
+ }
#endif
if (dump_on_failure) {
@@ -361,12 +381,15 @@ test_skipping(const char *fmt, ...)
va_start(ap, fmt);
vsprintf(buff, fmt, ap);
va_end(ap);
+ /* Use failure() message if set. */
+ msg = nextmsg;
+ nextmsg = NULL;
/* failure_start() isn't quite right, but is awfully convenient. */
- failure_start(test_filename, test_line, "SKIPPING: %s", buff);
+ failure_start(skipping_filename, skipping_line, "SKIPPING: %s", buff);
--failures; /* Undo failures++ in failure_start() */
/* Don't failure_finish() here. */
/* Mark as skip, so doesn't count as failed test. */
- failed_lines[test_line].skip = 1;
+ failed_lines[skipping_line].skip = 1;
++skips;
}
@@ -417,13 +440,102 @@ assertion_equal_int(const char *file, int line,
return (0);
}
-static void strdump(const char *e, const char *p)
+/*
+ * Utility to convert a single UTF-8 sequence.
+ */
+static int
+_utf8_to_unicode(uint32_t *pwc, const char *s, size_t n)
+{
+ static const char utf8_count[256] = {
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 00 - 0F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 10 - 1F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 20 - 2F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 30 - 3F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40 - 4F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 50 - 5F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 60 - 6F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 70 - 7F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 80 - 8F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 90 - 9F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* A0 - AF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* B0 - BF */
+ 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,/* C0 - CF */
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,/* D0 - DF */
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,/* E0 - EF */
+ 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* F0 - FF */
+ };
+ int ch;
+ int cnt;
+ uint32_t wc;
+
+ *pwc = 0;
+
+ /* Sanity check. */
+ if (n == 0)
+ return (0);
+ /*
+ * Decode 1-4 bytes depending on the value of the first byte.
+ */
+ ch = (unsigned char)*s;
+ if (ch == 0)
+ return (0); /* Standard: return 0 for end-of-string. */
+ cnt = utf8_count[ch];
+
+ /* Invalide sequence or there are not plenty bytes. */
+ if (n < (size_t)cnt)
+ return (-1);
+
+ /* Make a Unicode code point from a single UTF-8 sequence. */
+ switch (cnt) {
+ case 1: /* 1 byte sequence. */
+ *pwc = ch & 0x7f;
+ return (cnt);
+ case 2: /* 2 bytes sequence. */
+ if ((s[1] & 0xc0) != 0x80) return (-1);
+ *pwc = ((ch & 0x1f) << 6) | (s[1] & 0x3f);
+ return (cnt);
+ case 3: /* 3 bytes sequence. */
+ if ((s[1] & 0xc0) != 0x80) return (-1);
+ if ((s[2] & 0xc0) != 0x80) return (-1);
+ wc = ((ch & 0x0f) << 12)
+ | ((s[1] & 0x3f) << 6)
+ | (s[2] & 0x3f);
+ if (wc < 0x800)
+ return (-1);/* Overlong sequence. */
+ break;
+ case 4: /* 4 bytes sequence. */
+ if (n < 4)
+ return (-1);
+ if ((s[1] & 0xc0) != 0x80) return (-1);
+ if ((s[2] & 0xc0) != 0x80) return (-1);
+ if ((s[3] & 0xc0) != 0x80) return (-1);
+ wc = ((ch & 0x07) << 18)
+ | ((s[1] & 0x3f) << 12)
+ | ((s[2] & 0x3f) << 6)
+ | (s[3] & 0x3f);
+ if (wc < 0x10000)
+ return (-1);/* Overlong sequence. */
+ break;
+ default:
+ return (-1);
+ }
+
+ /* The code point larger than 0x10FFFF is not leagal
+ * Unicode values. */
+ if (wc > 0x10FFFF)
+ return (-1);
+ /* Correctly gets a Unicode, returns used bytes. */
+ *pwc = wc;
+ return (cnt);
+}
+
+static void strdump(const char *e, const char *p, int ewidth, int utf8)
{
const char *q = p;
- logprintf(" %s = ", e);
+ logprintf(" %*s = ", ewidth, e);
if (p == NULL) {
- logprintf("NULL");
+ logprintf("NULL\n");
return;
}
logprintf("\"");
@@ -442,7 +554,37 @@ static void strdump(const char *e, const char *p)
}
}
logprintf("\"");
- logprintf(" (length %d)\n", q == NULL ? -1 : (int)strlen(q));
+ logprintf(" (length %d)", q == NULL ? -1 : (int)strlen(q));
+
+ /*
+ * If the current string is UTF-8, dump its code points.
+ */
+ if (utf8) {
+ size_t len;
+ uint32_t uc;
+ int n;
+ int cnt = 0;
+
+ p = q;
+ len = strlen(p);
+ logprintf(" [");
+ while ((n = _utf8_to_unicode(&uc, p, len)) > 0) {
+ if (p != q)
+ logprintf(" ");
+ logprintf("%04X", uc);
+ p += n;
+ len -= n;
+ cnt++;
+ }
+ logprintf("]");
+ logprintf(" (count %d", cnt);
+ if (n < 0) {
+ logprintf(",unknown %d bytes", len);
+ }
+ logprintf(")");
+
+ }
+ logprintf("\n");
}
/* Verify two strings are equal, dump them if not. */
@@ -450,14 +592,20 @@ int
assertion_equal_string(const char *file, int line,
const char *v1, const char *e1,
const char *v2, const char *e2,
- void *extra)
+ void *extra, int utf8)
{
+ int l1, l2;
+
assertion_count(file, line);
if (v1 == v2 || (v1 != NULL && v2 != NULL && strcmp(v1, v2) == 0))
return (1);
failure_start(file, line, "%s != %s", e1, e2);
- strdump(e1, v1);
- strdump(e2, v2);
+ l1 = strlen(e1);
+ l2 = strlen(e2);
+ if (l1 < l2)
+ l1 = l2;
+ strdump(e1, v1, l1, utf8);
+ strdump(e2, v2, l1, utf8);
failure_finish(extra);
return (0);
}
@@ -509,7 +657,9 @@ assertion_equal_wstring(const char *file, int line,
void *extra)
{
assertion_count(file, line);
- if (v1 == v2 || wcscmp(v1, v2) == 0)
+ if (v1 == v2)
+ return (1);
+ if (v1 != NULL && v2 != NULL && wcscmp(v1, v2) == 0)
return (1);
failure_start(file, line, "%s != %s", e1, e2);
wcsdump(e1, v1);
@@ -588,9 +738,9 @@ assertion_equal_mem(const char *file, int line,
offset += 16;
}
logprintf(" Dump of %s\n", e1);
- hexdump(v1, v2, l < 64 ? l : 64, offset);
+ hexdump(v1, v2, l < 128 ? l : 128, offset);
logprintf(" Dump of %s\n", e2);
- hexdump(v2, v1, l < 64 ? l : 64, offset);
+ hexdump(v2, v1, l < 128 ? l : 128, offset);
logprintf("\n");
failure_finish(extra);
return (0);
@@ -598,29 +748,24 @@ assertion_equal_mem(const char *file, int line,
/* Verify that the named file exists and is empty. */
int
-assertion_empty_file(const char *f1fmt, ...)
+assertion_empty_file(const char *filename, int line, const char *f1)
{
char buff[1024];
- char f1[1024];
struct stat st;
- va_list ap;
ssize_t s;
FILE *f;
- assertion_count(test_filename, test_line);
- va_start(ap, f1fmt);
- vsprintf(f1, f1fmt, ap);
- va_end(ap);
+ assertion_count(filename, line);
if (stat(f1, &st) != 0) {
- failure_start(test_filename, test_line, "Stat failed: %s", f1);
+ failure_start(filename, line, "Stat failed: %s", f1);
failure_finish(NULL);
return (0);
}
if (st.st_size == 0)
return (1);
- failure_start(test_filename, test_line, "File should be empty: %s", f1);
+ failure_start(filename, line, "File should be empty: %s", f1);
logprintf(" File size: %d\n", (int)st.st_size);
logprintf(" Contents:\n");
f = fopen(f1, "rb");
@@ -639,24 +784,19 @@ assertion_empty_file(const char *f1fmt, ...)
/* Verify that the named file exists and is not empty. */
int
-assertion_non_empty_file(const char *f1fmt, ...)
+assertion_non_empty_file(const char *filename, int line, const char *f1)
{
- char f1[1024];
struct stat st;
- va_list ap;
- assertion_count(test_filename, test_line);
- va_start(ap, f1fmt);
- vsprintf(f1, f1fmt, ap);
- va_end(ap);
+ assertion_count(filename, line);
if (stat(f1, &st) != 0) {
- failure_start(test_filename, test_line, "Stat failed: %s", f1);
+ failure_start(filename, line, "Stat failed: %s", f1);
failure_finish(NULL);
return (0);
}
if (st.st_size == 0) {
- failure_start(test_filename, test_line, "File empty: %s", f1);
+ failure_start(filename, line, "File empty: %s", f1);
failure_finish(NULL);
return (0);
}
@@ -666,19 +806,14 @@ assertion_non_empty_file(const char *f1fmt, ...)
/* Verify that two files have the same contents. */
/* TODO: hexdump the first bytes that actually differ. */
int
-assertion_equal_file(const char *fn1, const char *f2pattern, ...)
+assertion_equal_file(const char *filename, int line, const char *fn1, const char *fn2)
{
- char fn2[1024];
- va_list ap;
char buff1[1024];
char buff2[1024];
FILE *f1, *f2;
int n1, n2;
- assertion_count(test_filename, test_line);
- va_start(ap, f2pattern);
- vsprintf(fn2, f2pattern, ap);
- va_end(ap);
+ assertion_count(filename, line);
f1 = fopen(fn1, "rb");
f2 = fopen(fn2, "rb");
@@ -697,24 +832,18 @@ assertion_equal_file(const char *fn1, const char *f2pattern, ...)
}
fclose(f1);
fclose(f2);
- failure_start(test_filename, test_line, "Files not identical");
+ failure_start(filename, line, "Files not identical");
logprintf(" file1=\"%s\"\n", fn1);
logprintf(" file2=\"%s\"\n", fn2);
- failure_finish(test_extra);
+ failure_finish(NULL);
return (0);
}
/* Verify that the named file does exist. */
int
-assertion_file_exists(const char *fpattern, ...)
+assertion_file_exists(const char *filename, int line, const char *f)
{
- char f[1024];
- va_list ap;
-
- assertion_count(test_filename, test_line);
- va_start(ap, fpattern);
- vsprintf(f, fpattern, ap);
- va_end(ap);
+ assertion_count(filename, line);
#if defined(_WIN32) && !defined(__CYGWIN__)
if (!_access(f, 0))
@@ -723,22 +852,16 @@ assertion_file_exists(const char *fpattern, ...)
if (!access(f, F_OK))
return (1);
#endif
- failure_start(test_filename, test_line, "File should exist: %s", f);
- failure_finish(test_extra);
+ failure_start(filename, line, "File should exist: %s", f);
+ failure_finish(NULL);
return (0);
}
/* Verify that the named file doesn't exist. */
int
-assertion_file_not_exists(const char *fpattern, ...)
+assertion_file_not_exists(const char *filename, int line, const char *f)
{
- char f[1024];
- va_list ap;
-
- assertion_count(test_filename, test_line);
- va_start(ap, fpattern);
- vsprintf(f, fpattern, ap);
- va_end(ap);
+ assertion_count(filename, line);
#if defined(_WIN32) && !defined(__CYGWIN__)
if (_access(f, 0))
@@ -747,31 +870,26 @@ assertion_file_not_exists(const char *fpattern, ...)
if (access(f, F_OK))
return (1);
#endif
- failure_start(test_filename, test_line, "File should not exist: %s", f);
- failure_finish(test_extra);
+ failure_start(filename, line, "File should not exist: %s", f);
+ failure_finish(NULL);
return (0);
}
/* Compare the contents of a file to a block of memory. */
int
-assertion_file_contents(const void *buff, int s, const char *fpattern, ...)
+assertion_file_contents(const char *filename, int line, const void *buff, int s, const char *fn)
{
- char fn[1024];
- va_list ap;
char *contents;
FILE *f;
int n;
- assertion_count(test_filename, test_line);
- va_start(ap, fpattern);
- vsprintf(fn, fpattern, ap);
- va_end(ap);
+ assertion_count(filename, line);
f = fopen(fn, "rb");
if (f == NULL) {
- failure_start(test_filename, test_line,
+ failure_start(filename, line,
"File should exist: %s", fn);
- failure_finish(test_extra);
+ failure_finish(NULL);
return (0);
}
contents = malloc(s * 2);
@@ -781,30 +899,36 @@ assertion_file_contents(const void *buff, int s, const char *fpattern, ...)
free(contents);
return (1);
}
- failure_start(test_filename, test_line, "File contents don't match");
+ failure_start(filename, line, "File contents don't match");
logprintf(" file=\"%s\"\n", fn);
if (n > 0)
hexdump(contents, buff, n > 512 ? 512 : n, 0);
else {
logprintf(" File empty, contents should be:\n");
- hexdump(buff, NULL, s > 512 ? 512 : n, 0);
+ hexdump(buff, NULL, s > 512 ? 512 : s, 0);
}
- failure_finish(test_extra);
+ failure_finish(NULL);
free(contents);
return (0);
}
/* Check the contents of a text file, being tolerant of line endings. */
int
-assertion_text_file_contents(const char *buff, const char *fn)
+assertion_text_file_contents(const char *filename, int line, const char *buff, const char *fn)
{
char *contents;
const char *btxt, *ftxt;
FILE *f;
int n, s;
- assertion_count(test_filename, test_line);
+ assertion_count(filename, line);
f = fopen(fn, "r");
+ if (f == NULL) {
+ failure_start(filename, line,
+ "File doesn't exist: %s", fn);
+ failure_finish(NULL);
+ return (0);
+ }
s = strlen(buff);
contents = malloc(s * 2 + 128);
n = fread(contents, 1, s * 2 + 128 - 1, f);
@@ -832,19 +956,122 @@ assertion_text_file_contents(const char *buff, const char *fn)
free(contents);
return (1);
}
- failure_start(test_filename, test_line, "Contents don't match");
+ failure_start(filename, line, "Contents don't match");
logprintf(" file=\"%s\"\n", fn);
- if (n > 0)
+ if (n > 0) {
hexdump(contents, buff, n, 0);
- else {
+ logprintf(" expected\n", fn);
+ hexdump(buff, contents, s, 0);
+ } else {
logprintf(" File empty, contents should be:\n");
hexdump(buff, NULL, s, 0);
}
- failure_finish(test_extra);
+ failure_finish(NULL);
free(contents);
return (0);
}
+/* Verify that a text file contains the specified lines, regardless of order */
+/* This could be more efficient if we sorted both sets of lines, etc, but
+ * since this is used only for testing and only ever deals with a dozen or so
+ * lines at a time, this relatively crude approach is just fine. */
+int
+assertion_file_contains_lines_any_order(const char *file, int line,
+ const char *pathname, const char *lines[])
+{
+ char *buff;
+ size_t buff_size;
+ size_t expected_count, actual_count, i, j;
+ char **expected;
+ char *p, **actual;
+ char c;
+ int expected_failure = 0, actual_failure = 0;
+
+ assertion_count(file, line);
+
+ buff = slurpfile(&buff_size, "%s", pathname);
+ if (buff == NULL) {
+ failure_start(pathname, line, "Can't read file: %s", pathname);
+ failure_finish(NULL);
+ return (0);
+ }
+
+ /* Make a copy of the provided lines and count up the expected file size. */
+ expected_count = 0;
+ for (i = 0; lines[i] != NULL; ++i) {
+ }
+ expected_count = i;
+ expected = malloc(sizeof(char *) * expected_count);
+ for (i = 0; lines[i] != NULL; ++i) {
+ expected[i] = strdup(lines[i]);
+ }
+
+ /* Break the file into lines */
+ actual_count = 0;
+ for (c = '\0', p = buff; p < buff + buff_size; ++p) {
+ if (*p == '\x0d' || *p == '\x0a')
+ *p = '\0';
+ if (c == '\0' && *p != '\0')
+ ++actual_count;
+ c = *p;
+ }
+ actual = malloc(sizeof(char *) * actual_count);
+ for (j = 0, p = buff; p < buff + buff_size; p += 1 + strlen(p)) {
+ if (*p != '\0') {
+ actual[j] = p;
+ ++j;
+ }
+ }
+
+ /* Erase matching lines from both lists */
+ for (i = 0; i < expected_count; ++i) {
+ if (expected[i] == NULL)
+ continue;
+ for (j = 0; j < actual_count; ++j) {
+ if (actual[j] == NULL)
+ continue;
+ if (strcmp(expected[i], actual[j]) == 0) {
+ free(expected[i]);
+ expected[i] = NULL;
+ actual[j] = NULL;
+ break;
+ }
+ }
+ }
+
+ /* If there's anything left, it's a failure */
+ for (i = 0; i < expected_count; ++i) {
+ if (expected[i] != NULL)
+ ++expected_failure;
+ }
+ for (j = 0; j < actual_count; ++j) {
+ if (actual[j] != NULL)
+ ++actual_failure;
+ }
+ if (expected_failure == 0 && actual_failure == 0) {
+ free(buff);
+ free(expected);
+ free(actual);
+ return (1);
+ }
+ failure_start(file, line, "File doesn't match: %s", pathname);
+ for (i = 0; i < expected_count; ++i) {
+ if (expected[i] != NULL) {
+ logprintf(" Expected but not present: %s\n", expected[i]);
+ free(expected[i]);
+ }
+ }
+ for (j = 0; j < actual_count; ++j) {
+ if (actual[j] != NULL)
+ logprintf(" Present but not expected: %s\n", actual[j]);
+ }
+ failure_finish(NULL);
+ free(buff);
+ free(expected);
+ free(actual);
+ return (0);
+}
+
/* Test that two paths point to the same file. */
/* As a side-effect, asserts that both files exist. */
static int
@@ -934,8 +1161,11 @@ assertion_file_time(const char *file, int line,
ftime.dwHighDateTime = 0;
assertion_count(file, line);
+ /* Note: FILE_FLAG_BACKUP_SEMANTICS applies to open
+ * a directory file. If not, CreateFile() will fail when
+ * the pathname is a directory. */
h = CreateFile(pathname, FILE_READ_ATTRIBUTES, 0, NULL,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (h == INVALID_HANDLE_VALUE) {
failure_start(file, line, "Can't access %s\n", pathname);
failure_finish(NULL);
@@ -1000,14 +1230,14 @@ assertion_file_time(const char *file, int line,
time_t now = time(NULL);
if (filet < now - 10 || filet > now + 1) {
failure_start(file, line,
- "File %s has %ctime %ld, %ld seconds ago\n",
+ "File %s has %ctime %lld, %lld seconds ago\n",
pathname, type, filet, now - filet);
failure_finish(NULL);
return (0);
}
} else if (filet != t || filet_nsec != nsec) {
failure_start(file, line,
- "File %s has %ctime %ld.%09ld, expected %ld.%09ld",
+ "File %s has %ctime %lld.%09lld, expected %lld.%09lld",
pathname, type, filet, filet_nsec, t, nsec);
failure_finish(NULL);
return (0);
@@ -1380,6 +1610,110 @@ assertion_umask(const char *file, int line, int mask)
return (1);
}
+/* Set times, report failures. */
+int
+assertion_utimes(const char *file, int line,
+ const char *pathname, long at, long at_nsec, long mt, long mt_nsec)
+{
+ int r;
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#define WINTIME(sec, nsec) ((Int32x32To64(sec, 10000000) + EPOC_TIME)\
+ + (((nsec)/1000)*10))
+ HANDLE h;
+ ULARGE_INTEGER wintm;
+ FILETIME fatime, fmtime;
+ FILETIME *pat, *pmt;
+
+ assertion_count(file, line);
+ h = CreateFileA(pathname,GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (h == INVALID_HANDLE_VALUE) {
+ failure_start(file, line, "Can't access %s\n", pathname);
+ failure_finish(NULL);
+ return (0);
+ }
+
+ if (at > 0 || at_nsec > 0) {
+ wintm.QuadPart = WINTIME(at, at_nsec);
+ fatime.dwLowDateTime = wintm.LowPart;
+ fatime.dwHighDateTime = wintm.HighPart;
+ pat = &fatime;
+ } else
+ pat = NULL;
+ if (mt > 0 || mt_nsec > 0) {
+ wintm.QuadPart = WINTIME(mt, mt_nsec);
+ fmtime.dwLowDateTime = wintm.LowPart;
+ fmtime.dwHighDateTime = wintm.HighPart;
+ pmt = &fmtime;
+ } else
+ pmt = NULL;
+ if (pat != NULL || pmt != NULL)
+ r = SetFileTime(h, NULL, pat, pmt);
+ else
+ r = 1;
+ CloseHandle(h);
+ if (r == 0) {
+ failure_start(file, line, "Can't SetFileTime %s\n", pathname);
+ failure_finish(NULL);
+ return (0);
+ }
+ return (1);
+#else /* defined(_WIN32) && !defined(__CYGWIN__) */
+ struct stat st;
+ struct timeval times[2];
+
+#if !defined(__FreeBSD__)
+ mt_nsec = at_nsec = 0; /* Generic POSIX only has whole seconds. */
+#endif
+ if (mt == 0 && mt_nsec == 0 && at == 0 && at_nsec == 0)
+ return (1);
+
+ r = lstat(pathname, &st);
+ if (r < 0) {
+ failure_start(file, line, "Can't stat %s\n", pathname);
+ failure_finish(NULL);
+ return (0);
+ }
+
+ if (mt == 0 && mt_nsec == 0) {
+ mt = st.st_mtime;
+#if defined(__FreeBSD__)
+ mt_nsec = st.st_mtimespec.tv_nsec;
+ /* FreeBSD generally only stores to microsecond res, so round. */
+ mt_nsec = (mt_nsec / 1000) * 1000;
+#endif
+ }
+ if (at == 0 && at_nsec == 0) {
+ at = st.st_atime;
+#if defined(__FreeBSD__)
+ at_nsec = st.st_atimespec.tv_nsec;
+ /* FreeBSD generally only stores to microsecond res, so round. */
+ at_nsec = (at_nsec / 1000) * 1000;
+#endif
+ }
+
+ times[1].tv_sec = mt;
+ times[1].tv_usec = mt_nsec / 1000;
+
+ times[0].tv_sec = at;
+ times[0].tv_usec = at_nsec / 1000;
+
+#ifdef HAVE_LUTIMES
+ r = lutimes(pathname, times);
+#else
+ r = utimes(pathname, times);
+#endif
+ if (r < 0) {
+ failure_start(file, line, "Can't utimes %s\n", pathname);
+ failure_finish(NULL);
+ return (0);
+ }
+ return (1);
+#endif /* defined(_WIN32) && !defined(__CYGWIN__) */
+}
+
/*
*
* UTILITIES for use by tests.
@@ -1605,6 +1939,27 @@ extract_reference_file(const char *name)
fclose(in);
}
+int
+is_LargeInode(const char *file)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ BY_HANDLE_FILE_INFORMATION bhfi;
+ int r;
+
+ r = my_GetFileInformationByName(file, &bhfi);
+ if (r != 0)
+ return (0);
+ return (bhfi.nFileIndexHigh & 0x0000FFFFUL);
+#else
+ struct stat st;
+ int64_t ino;
+
+ if (stat(file, &st) < 0)
+ return (0);
+ ino = (int64_t)st.st_ino;
+ return (ino > 0xffffffff);
+#endif
+}
/*
*
* TEST management
@@ -1634,7 +1989,7 @@ struct { void (*func)(void); const char *name; int failures; } tests[] = {
* Summarize repeated failures in the just-completed test.
*/
static void
-test_summarize(const char *filename, int failed)
+test_summarize(int failed)
{
unsigned int i;
@@ -1653,9 +2008,10 @@ test_summarize(const char *filename, int failed)
for (i = 0; i < sizeof(failed_lines)/sizeof(failed_lines[0]); i++) {
if (failed_lines[i].count > 1 && !failed_lines[i].skip)
logprintf("%s:%d: Summary: Failed %d times\n",
- filename, i, failed_lines[i].count);
+ failed_filename, i, failed_lines[i].count);
}
/* Clear the failure history for the next file. */
+ failed_filename = NULL;
memset(failed_lines, 0, sizeof(failed_lines));
}
@@ -1665,6 +2021,7 @@ test_summarize(const char *filename, int failed)
static int
test_run(int i, const char *tmpdir)
{
+ char workdir[1024];
char logfilename[64];
int failures_before = failures;
int oldumask;
@@ -1691,11 +2048,12 @@ test_run(int i, const char *tmpdir)
logfile = fopen(logfilename, "w");
fprintf(logfile, "%s\n\n", tests[i].name);
/* Chdir() to a work dir for this specific test. */
- if (!assertMakeDir(tests[i].name, 0755)
- || !assertChdir(tests[i].name)) {
+ snprintf(workdir, sizeof(workdir), "%s/%s", tmpdir, tests[i].name);
+ testworkdir = workdir;
+ if (!assertMakeDir(testworkdir, 0755)
+ || !assertChdir(testworkdir)) {
fprintf(stderr,
- "ERROR: Can't chdir to work dir %s/%s\n",
- tmpdir, tests[i].name);
+ "ERROR: Can't chdir to work dir %s\n", testworkdir);
exit(1);
}
/* Explicitly reset the locale before each test. */
@@ -1709,6 +2067,7 @@ test_run(int i, const char *tmpdir)
/*
* Clean up and report afterwards.
*/
+ testworkdir = NULL;
/* Restore umask */
umask(oldumask);
/* Reset locale. */
@@ -1721,7 +2080,7 @@ test_run(int i, const char *tmpdir)
}
/* Report per-test summaries. */
tests[i].failures = failures - failures_before;
- test_summarize(test_filename, tests[i].failures);
+ test_summarize(tests[i].failures);
/* Close the per-test log file. */
fclose(logfile);
logfile = NULL;
@@ -1781,6 +2140,7 @@ usage(const char *program)
printf(" -q Quiet.\n");
printf(" -r <dir> Path to dir containing reference files.\n");
printf(" Default: Current directory.\n");
+ printf(" -u Keep running specifies tests until one fails.\n");
printf(" -v Verbose.\n");
printf("Available tests:\n");
for (i = 0; i < limit; i++)
@@ -1807,7 +2167,11 @@ get_refdir(const char *d)
}
/* Get the current dir. */
+#ifdef PATH_MAX
+ pwd = getcwd(NULL, PATH_MAX);/* Solaris getcwd needs the size. */
+#else
pwd = getcwd(NULL, 0);
+#endif
while (pwd[strlen(pwd) - 1] == '\n')
pwd[strlen(pwd) - 1] = '\0';
@@ -1834,6 +2198,14 @@ get_refdir(const char *d)
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
+#if defined(PROGRAM_ALIAS)
+ snprintf(buff, sizeof(buff), "%s/%s/test", pwd, PROGRAM_ALIAS);
+ p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
+ if (p != NULL) goto success;
+ strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
+ strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
+#endif
+
if (memcmp(pwd, "/usr/obj", 8) == 0) {
snprintf(buff, sizeof(buff), "%s", pwd + 8);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
@@ -1866,16 +2238,26 @@ int
main(int argc, char **argv)
{
static const int limit = sizeof(tests) / sizeof(tests[0]);
- int i, tests_run = 0, tests_failed = 0, option;
+ int i = 0, j = 0, start, end, tests_run = 0, tests_failed = 0, option;
time_t now;
char *refdir_alloc = NULL;
const char *progname;
+ char **saved_argv;
const char *tmp, *option_arg, *p;
- char tmpdir[256];
+ char tmpdir[256], *pwd, *testprogdir, *tmp2 = NULL;
char tmpdir_timestamp[256];
(void)argc; /* UNUSED */
+ /* Get the current dir. */
+#ifdef PATH_MAX
+ pwd = getcwd(NULL, PATH_MAX);/* Solaris getcwd needs the size. */
+#else
+ pwd = getcwd(NULL, 0);
+#endif
+ while (pwd[strlen(pwd) - 1] == '\n')
+ pwd[strlen(pwd) - 1] = '\0';
+
#if defined(HAVE__CrtSetReportMode)
/* To stop to run the default invalid parameter handler. */
_set_invalid_parameter_handler(invalid_parameter_handler);
@@ -1888,11 +2270,35 @@ main(int argc, char **argv)
* tree.
*/
progname = p = argv[0];
+ if ((testprogdir = (char *)malloc(strlen(progname) + 1)) == NULL)
+ {
+ fprintf(stderr, "ERROR: Out of memory.");
+ exit(1);
+ }
+ strcpy(testprogdir, progname);
while (*p != '\0') {
/* Support \ or / dir separators for Windows compat. */
if (*p == '/' || *p == '\\')
+ {
progname = p + 1;
+ i = j;
+ }
++p;
+ j++;
+ }
+ testprogdir[i] = '\0';
+ if (testprogdir[0] != '/')
+ {
+ /* Fixup path for relative directories. */
+ if ((testprogdir = (char *)realloc(testprogdir,
+ strlen(pwd) + 1 + strlen(testprogdir) + 1)) == NULL)
+ {
+ fprintf(stderr, "ERROR: Out of memory.");
+ exit(1);
+ }
+ strcpy(testprogdir + strlen(pwd) + 1, testprogdir);
+ strcpy(testprogdir, pwd);
+ testprogdir[strlen(pwd)] = '/';
}
#ifdef PROGRAM
@@ -1957,6 +2363,7 @@ main(int argc, char **argv)
#ifdef PROGRAM
testprogfile = option_arg;
#else
+ fprintf(stderr, "-p option not permitted\n");
usage(progname);
#endif
break;
@@ -1966,10 +2373,15 @@ main(int argc, char **argv)
case 'r':
refdir = option_arg;
break;
+ case 'u':
+ until_failure++;
+ break;
case 'v':
verbosity++;
break;
default:
+ fprintf(stderr, "Unrecognized option '%c'\n",
+ option);
usage(progname);
}
}
@@ -1980,7 +2392,19 @@ main(int argc, char **argv)
*/
#ifdef PROGRAM
if (testprogfile == NULL)
- usage(progname);
+ {
+ if ((tmp2 = (char *)malloc(strlen(testprogdir) + 1 +
+ strlen(PROGRAM) + 1)) == NULL)
+ {
+ fprintf(stderr, "ERROR: Out of memory.");
+ exit(1);
+ }
+ strcpy(tmp2, testprogdir);
+ strcat(tmp2, "/");
+ strcat(tmp2, PROGRAM);
+ testprogfile = tmp2;
+ }
+
{
char *testprg;
#if defined(_WIN32) && !defined(__CYGWIN__)
@@ -2001,6 +2425,16 @@ main(int argc, char **argv)
}
#endif
+#if !defined(_WIN32) && defined(SIGPIPE)
+ { /* Ignore SIGPIPE signals */
+ struct sigaction sa;
+ sa.sa_handler = SIG_IGN;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ sigaction(SIGPIPE, &sa, NULL);
+ }
+#endif
+
/*
* Create a temp directory for the following tests.
* Include the time the tests started as part of the name,
@@ -2053,42 +2487,88 @@ main(int argc, char **argv)
/*
* Run some or all of the individual tests.
*/
- if (*argv == NULL) {
- /* Default: Run all tests. */
- for (i = 0; i < limit; i++) {
- if (test_run(i, tmpdir))
- tests_failed++;
- tests_run++;
- }
- } else {
- while (*(argv) != NULL) {
- if (**argv >= '0' && **argv <= '9') {
- i = atoi(*argv);
- if (i < 0 || i >= limit) {
- printf("*** INVALID Test %s\n", *argv);
- free(refdir_alloc);
- usage(progname);
- /* usage() never returns */
+ saved_argv = argv;
+ do {
+ argv = saved_argv;
+ if (*argv == NULL) {
+ /* Default: Run all tests. */
+ for (i = 0; i < limit; i++) {
+ tests_run++;
+ if (test_run(i, tmpdir)) {
+ tests_failed++;
+ if (until_failure)
+ goto finish;
}
- } else {
- for (i = 0; i < limit; ++i) {
- if (strcmp(*argv, tests[i].name) == 0)
- break;
+ }
+ } else {
+ while (*(argv) != NULL) {
+ if (**argv >= '0' && **argv <= '9') {
+ char *p = *argv;
+ start = 0;
+ while (*p >= '0' && *p <= '9') {
+ start *= 10;
+ start += *p - '0';
+ ++p;
+ }
+ if (*p == '\0') {
+ end = start;
+ } else if (*p == '-') {
+ ++p;
+ if (*p == '\0') {
+ end = limit - 1;
+ } else {
+ end = 0;
+ while (*p >= '0' && *p <= '9') {
+ end *= 10;
+ end += *p - '0';
+ ++p;
+ }
+ }
+ } else {
+ printf("*** INVALID Test %s\n", *argv);
+ free(refdir_alloc);
+ usage(progname);
+ return (1);
+ }
+ if (start < 0 || end >= limit || start > end) {
+ printf("*** INVALID Test %s\n", *argv);
+ free(refdir_alloc);
+ usage(progname);
+ return (1);
+ }
+ } else {
+ for (start = 0; start < limit; ++start) {
+ if (strcmp(*argv, tests[start].name) == 0)
+ break;
+ }
+ end = start;
+ if (start >= limit) {
+ printf("*** INVALID Test ``%s''\n",
+ *argv);
+ free(refdir_alloc);
+ usage(progname);
+ /* usage() never returns */
+ }
}
- if (i >= limit) {
- printf("*** INVALID Test ``%s''\n",
- *argv);
- free(refdir_alloc);
- usage(progname);
- /* usage() never returns */
+ while (start <= end) {
+ tests_run++;
+ if (test_run(start, tmpdir)) {
+ tests_failed++;
+ if (until_failure)
+ goto finish;
+ }
+ ++start;
}
+ argv++;
}
- if (test_run(i, tmpdir))
- tests_failed++;
- tests_run++;
- argv++;
}
- }
+ } while (until_failure);
+
+finish:
+ /* Must be freed after all tests run */
+ free(tmp2);
+ free(testprogdir);
+ free(pwd);
/*
* Report summary statistics.
diff --git a/libarchive/test/read_open_memory.c b/libarchive/test/read_open_memory.c
index e4e911c2f8b5..d7e203b20e8d 100644
--- a/libarchive/test/read_open_memory.c
+++ b/libarchive/test/read_open_memory.c
@@ -39,7 +39,8 @@ __FBSDID("$FreeBSD: head/lib/libarchive/test/read_open_memory.c 191183 2009-04-1
*/
struct read_memory_data {
- unsigned char *buffer;
+ unsigned char *start;
+ unsigned char *p;
unsigned char *end;
size_t read_size;
size_t copy_buff_size;
@@ -49,7 +50,8 @@ struct read_memory_data {
static int memory_read_close(struct archive *, void *);
static int memory_read_open(struct archive *, void *);
-static off_t memory_read_skip(struct archive *, void *, off_t request);
+static int64_t memory_read_seek(struct archive *, void *, int64_t request, int whence);
+static int64_t memory_read_skip(struct archive *, void *, int64_t request);
static ssize_t memory_read(struct archive *, void *, const void **buff);
static int read_open_memory_internal(struct archive *a, void *buff,
size_t size, size_t read_size, int fullapi);
@@ -58,7 +60,7 @@ static int read_open_memory_internal(struct archive *a, void *buff,
int
read_open_memory(struct archive *a, void *buff, size_t size, size_t read_size)
{
- return read_open_memory_internal(a, buff, size, read_size, 1);
+ return read_open_memory_internal(a, buff, size, read_size, 2);
}
/*
@@ -68,12 +70,21 @@ read_open_memory(struct archive *a, void *buff, size_t size, size_t read_size)
int
read_open_memory2(struct archive *a, void *buff, size_t size, size_t read_size)
{
- return read_open_memory_internal(a, buff, size, read_size, 0);
+ return read_open_memory_internal(a, buff, size, read_size, 1);
+}
+
+/*
+ * Include a seek callback as well.
+ */
+int
+read_open_memory_seek(struct archive *a, void *buff, size_t size, size_t read_size)
+{
+ return read_open_memory_internal(a, buff, size, read_size, 3);
}
static int
read_open_memory_internal(struct archive *a, void *buff,
- size_t size, size_t read_size, int fullapi)
+ size_t size, size_t read_size, int level)
{
struct read_memory_data *mine;
@@ -83,19 +94,26 @@ read_open_memory_internal(struct archive *a, void *buff,
return (ARCHIVE_FATAL);
}
memset(mine, 0, sizeof(*mine));
- mine->buffer = (unsigned char *)buff;
- mine->end = mine->buffer + size;
+ mine->start = mine->p = (unsigned char *)buff;
+ mine->end = mine->start + size;
mine->read_size = read_size;
mine->copy_buff_offset = 32;
mine->copy_buff_size = read_size + mine->copy_buff_offset * 2;
mine->copy_buff = malloc(mine->copy_buff_size);
memset(mine->copy_buff, 0xA5, mine->copy_buff_size);
- if (fullapi)
- return (archive_read_open2(a, mine, memory_read_open,
- memory_read, memory_read_skip, memory_read_close));
- else
- return (archive_read_open2(a, mine, NULL,
- memory_read, NULL, memory_read_close));
+
+ switch (level) {
+ case 3:
+ archive_read_set_seek_callback(a, memory_read_seek);
+ case 2:
+ archive_read_set_open_callback(a, memory_read_open);
+ archive_read_set_skip_callback(a, memory_read_skip);
+ case 1:
+ archive_read_set_read_callback(a, memory_read);
+ archive_read_set_close_callback(a, memory_read_close);
+ archive_read_set_callback_data(a, mine);
+ }
+ return archive_read_open1(a);
}
/*
@@ -119,41 +137,75 @@ static ssize_t
memory_read(struct archive *a, void *client_data, const void **buff)
{
struct read_memory_data *mine = (struct read_memory_data *)client_data;
- size_t size;
+ ssize_t size;
(void)a; /* UNUSED */
- size = mine->end - mine->buffer;
- if (size > mine->read_size)
+ size = mine->end - mine->p;
+ if (size < 0) {
+ buff = NULL;
+ return 0;
+ }
+ if ((size_t)size > mine->read_size)
size = mine->read_size;
else
memset(mine->copy_buff, 0xA5, mine->copy_buff_size);
- memcpy(mine->copy_buff + mine->copy_buff_offset, mine->buffer, size);
+ memcpy(mine->copy_buff + mine->copy_buff_offset, mine->p, size);
*buff = mine->copy_buff + mine->copy_buff_offset;
- mine->buffer += size;
+ mine->p += size;
return ((ssize_t)size);
}
/*
* How mean can a skip() routine be? Let's try to find out.
*/
-static off_t
-memory_read_skip(struct archive *a, void *client_data, off_t skip)
+static int64_t
+memory_read_skip(struct archive *a, void *client_data, int64_t skip)
{
struct read_memory_data *mine = (struct read_memory_data *)client_data;
(void)a; /* UNUSED */
/* We can't skip by more than is available. */
- if ((off_t)skip > (off_t)(mine->end - mine->buffer))
- skip = mine->end - mine->buffer;
+ if ((off_t)skip > (off_t)(mine->end - mine->p))
+ skip = mine->end - mine->p;
/* Always do small skips by prime amounts. */
if (skip > 71)
skip = 71;
- mine->buffer += skip;
+ mine->p += skip;
return (skip);
}
/*
+ */
+static int64_t
+memory_read_seek(struct archive *a, void *client_data, int64_t offset, int whence)
+{
+ struct read_memory_data *mine = (struct read_memory_data *)client_data;
+
+ (void)a; /* UNUSED */
+ switch (whence) {
+ case SEEK_SET:
+ mine->p = mine->start + offset;
+ break;
+ case SEEK_END:
+ mine->p = mine->end + offset;
+ break;
+ case SEEK_CUR:
+ mine->p += offset;
+ break;
+ }
+ if (mine->p < mine->start) {
+ mine->p = mine->start;
+ return ARCHIVE_FAILED;
+ }
+ if (mine->p > mine->end) {
+ mine->p = mine->end;
+ return ARCHIVE_FAILED;
+ }
+ return (mine->p - mine->start);
+}
+
+/*
* Close is just cleaning up our one small bit of data.
*/
static int
diff --git a/libarchive/test/test.h b/libarchive/test/test.h
index 40c31e13dba6..4c82ece92d45 100644
--- a/libarchive/test/test.h
+++ b/libarchive/test/test.h
@@ -86,9 +86,6 @@
#if !defined(__BORLANDC__)
#define strdup _strdup
#endif
-#define LOCALE_UTF8 NULL
-#else
-#define LOCALE_UTF8 "de_DE.UTF-8"
#endif
/* Visual Studio */
@@ -100,16 +97,9 @@
#pragma warn -8068 /* Constant out of range in comparison. */
#endif
-/* Cygwin */
-#if defined(__CYGWIN__)
-/* Cygwin-1.7.x is lazy about populating nlinks, so don't
- * expect it to be accurate. */
-# define NLINKS_INACCURATE_FOR_DIRS
-#endif
-
-/* Haiku OS */
-#if defined(__HAIKU__)
-/* Haiku has typedefs in stdint.h (needed for int64_t) */
+/* Haiku OS and QNX */
+#if defined(__HAIKU__) || defined(__QNXNTO__)
+/* Haiku and QNX have typedefs in stdint.h (needed for int64_t) */
#include <stdint.h>
#endif
@@ -143,24 +133,24 @@
assertion_equal_int(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
/* Assert two strings are the same. Reports value of each one if not. */
#define assertEqualString(v1,v2) \
- assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
+ assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL, 0)
+#define assertEqualUTF8String(v1,v2) \
+ assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL, 1)
/* As above, but v1 and v2 are wchar_t * */
#define assertEqualWString(v1,v2) \
assertion_equal_wstring(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
/* As above, but raw blocks of bytes. */
#define assertEqualMem(v1, v2, l) \
assertion_equal_mem(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (l), #l, NULL)
-/* Assert two files are the same; allow printf-style expansion of second name.
- * See below for comments about variable arguments here...
- */
-#define assertEqualFile \
- assertion_setup(__FILE__, __LINE__);assertion_equal_file
-/* Assert that a file is empty; supports printf-style arguments. */
-#define assertEmptyFile \
- assertion_setup(__FILE__, __LINE__);assertion_empty_file
-/* Assert that a file is not empty; supports printf-style arguments. */
-#define assertNonEmptyFile \
- assertion_setup(__FILE__, __LINE__);assertion_non_empty_file
+/* Assert two files are the same. */
+#define assertEqualFile(f1, f2) \
+ assertion_equal_file(__FILE__, __LINE__, (f1), (f2))
+/* Assert that a file is empty. */
+#define assertEmptyFile(pathname) \
+ assertion_empty_file(__FILE__, __LINE__, (pathname))
+/* Assert that a file is not empty. */
+#define assertNonEmptyFile(pathname) \
+ assertion_non_empty_file(__FILE__, __LINE__, (pathname))
#define assertFileAtime(pathname, sec, nsec) \
assertion_file_atime(__FILE__, __LINE__, pathname, sec, nsec)
#define assertFileAtimeRecent(pathname) \
@@ -170,14 +160,14 @@
#define assertFileBirthtimeRecent(pathname) \
assertion_file_birthtime_recent(__FILE__, __LINE__, pathname)
/* Assert that a file exists; supports printf-style arguments. */
-#define assertFileExists \
- assertion_setup(__FILE__, __LINE__);assertion_file_exists
-/* Assert that a file exists; supports printf-style arguments. */
-#define assertFileNotExists \
- assertion_setup(__FILE__, __LINE__);assertion_file_not_exists
-/* Assert that file contents match a string; supports printf-style arguments. */
-#define assertFileContents \
- assertion_setup(__FILE__, __LINE__);assertion_file_contents
+#define assertFileExists(pathname) \
+ assertion_file_exists(__FILE__, __LINE__, pathname)
+/* Assert that a file exists. */
+#define assertFileNotExists(pathname) \
+ assertion_file_not_exists(__FILE__, __LINE__, pathname)
+/* Assert that file contents match a string. */
+#define assertFileContents(data, data_size, pathname) \
+ assertion_file_contents(__FILE__, __LINE__, data, data_size, pathname)
#define assertFileMtime(pathname, sec, nsec) \
assertion_file_mtime(__FILE__, __LINE__, pathname, sec, nsec)
#define assertFileMtimeRecent(pathname) \
@@ -186,8 +176,10 @@
assertion_file_nlinks(__FILE__, __LINE__, pathname, nlinks)
#define assertFileSize(pathname, size) \
assertion_file_size(__FILE__, __LINE__, pathname, size)
-#define assertTextFileContents \
- assertion_setup(__FILE__, __LINE__);assertion_text_file_contents
+#define assertTextFileContents(text, pathname) \
+ assertion_text_file_contents(__FILE__, __LINE__, text, pathname)
+#define assertFileContainsLinesAnyOrder(pathname, lines) \
+ assertion_file_contains_lines_any_order(__FILE__, __LINE__, pathname, lines)
#define assertIsDir(pathname, mode) \
assertion_is_dir(__FILE__, __LINE__, pathname, mode)
#define assertIsHardlink(path1, path2) \
@@ -209,6 +201,8 @@
assertion_make_symlink(__FILE__, __LINE__, newfile, linkto)
#define assertUmask(mask) \
assertion_umask(__FILE__, __LINE__, mask)
+#define assertUtimes(pathname, atime, atime_nsec, mtime, mtime_nsec) \
+ assertion_utimes(__FILE__, __LINE__, pathname, atime, atime_nsec, mtime, mtime_nsec)
/*
* This would be simple with C99 variadic macros, but I don't want to
@@ -217,28 +211,29 @@
* but effective.
*/
#define skipping \
- assertion_setup(__FILE__, __LINE__);test_skipping
+ skipping_setup(__FILE__, __LINE__);test_skipping
/* Function declarations. These are defined in test_utility.c. */
void failure(const char *fmt, ...);
int assertion_assert(const char *, int, int, const char *, void *);
int assertion_chdir(const char *, int, const char *);
-int assertion_empty_file(const char *, ...);
-int assertion_equal_file(const char *, const char *, ...);
+int assertion_empty_file(const char *, int, const char *);
+int assertion_equal_file(const char *, int, const char *, const char *);
int assertion_equal_int(const char *, int, long long, const char *, long long, const char *, void *);
int assertion_equal_mem(const char *, int, const void *, const char *, const void *, const char *, size_t, const char *, void *);
-int assertion_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *);
+int assertion_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *, int);
int assertion_equal_wstring(const char *, int, const wchar_t *v1, const char *, const wchar_t *v2, const char *, void *);
int assertion_file_atime(const char *, int, const char *, long, long);
int assertion_file_atime_recent(const char *, int, const char *);
int assertion_file_birthtime(const char *, int, const char *, long, long);
int assertion_file_birthtime_recent(const char *, int, const char *);
-int assertion_file_contents(const void *, int, const char *, ...);
-int assertion_file_exists(const char *, ...);
+int assertion_file_contains_lines_any_order(const char *, int, const char *, const char **);
+int assertion_file_contents(const char *, int, const void *, int, const char *);
+int assertion_file_exists(const char *, int, const char *);
int assertion_file_mtime(const char *, int, const char *, long, long);
int assertion_file_mtime_recent(const char *, int, const char *);
int assertion_file_nlinks(const char *, int, const char *, int);
-int assertion_file_not_exists(const char *, ...);
+int assertion_file_not_exists(const char *, int, const char *);
int assertion_file_size(const char *, int, const char *, long);
int assertion_is_dir(const char *, int, const char *, int);
int assertion_is_hardlink(const char *, int, const char *, const char *);
@@ -249,11 +244,12 @@ int assertion_make_dir(const char *, int, const char *, int);
int assertion_make_file(const char *, int, const char *, int, const char *);
int assertion_make_hardlink(const char *, int, const char *newpath, const char *);
int assertion_make_symlink(const char *, int, const char *newpath, const char *);
-int assertion_non_empty_file(const char *, ...);
-int assertion_text_file_contents(const char *buff, const char *f);
+int assertion_non_empty_file(const char *, int, const char *);
+int assertion_text_file_contents(const char *, int, const char *buff, const char *f);
int assertion_umask(const char *, int, int);
-void assertion_setup(const char *, int);
+int assertion_utimes(const char *, int, const char *, long, long, long, long );
+void skipping_setup(const char *, int);
void test_skipping(const char *fmt, ...);
/* Like sprintf, then system() */
@@ -271,6 +267,9 @@ int canGzip(void);
/* Return true if this platform can run the "gunzip" program. */
int canGunzip(void);
+/* Return true if the file has large i-node number(>0xffffffff). */
+int is_LargeInode(const char *);
+
/* Suck file into string allocated via malloc(). Call free() when done. */
/* Supports printf-style args: slurpfile(NULL, "%s/myfile", refdir); */
char *slurpfile(size_t *, const char *fmt, ...);
@@ -278,6 +277,9 @@ char *slurpfile(size_t *, const char *fmt, ...);
/* Extracts named reference file to the current directory. */
void extract_reference_file(const char *);
+/* Path to working directory for current test */
+const char *testworkdir;
+
/*
* Special interfaces for libarchive test harness.
*/
@@ -289,13 +291,15 @@ void extract_reference_file(const char *);
int read_open_memory(struct archive *, void *, size_t, size_t);
/* "2" version exercises a slightly different set of libarchive APIs. */
int read_open_memory2(struct archive *, void *, size_t, size_t);
+/* _seek version produces a seekable file. */
+int read_open_memory_seek(struct archive *, void *, size_t, size_t);
/* Versions of above that accept an archive argument for additional info. */
#define assertA(e) assertion_assert(__FILE__, __LINE__, (e), #e, (a))
#define assertEqualIntA(a,v1,v2) \
assertion_equal_int(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (a))
#define assertEqualStringA(a,v1,v2) \
- assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (a))
+ assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (a), 0)
#ifdef USE_DMALLOC
#include <dmalloc.h>
diff --git a/libarchive/test/test_acl_freebsd.c b/libarchive/test/test_acl_freebsd.c
index c684a7ae9e81..1680f9f80e55 100644
--- a/libarchive/test/test_acl_freebsd.c
+++ b/libarchive/test/test_acl_freebsd.c
@@ -222,7 +222,7 @@ DEFINE_TEST(test_acl_freebsd)
}
if (n != 0 && errno == EINVAL) {
close(fd);
- skipping("POSIX.1e ACL tests require that POSIX.1e ACL support be enabled on the filesystem");
+ skipping("This filesystem does not support POSIX.1e ACLs");
return;
}
failure("acl_set_fd(): errno = %d (%s)",
@@ -247,7 +247,7 @@ DEFINE_TEST(test_acl_freebsd)
/* Close the archive. */
assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
- assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/* Verify the data on disk. */
assertEqualInt(0, stat("test0", &st));
diff --git a/libarchive/test/test_acl_nfs4.c b/libarchive/test/test_acl_nfs4.c
new file mode 100644
index 000000000000..820b9d60f674
--- /dev/null
+++ b/libarchive/test/test_acl_nfs4.c
@@ -0,0 +1,291 @@
+/*-
+ * Copyright (c) 2003-2010 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+/*
+ * Exercise the system-independent portion of the ACL support.
+ * Check that archive_entry objects can save and restore NFS4 ACL data.
+ *
+ * This should work on all systems, regardless of whether local
+ * filesystems support ACLs or not.
+ */
+
+struct acl_t {
+ int type; /* Type of entry: "allow" or "deny" */
+ int permset; /* Permissions for this class of users. */
+ int tag; /* Owner, User, Owning group, group, everyone, etc. */
+ int qual; /* GID or UID of user/group, depending on tag. */
+ const char *name; /* Name of user/group, depending on tag. */
+};
+
+static struct acl_t acls1[] = {
+ { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
+ ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
+ { ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_READ_DATA,
+ ARCHIVE_ENTRY_ACL_USER, 77, "user77" },
+ { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_DATA,
+ ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
+ { ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_WRITE_DATA,
+ ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" },
+};
+
+static struct acl_t acls2[] = {
+ /* An entry for each type. */
+ { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 0,
+ ARCHIVE_ENTRY_ACL_USER, 108, "user108" },
+ { ARCHIVE_ENTRY_ACL_TYPE_DENY, 0,
+ ARCHIVE_ENTRY_ACL_USER, 109, "user109" },
+ { ARCHIVE_ENTRY_ACL_TYPE_AUDIT, 0,
+ ARCHIVE_ENTRY_ACL_USER, 110, "user110" },
+ { ARCHIVE_ENTRY_ACL_TYPE_ALARM, 0,
+ ARCHIVE_ENTRY_ACL_USER, 111, "user111" },
+
+ /* An entry for each permission. */
+ { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
+ ARCHIVE_ENTRY_ACL_USER, 112, "user112" },
+ { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_DATA,
+ ARCHIVE_ENTRY_ACL_USER, 113, "user113" },
+ { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
+ ARCHIVE_ENTRY_ACL_USER, 114, "user114" },
+ { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_DATA,
+ ARCHIVE_ENTRY_ACL_USER, 115, "user115" },
+ { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_ADD_FILE,
+ ARCHIVE_ENTRY_ACL_USER, 116, "user116" },
+ { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_APPEND_DATA,
+ ARCHIVE_ENTRY_ACL_USER, 117, "user117" },
+ { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY,
+ ARCHIVE_ENTRY_ACL_USER, 118, "user118" },
+ { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS,
+ ARCHIVE_ENTRY_ACL_USER, 119, "user119" },
+ { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS,
+ ARCHIVE_ENTRY_ACL_USER, 120, "user120" },
+ { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_DELETE_CHILD,
+ ARCHIVE_ENTRY_ACL_USER, 121, "user121" },
+ { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES,
+ ARCHIVE_ENTRY_ACL_USER, 122, "user122" },
+ { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES,
+ ARCHIVE_ENTRY_ACL_USER, 123, "user123" },
+ { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_DELETE,
+ ARCHIVE_ENTRY_ACL_USER, 124, "user124" },
+ { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ACL,
+ ARCHIVE_ENTRY_ACL_USER, 125, "user125" },
+ { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_ACL,
+ ARCHIVE_ENTRY_ACL_USER, 126, "user126" },
+ { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_OWNER,
+ ARCHIVE_ENTRY_ACL_USER, 127, "user127" },
+ { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
+ ARCHIVE_ENTRY_ACL_USER, 128, "user128" },
+
+ /* One entry with each inheritance value. */
+ { ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
+ ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT,
+ ARCHIVE_ENTRY_ACL_USER, 129, "user129" },
+ { ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
+ ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT,
+ ARCHIVE_ENTRY_ACL_USER, 130, "user130" },
+ { ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
+ ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT,
+ ARCHIVE_ENTRY_ACL_USER, 131, "user131" },
+ { ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
+ ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY,
+ ARCHIVE_ENTRY_ACL_USER, 132, "user132" },
+ { ARCHIVE_ENTRY_ACL_TYPE_AUDIT,
+ ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS,
+ ARCHIVE_ENTRY_ACL_USER, 133, "user133" },
+ { ARCHIVE_ENTRY_ACL_TYPE_AUDIT,
+ ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS,
+ ARCHIVE_ENTRY_ACL_USER, 134, "user134" },
+
+ /* One entry for each qualifier. */
+ { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
+ ARCHIVE_ENTRY_ACL_USER, 135, "user135" },
+ { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
+ ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
+ { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
+ ARCHIVE_ENTRY_ACL_GROUP, 136, "group136" },
+ { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
+ ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
+ { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
+ ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" },
+};
+
+/*
+ * Entries that should be rejected when we attempt to set them
+ * on an ACL that already has NFS4 entries.
+ */
+static struct acl_t acls_bad[] = {
+ /* POSIX.1e ACL types */
+ { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE,
+ ARCHIVE_ENTRY_ACL_USER, 78, "" },
+ { ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE,
+ ARCHIVE_ENTRY_ACL_USER, 78, "" },
+
+ /* POSIX.1e tags */
+ { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
+ ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
+ { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
+ ARCHIVE_ENTRY_ACL_MASK, -1, "" },
+
+ /* POSIX.1e permissions */
+ { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ,
+ ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" },
+ { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE,
+ ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" },
+};
+
+static void
+set_acls(struct archive_entry *ae, struct acl_t *acls, int n)
+{
+ int i;
+
+ archive_entry_acl_clear(ae);
+ for (i = 0; i < n; i++) {
+ failure("type=%d, permset=%d, tag=%d, qual=%d name=%s",
+ acls[i].type, acls[i].permset, acls[i].tag,
+ acls[i].qual, acls[i].name);
+ assertEqualInt(ARCHIVE_OK,
+ archive_entry_acl_add_entry(ae,
+ acls[i].type, acls[i].permset, acls[i].tag,
+ acls[i].qual, acls[i].name));
+ }
+}
+
+static int
+acl_match(struct acl_t *acl, int type, int permset, int tag, int qual, const char *name)
+{
+ if (type != acl->type)
+ return (0);
+ if (permset != acl->permset)
+ return (0);
+ if (tag != acl->tag)
+ return (0);
+ if (tag == ARCHIVE_ENTRY_ACL_USER_OBJ)
+ return (1);
+ if (tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ)
+ return (1);
+ if (tag == ARCHIVE_ENTRY_ACL_EVERYONE)
+ return (1);
+ if (qual != acl->qual)
+ return (0);
+ if (name == NULL) {
+ if (acl->name == NULL || acl->name[0] == '\0')
+ return (1);
+ }
+ if (acl->name == NULL) {
+ if (name[0] == '\0')
+ return (1);
+ }
+ return (0 == strcmp(name, acl->name));
+}
+
+static void
+compare_acls(struct archive_entry *ae, struct acl_t *acls, int n)
+{
+ int *marker = malloc(sizeof(marker[0]) * n);
+ int i;
+ int r;
+ int type, permset, tag, qual;
+ int matched;
+ const char *name;
+
+ for (i = 0; i < n; i++)
+ marker[i] = i;
+
+ while (0 == (r = archive_entry_acl_next(ae,
+ ARCHIVE_ENTRY_ACL_TYPE_NFS4,
+ &type, &permset, &tag, &qual, &name))) {
+ for (i = 0, matched = 0; i < n && !matched; i++) {
+ if (acl_match(&acls[marker[i]], type, permset,
+ tag, qual, name)) {
+ /* We found a match; remove it. */
+ marker[i] = marker[n - 1];
+ n--;
+ matched = 1;
+ }
+ }
+ failure("Could not find match for ACL "
+ "(type=%d,permset=%d,tag=%d,qual=%d,name=``%s'')",
+ type, permset, tag, qual, name);
+ assertEqualInt(1, matched);
+ }
+ assertEqualInt(ARCHIVE_EOF, r);
+ failure("Could not find match for ACL "
+ "(type=%d,permset=%d,tag=%d,qual=%d,name=``%s'')",
+ acls[marker[0]].type, acls[marker[0]].permset,
+ acls[marker[0]].tag, acls[marker[0]].qual, acls[marker[0]].name);
+ assertEqualInt(0, n); /* Number of ACLs not matched should == 0 */
+ free(marker);
+}
+
+DEFINE_TEST(test_acl_nfs4)
+{
+ struct archive_entry *ae;
+ int i;
+
+ /* Create a simple archive_entry. */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_pathname(ae, "file");
+ archive_entry_set_mode(ae, S_IFREG | 0777);
+
+ /* Store and read back some basic ACL entries. */
+ set_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]));
+ assertEqualInt(4,
+ archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_NFS4));
+ compare_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]));
+
+ /* A more extensive set of ACLs. */
+ set_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]));
+ assertEqualInt(32,
+ archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_NFS4));
+ compare_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]));
+
+ /*
+ * Check that clearing ACLs gets rid of them all by repeating
+ * the first test.
+ */
+ set_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]));
+ failure("Basic ACLs shouldn't be stored as extended ACLs");
+ assertEqualInt(4,
+ archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_NFS4));
+
+ /*
+ * Different types of malformed ACL entries that should
+ * fail when added to existing NFS4 ACLs.
+ */
+ set_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]));
+ for (i = 0; i < sizeof(acls_bad)/sizeof(acls_bad[0]); ++i) {
+ struct acl_t *p = &acls_bad[i];
+ failure("Malformed ACL test #%d", i);
+ assertEqualInt(ARCHIVE_FAILED,
+ archive_entry_acl_add_entry(ae,
+ p->type, p->permset, p->tag, p->qual, p->name));
+ failure("Malformed ACL test #%d", i);
+ assertEqualInt(32,
+ archive_entry_acl_reset(ae,
+ ARCHIVE_ENTRY_ACL_TYPE_NFS4));
+ }
+ archive_entry_free(ae);
+}
diff --git a/libarchive/test/test_acl_pax.c b/libarchive/test/test_acl_pax.c
index 1f0468ca115a..6a7ee1516491 100644
--- a/libarchive/test/test_acl_pax.c
+++ b/libarchive/test/test_acl_pax.c
@@ -35,230 +35,6 @@ __FBSDID("$FreeBSD: head/lib/libarchive/test/test_acl_pax.c 201247 2009-12-30 05
static unsigned char buff[16384];
-static unsigned char reference[] = {
-'P','a','x','H','e','a','d','e','r','/','f','i','l','e',0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,'0','0','0','1','4','2',' ',0,'0','0','0','0','0','0',' ',0,'0','0',
-'0','0','0','0',' ',0,'0','0','0','0','0','0','0','0','0','6','2',' ','0',
-'0','0','0','0','0','0','0','0','0','0',' ','0','1','1','7','6','7',0,' ',
-'x',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'u','s','t','a','r',
-0,'0','0',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'0','0','0',
-'0','0','0',' ',0,'0','0','0','0','0','0',' ',0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,'1','6',' ','S','C','H','I','L','Y','.','d','e','v','=','0',10,
-'1','6',' ','S','C','H','I','L','Y','.','i','n','o','=','0',10,'1','8',' ',
-'S','C','H','I','L','Y','.','n','l','i','n','k','=','0',10,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,'f','i','l','e',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,'0','0','0','1','4','2',' ',0,'0','0','0','0','0','0',' ',0,'0','0',
-'0','0','0','0',' ',0,'0','0','0','0','0','0','0','0','0','0','0',' ','0',
-'0','0','0','0','0','0','0','0','0','0',' ','0','1','0','0','0','6',0,' ',
-'0',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'u','s','t','a','r',
-0,'0','0',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'0','0','0',
-'0','0','0',' ',0,'0','0','0','0','0','0',' ',0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,'P','a','x','H','e','a','d','e','r','/','f','i','l','e',0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,'0','0','0','1','4','2',' ',0,'0','0','0','0','0','0',' ',
-0,'0','0','0','0','0','0',' ',0,'0','0','0','0','0','0','0','0','1','7','2',
-' ','0','0','0','0','0','0','0','0','0','0','0',' ','0','1','1','7','7','1',
-0,' ','x',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'u','s','t',
-'a','r',0,'0','0',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'0',
-'0','0','0','0','0',' ',0,'0','0','0','0','0','0',' ',0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,'7','2',' ','S','C','H','I','L','Y','.','a','c','l','.',
-'a','c','c','e','s','s','=','u','s','e','r',':',':','-','-','x',',','g','r',
-'o','u','p',':',':','r','-','-',',','o','t','h','e','r',':',':','-','w','-',
-',','u','s','e','r',':','u','s','e','r','7','7',':','r','-','-',':','7','7',
-10,'1','6',' ','S','C','H','I','L','Y','.','d','e','v','=','0',10,'1','6',
-' ','S','C','H','I','L','Y','.','i','n','o','=','0',10,'1','8',' ','S','C',
-'H','I','L','Y','.','n','l','i','n','k','=','0',10,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,'f','i','l','e',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,'0','0','0','1','4','2',' ',0,'0','0','0','0','0','0',' ',0,'0','0','0',
-'0','0','0',' ',0,'0','0','0','0','0','0','0','0','0','0','0',' ','0','0',
-'0','0','0','0','0','0','0','0','0',' ','0','1','0','0','0','6',0,' ','0',
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'u','s','t','a','r',0,
-'0','0',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'0','0','0',
-'0','0','0',' ',0,'0','0','0','0','0','0',' ',0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,'P','a','x','H','e','a','d','e','r','/','f','i','l','e',0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,'0','0','0','5','4','3',' ',0,'0','0','0','0','0','0',' ',
-0,'0','0','0','0','0','0',' ',0,'0','0','0','0','0','0','0','0','2','4','3',
-' ','0','0','0','0','0','0','0','0','0','0','0',' ','0','1','1','7','7','5',
-0,' ','x',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'u','s','t',
-'a','r',0,'0','0',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'0',
-'0','0','0','0','0',' ',0,'0','0','0','0','0','0',' ',0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,'1','1','3',' ','S','C','H','I','L','Y','.','a','c','l',
-'.','a','c','c','e','s','s','=','u','s','e','r',':',':','r','-','x',',','g',
-'r','o','u','p',':',':','r','-','-',',','o','t','h','e','r',':',':','-','w',
-'x',',','u','s','e','r',':','u','s','e','r','7','7',':','r','-','-',':','7',
-'7',',','u','s','e','r',':','u','s','e','r','7','8',':','-','-','-',':','7',
-'8',',','g','r','o','u','p',':','g','r','o','u','p','7','8',':','r','w','x',
-':','7','8',10,'1','6',' ','S','C','H','I','L','Y','.','d','e','v','=','0',
-10,'1','6',' ','S','C','H','I','L','Y','.','i','n','o','=','0',10,'1','8',
-' ','S','C','H','I','L','Y','.','n','l','i','n','k','=','0',10,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,'f','i','l','e',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,'0','0','0','5','4','3',' ',0,'0','0','0','0','0','0',' ',0,'0','0',
-'0','0','0','0',' ',0,'0','0','0','0','0','0','0','0','0','0','0',' ','0',
-'0','0','0','0','0','0','0','0','0','0',' ','0','1','0','0','1','3',0,' ',
-'0',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'u','s','t','a','r',
-0,'0','0',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'0','0','0',
-'0','0','0',' ',0,'0','0','0','0','0','0',' ',0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,'P','a','x','H','e','a','d','e','r','/','f','i','l','e',0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,'0','0','0','1','4','2',' ',0,'0','0','0','0','0','0',' ',
-0,'0','0','0','0','0','0',' ',0,'0','0','0','0','0','0','0','0','0','6','2',
-' ','0','0','0','0','0','0','0','0','0','0','0',' ','0','1','1','7','6','7',
-0,' ','x',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'u','s','t',
-'a','r',0,'0','0',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'0',
-'0','0','0','0','0',' ',0,'0','0','0','0','0','0',' ',0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,'1','6',' ','S','C','H','I','L','Y','.','d','e','v','=',
-'0',10,'1','6',' ','S','C','H','I','L','Y','.','i','n','o','=','0',10,'1',
-'8',' ','S','C','H','I','L','Y','.','n','l','i','n','k','=','0',10,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'f','i','l','e',0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,'0','0','0','1','4','2',' ',0,'0','0','0','0','0','0',' ',
-0,'0','0','0','0','0','0',' ',0,'0','0','0','0','0','0','0','0','0','0','0',
-' ','0','0','0','0','0','0','0','0','0','0','0',' ','0','1','0','0','0','6',
-0,' ','0',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'u','s','t',
-'a','r',0,'0','0',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'0',
-'0','0','0','0','0',' ',0,'0','0','0','0','0','0',' ',0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
-
-
struct acl_t {
int type; /* Type of ACL: "access" or "default" */
int permset; /* Permissions for this class of users. */
@@ -386,12 +162,7 @@ compare_acls(struct archive_entry *ae, struct acl_t *acls, int n, int mode)
assert(matched == 1);
}
}
-#if ARCHIVE_VERSION_NUMBER < 1009000
- /* Known broken before 1.9.0. */
- skipping("archive_entry_acl_next() exits with ARCHIVE_EOF");
-#else
assertEqualInt(ARCHIVE_EOF, r);
-#endif
assert((mode & 0777) == (archive_entry_mode(ae) & 0777));
failure("Could not find match for ACL "
"(type=%d,permset=%d,tag=%d,qual=%d,name=``%s'')",
@@ -407,6 +178,8 @@ DEFINE_TEST(test_acl_pax)
struct archive_entry *ae;
size_t used;
FILE *f;
+ void *reference;
+ size_t reference_size;
/* Write an archive to memory. */
assert(NULL != (a = archive_write_new()));
@@ -445,12 +218,8 @@ DEFINE_TEST(test_acl_pax)
archive_entry_free(ae);
/* Close out the archive. */
- assertA(0 == archive_write_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_write_finish(a);
-#else
- assertA(0 == archive_write_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/* Write out the data we generated to a file for manual inspection. */
assert(NULL != (f = fopen("testout", "wb")));
@@ -458,20 +227,20 @@ DEFINE_TEST(test_acl_pax)
fclose(f);
/* Write out the reference data to a file for manual inspection. */
- assert(NULL != (f = fopen("reference", "wb")));
- assert(sizeof(reference) == fwrite(reference, 1, sizeof(reference), f));
- fclose(f);
+ extract_reference_file("test_acl_pax.tar");
+ reference = slurpfile(&reference_size, "test_acl_pax.tar");
/* Assert that the generated data matches the built-in reference data.*/
- failure("Generated pax archive does not match reference; check 'testout' and 'reference' files.");
- assertEqualMem(buff, reference, sizeof(reference));
- failure("Generated pax archive does not match reference; check 'testout' and 'reference' files.");
- assertEqualInt((int)used, sizeof(reference));
+ failure("Generated pax archive does not match reference; compare 'testout' to 'test_acl_pax.tar' reference file.");
+ assertEqualMem(buff, reference, reference_size);
+ failure("Generated pax archive does not match reference; compare 'testout' to 'test_acl_pax.tar' reference file.");
+ assertEqualInt((int)used, reference_size);
+ free(reference);
/* Read back each entry and check that the ACL data is right. */
assert(NULL != (a = archive_read_new()));
assertA(0 == archive_read_support_format_all(a));
- assertA(0 == archive_read_support_compression_all(a));
+ assertA(0 == archive_read_support_filter_all(a));
assertA(0 == archive_read_open_memory(a, buff, used));
/* First item has no ACLs */
@@ -508,10 +277,6 @@ DEFINE_TEST(test_acl_pax)
assert((archive_entry_mode(ae) & 0777) == 0142);
/* Close the archive. */
- assertA(0 == archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assertA(0 == archive_read_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_acl_pax.tar.uu b/libarchive/test/test_acl_pax.tar.uu
new file mode 100644
index 000000000000..58d7b62463d4
--- /dev/null
+++ b/libarchive/test/test_acl_pax.tar.uu
@@ -0,0 +1,117 @@
+begin 644 test_acl_pax.tar
+M9FEL90``````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````#`P,#$T,B``,#`P,#`P(``P,#`P,#`@`#`P,#`P,#`P,#`P
+M(#`P,#`P,#`P,#`P(#`Q,#`P-@`@,```````````````````````````````
+M````````````````````````````````````````````````````````````
+M``````````````````````````````````````````!U<W1A<@`P,```````
+M````````````````````````````````````````````````````````````
+M```````````````````P,#`P,#`@`#`P,#`P,"``````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M``````````````````````!087A(96%D97(O9FEL90``````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````,#`P,30R(``P,#`P,#`@`#`P
+M,#`P,"``,#`P,#`P,#`Q,3`@,#`P,#`P,#`P,#`@,#$Q-S8Q`"!X````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````'5S=&%R`#`P````````````````````````````````````````````
+M`````````````````````````````````````````#`P,#`P,"``,#`P,#`P
+M(```````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````````````````#<R(%-#2$E,62YA
+M8VPN86-C97-S/75S97(Z.BTM>"QG<F]U<#HZ<BTM+&]T:&5R.CHM=RTL=7-E
+M<CIU<V5R-S<Z<BTM.C<W"@``````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````9FEL90``````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````#`P,#$T,B``,#`P,#`P(``P,#`P,#`@`#`P,#`P
+M,#`P,#`P(#`P,#`P,#`P,#`P(#`Q,#`P-@`@,```````````````````````
+M````````````````````````````````````````````````````````````
+M``````````````````````````````````````````````````!U<W1A<@`P
+M,```````````````````````````````````````````````````````````
+M```````````````````````````P,#`P,#`@`#`P,#`P,"``````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M``````````````````````````````!087A(96%D97(O9FEL90``````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````,#`P-30S(``P,#`P
+M,#`@`#`P,#`P,"``,#`P,#`P,#`Q-C$@,#`P,#`P,#`P,#`@,#$Q-S<T`"!X
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````'5S=&%R`#`P````````````````````````````````````
+M`````````````````````````````````````````````````#`P,#`P,"``
+M,#`P,#`P(```````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````````````````````````#$Q,R!3
+M0TA)3%DN86-L+F%C8V5S<SUU<V5R.CIR+7@L9W)O=7`Z.G(M+2QO=&AE<CHZ
+M+7=X+'5S97(Z=7-E<C<W.G(M+3HW-RQU<V5R.G5S97(W.#HM+2TZ-S@L9W)O
+M=7`Z9W)O=7`W.#IR=W@Z-S@*````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````9FEL90``````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````#`P,#4T,R``,#`P,#`P(``P,#`P,#`@
+M`#`P,#`P,#`P,#`P(#`P,#`P,#`P,#`P(#`Q,#`Q,P`@,```````````````
+M````````````````````````````````````````````````````````````
+M``````````````````````````````````````````````````````````!U
+M<W1A<@`P,```````````````````````````````````````````````````
+M```````````````````````````````````P,#`P,#`@`#`P,#`P,"``````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M``````````````````````````````````````!F:6QE````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````,#`P,30R
+M(``P,#`P,#`@`#`P,#`P,"``,#`P,#`P,#`P,#`@,#`P,#`P,#`P,#`@,#$P
+M,#`V`"`P````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````'5S=&%R`#`P````````````````````````````
+M`````````````````````````````````````````````````````````#`P
+M,#`P,"``,#`P,#`P(```````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+C````````````````````````````````````````````````
+`
+end
diff --git a/libarchive/test/test_acl_basic.c b/libarchive/test/test_acl_posix1e.c
index f66014cdd31b..bbe8bcde25e4 100644
--- a/libarchive/test/test_acl_basic.c
+++ b/libarchive/test/test_acl_posix1e.c
@@ -27,7 +27,7 @@ __FBSDID("$FreeBSD: src/lib/libarchive/test/test_acl_basic.c,v 1.6 2008/10/19 00
/*
* Exercise the system-independent portion of the ACL support.
- * Check that archive_entry objects can save and restore ACL data.
+ * Check that archive_entry objects can save and restore POSIX.1e-style ACL data.
*
* This should work on all systems, regardless of whether local
* filesystems support ACLs or not.
@@ -76,6 +76,34 @@ static struct acl_t acls2[] = {
ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
};
+/*
+ * NFS4 entry types; attempts to set these on top of POSIX.1e
+ * attributes should fail.
+ */
+static struct acl_t acls_nfs4[] = {
+ /* NFS4 types */
+ { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ,
+ ARCHIVE_ENTRY_ACL_USER, 78, "" },
+ { ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_READ,
+ ARCHIVE_ENTRY_ACL_USER, 78, "" },
+ { ARCHIVE_ENTRY_ACL_TYPE_AUDIT, ARCHIVE_ENTRY_ACL_READ,
+ ARCHIVE_ENTRY_ACL_USER, 78, "" },
+ { ARCHIVE_ENTRY_ACL_TYPE_ALARM, ARCHIVE_ENTRY_ACL_READ,
+ ARCHIVE_ENTRY_ACL_USER, 78, "" },
+
+ /* NFS4 tags */
+ { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
+ ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" },
+
+ /* NFS4 inheritance markers */
+ { ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
+ ARCHIVE_ENTRY_ACL_READ | ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT,
+ ARCHIVE_ENTRY_ACL_USER, 79, "" },
+ { ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
+ ARCHIVE_ENTRY_ACL_READ | ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT,
+ ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
+};
+
static void
set_acls(struct archive_entry *ae, struct acl_t *acls, int n)
{
@@ -164,12 +192,7 @@ compare_acls(struct archive_entry *ae, struct acl_t *acls, int n, int mode)
assert(matched == 1);
}
}
-#if ARCHIVE_VERSION_NUMBER < 1009000
- /* Known broken before 1.9.0. */
- skipping("archive_entry_acl_next() exits with ARCHIVE_EOF");
-#else
assertEqualInt(ARCHIVE_EOF, r);
-#endif
assert((mode & 0777) == (archive_entry_mode(ae) & 0777));
failure("Could not find match for ACL "
"(type=%d,permset=%d,tag=%d,qual=%d,name=``%s'')",
@@ -179,9 +202,10 @@ compare_acls(struct archive_entry *ae, struct acl_t *acls, int n, int mode)
free(marker);
}
-DEFINE_TEST(test_acl_basic)
+DEFINE_TEST(test_acl_posix1e)
{
struct archive_entry *ae;
+ int i;
/* Create a simple archive_entry. */
assert((ae = archive_entry_new()) != NULL);
@@ -189,6 +213,14 @@ DEFINE_TEST(test_acl_basic)
archive_entry_set_mode(ae, S_IFREG | 0777);
/* Basic owner/owning group should just update mode bits. */
+
+ /*
+ * Note: This features of libarchive's ACL implementation
+ * shouldn't be relied on and should probably be removed. It
+ * was done to identify trivial ACLs so we could avoid
+ * triggering unnecessary extensions. It's better to identify
+ * trivial ACLs at the point they are being read from disk.
+ */
set_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]));
failure("Basic ACLs shouldn't be stored as extended ACLs");
assert(0 == archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
@@ -225,5 +257,21 @@ DEFINE_TEST(test_acl_basic)
failure("Basic ACLs should set mode to 0142, not %04o",
archive_entry_mode(ae)&0777);
assert((archive_entry_mode(ae) & 0777) == 0142);
+
+ /*
+ * Different types of malformed ACL entries that should
+ * fail when added to existing POSIX.1e ACLs.
+ */
+ set_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]));
+ for (i = 0; i < sizeof(acls_nfs4)/sizeof(acls_nfs4[0]); ++i) {
+ struct acl_t *p = &acls_nfs4[i];
+ failure("Malformed ACL test #%d", i);
+ assertEqualInt(ARCHIVE_FAILED,
+ archive_entry_acl_add_entry(ae,
+ p->type, p->permset, p->tag, p->qual, p->name));
+ assertEqualInt(6,
+ archive_entry_acl_reset(ae,
+ ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
+ }
archive_entry_free(ae);
}
diff --git a/libarchive/test/test_archive_api_feature.c b/libarchive/test/test_archive_api_feature.c
index 23a7083c07fa..d551e6a01ebc 100644
--- a/libarchive/test/test_archive_api_feature.c
+++ b/libarchive/test/test_archive_api_feature.c
@@ -38,7 +38,7 @@ DEFINE_TEST(test_archive_api_feature)
archive_version_number() % 1000);
failure("Version string is: %s, computed is: %s",
archive_version_string(), buff);
- assert(memcmp(buff, archive_version_string(), strlen(buff)) == 0);
+ assertEqualMem(buff, archive_version_string(), strlen(buff));
if (strlen(buff) < strlen(archive_version_string())) {
p = archive_version_string() + strlen(buff);
failure("Version string is: %s", archive_version_string());
@@ -47,30 +47,4 @@ DEFINE_TEST(test_archive_api_feature)
failure("Version string is: %s", archive_version_string());
assert(*p == '\0');
}
-
-/* This is all scheduled to disappear in libarchive 3.0 */
-#if ARCHIVE_VERSION_NUMBER < 3000000
- assertEqualInt(ARCHIVE_VERSION_STAMP, ARCHIVE_VERSION_NUMBER);
- assertEqualInt(ARCHIVE_API_FEATURE, archive_api_feature());
- assertEqualInt(ARCHIVE_API_VERSION, archive_api_version());
- /*
- * Even though ARCHIVE_VERSION_STAMP only appears in
- * archive.h after 1.9.0 and 2.2.3, the macro is synthesized
- * in test.h, so this test is always valid.
- */
- assertEqualInt(ARCHIVE_VERSION_STAMP / 1000, ARCHIVE_API_VERSION * 1000 + ARCHIVE_API_FEATURE);
- /*
- * The function, however, isn't always available. It appeared
- * sometime in the middle of 2.2.3, but the synthesized value
- * never has a release version, so the following conditional
- * exactly determines whether the current library has the
- * function.
- */
-#if ARCHIVE_VERSION_STAMP / 1000 == 1009 || ARCHIVE_VERSION_STAMP > 2002000
- assertEqualInt(ARCHIVE_VERSION_STAMP, archive_version_stamp());
-#else
- skipping("archive_version_stamp()");
-#endif
- assertEqualString(ARCHIVE_LIBRARY_VERSION, archive_version());
-#endif
}
diff --git a/libarchive/test/test_archive_clear_error.c b/libarchive/test/test_archive_clear_error.c
new file mode 100644
index 000000000000..43265b5391b4
--- /dev/null
+++ b/libarchive/test/test_archive_clear_error.c
@@ -0,0 +1,42 @@
+/*-
+ * Copyright (c) 2003-2010 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+DEFINE_TEST(test_archive_clear_error)
+{
+ struct archive* a = archive_read_new();
+
+ archive_set_error(a, 12, "abcdefgh");
+ assertEqualInt(12, archive_errno(a));
+ assertEqualString("abcdefgh", archive_error_string(a));
+
+ archive_clear_error(a);
+ assertEqualInt(0, archive_errno(a));
+ assertEqualString(NULL, archive_error_string(a));
+
+ archive_read_finish(a);
+}
diff --git a/libarchive/test/test_archive_crypto.c b/libarchive/test/test_archive_crypto.c
new file mode 100644
index 000000000000..a4bf4ec6df5a
--- /dev/null
+++ b/libarchive/test/test_archive_crypto.c
@@ -0,0 +1,145 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2011 Andres Mejia
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+
+/* Sanity test of internal crypto functionality */
+
+#define __LIBARCHIVE_BUILD 1
+#include "archive_crypto_private.h"
+
+DEFINE_TEST(test_archive_md5)
+{
+ archive_md5_ctx ctx;
+ unsigned char buf[] = "";
+ unsigned char md[16];
+ unsigned char actualmd[] = "\x93\xb8\x85\xad\xfe\x0d\xa0\x89"
+ "\xcd\xf6\x34\x90\x4f\xd5\x9f\x71";
+
+ if (ARCHIVE_OK != archive_md5_init(&ctx)) {
+ skipping("This platform does not support MD5");
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK, archive_md5_update(&ctx, buf, sizeof(buf)));
+ assertEqualInt(ARCHIVE_OK, archive_md5_final(&ctx, md));
+ assertEqualMem(md, actualmd, sizeof(md));
+}
+
+DEFINE_TEST(test_archive_rmd160)
+{
+ archive_rmd160_ctx ctx;
+ unsigned char buf[] = "";
+ unsigned char md[20];
+ unsigned char actualmd[] = "\xc8\x1b\x94\x93\x34\x20\x22\x1a\x7a\xc0"
+ "\x04\xa9\x02\x42\xd8\xb1\xd3\xe5\x07\x0d";
+
+ if (ARCHIVE_OK != archive_rmd160_init(&ctx)) {
+ skipping("This platform does not support RMD160");
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK, archive_rmd160_update(&ctx, buf, sizeof(buf)));
+ assertEqualInt(ARCHIVE_OK, archive_rmd160_final(&ctx, md));
+ assertEqualMem(md, actualmd, sizeof(md));
+}
+
+DEFINE_TEST(test_archive_sha1)
+{
+ archive_sha1_ctx ctx;
+ unsigned char buf[] = "";
+ unsigned char md[20];
+ unsigned char actualmd[] = "\x5b\xa9\x3c\x9d\xb0\xcf\xf9\x3f\x52\xb5"
+ "\x21\xd7\x42\x0e\x43\xf6\xed\xa2\x78\x4f";
+
+ if (ARCHIVE_OK != archive_sha1_init(&ctx)) {
+ skipping("This platform does not support SHA1");
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK, archive_sha1_update(&ctx, buf, sizeof(buf)));
+ assertEqualInt(ARCHIVE_OK, archive_sha1_final(&ctx, md));
+ assertEqualMem(md, actualmd, sizeof(md));
+}
+
+DEFINE_TEST(test_archive_sha256)
+{
+ archive_sha256_ctx ctx;
+ unsigned char buf[] = "";
+ unsigned char md[32];
+ unsigned char actualmd[] = "\x6e\x34\x0b\x9c\xff\xb3\x7a\x98"
+ "\x9c\xa5\x44\xe6\xbb\x78\x0a\x2c"
+ "\x78\x90\x1d\x3f\xb3\x37\x38\x76"
+ "\x85\x11\xa3\x06\x17\xaf\xa0\x1d";
+
+ if (ARCHIVE_OK != archive_sha256_init(&ctx)) {
+ skipping("This platform does not support SHA256");
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK, archive_sha256_update(&ctx, buf, sizeof(buf)));
+ assertEqualInt(ARCHIVE_OK, archive_sha256_final(&ctx, md));
+ assertEqualMem(md, actualmd, sizeof(md));
+}
+
+DEFINE_TEST(test_archive_sha384)
+{
+ archive_sha384_ctx ctx;
+ unsigned char buf[] = "";
+ unsigned char md[48];
+ unsigned char actualmd[] = "\xbe\xc0\x21\xb4\xf3\x68\xe3\x06"
+ "\x91\x34\xe0\x12\xc2\xb4\x30\x70"
+ "\x83\xd3\xa9\xbd\xd2\x06\xe2\x4e"
+ "\x5f\x0d\x86\xe1\x3d\x66\x36\x65"
+ "\x59\x33\xec\x2b\x41\x34\x65\x96"
+ "\x68\x17\xa9\xc2\x08\xa1\x17\x17";
+
+ if (ARCHIVE_OK != archive_sha384_init(&ctx)) {
+ skipping("This platform does not support SHA384");
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK, archive_sha384_update(&ctx, buf, sizeof(buf)));
+ assertEqualInt(ARCHIVE_OK, archive_sha384_final(&ctx, md));
+ assertEqualMem(md, actualmd, sizeof(md));
+}
+
+DEFINE_TEST(test_archive_sha512)
+{
+ archive_sha512_ctx ctx;
+ unsigned char buf[] = "";
+ unsigned char md[64];
+ unsigned char actualmd[] = "\xb8\x24\x4d\x02\x89\x81\xd6\x93"
+ "\xaf\x7b\x45\x6a\xf8\xef\xa4\xca"
+ "\xd6\x3d\x28\x2e\x19\xff\x14\x94"
+ "\x2c\x24\x6e\x50\xd9\x35\x1d\x22"
+ "\x70\x4a\x80\x2a\x71\xc3\x58\x0b"
+ "\x63\x70\xde\x4c\xeb\x29\x3c\x32"
+ "\x4a\x84\x23\x34\x25\x57\xd4\xe5"
+ "\xc3\x84\x38\xf0\xe3\x69\x10\xee";
+
+ if (ARCHIVE_OK != archive_sha512_init(&ctx)) {
+ skipping("This platform does not support SHA512");
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK, archive_sha512_update(&ctx, buf, sizeof(buf)));
+ assertEqualInt(ARCHIVE_OK, archive_sha512_final(&ctx, md));
+ assertEqualMem(md, actualmd, sizeof(md));
+}
diff --git a/libarchive/test/test_archive_read_close_twice.c b/libarchive/test/test_archive_read_close_twice.c
new file mode 100644
index 000000000000..d69054b4fe5a
--- /dev/null
+++ b/libarchive/test/test_archive_read_close_twice.c
@@ -0,0 +1,43 @@
+/*-
+ * Copyright (c) 2003-2010 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+
+DEFINE_TEST(test_archive_read_close_twice)
+{
+ struct archive* a = archive_read_new();
+
+ assertEqualInt(0, archive_read_close(a));
+ assertEqualInt(0, archive_errno(a));
+ assertEqualString(NULL, archive_error_string(a));
+
+ assertEqualInt(0, archive_read_close(a));
+ assertEqualInt(0, archive_errno(a));
+ assertEqualString(NULL, archive_error_string(a));
+
+ archive_read_finish(a);
+}
diff --git a/libarchive/test/test_archive_read_close_twice_open_fd.c b/libarchive/test/test_archive_read_close_twice_open_fd.c
new file mode 100644
index 000000000000..d30735e4c48b
--- /dev/null
+++ b/libarchive/test/test_archive_read_close_twice_open_fd.c
@@ -0,0 +1,47 @@
+/*-
+ * Copyright (c) 2011 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+DEFINE_TEST(test_archive_read_close_twice_open_fd)
+{
+ struct archive* a = archive_read_new();
+
+ assertEqualInt(ARCHIVE_OK, archive_read_support_format_empty(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_open_fd(a, 0, 0));
+ assertEqualInt(0, archive_errno(a));
+ assertEqualString(NULL, archive_error_string(a));
+
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(0, archive_errno(a));
+ assertEqualString(NULL, archive_error_string(a));
+
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(0, archive_errno(a));
+ assertEqualString(NULL, archive_error_string(a));
+
+ assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+}
diff --git a/libarchive/test/test_archive_read_close_twice_open_filename.c b/libarchive/test/test_archive_read_close_twice_open_filename.c
new file mode 100644
index 000000000000..456b6d688e55
--- /dev/null
+++ b/libarchive/test/test_archive_read_close_twice_open_filename.c
@@ -0,0 +1,47 @@
+/*-
+ * Copyright (c) 2011 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+DEFINE_TEST(test_archive_read_close_twice_open_filename)
+{
+ struct archive* a = archive_read_new();
+
+ assertEqualInt(ARCHIVE_OK, archive_read_support_format_empty(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_open_filename(a, 0, 0));
+ assertEqualInt(0, archive_errno(a));
+ assertEqualString(NULL, archive_error_string(a));
+
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(0, archive_errno(a));
+ assertEqualString(NULL, archive_error_string(a));
+
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(0, archive_errno(a));
+ assertEqualString(NULL, archive_error_string(a));
+
+ assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+}
diff --git a/libarchive/test/test_archive_read_next_header_empty.c b/libarchive/test/test_archive_read_next_header_empty.c
new file mode 100644
index 000000000000..f650bccce89b
--- /dev/null
+++ b/libarchive/test/test_archive_read_next_header_empty.c
@@ -0,0 +1,111 @@
+/*-
+ * Copyright (c) 2003-2011 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+static void
+test_empty_file1(void)
+{
+ struct archive* a = archive_read_new();
+
+ /* Try opening an empty file with the raw handler. */
+ assertEqualInt(ARCHIVE_OK, archive_read_support_format_raw(a));
+ assertEqualInt(0, archive_errno(a));
+ assertEqualString(NULL, archive_error_string(a));
+
+ /* Raw handler doesn't support empty files. */
+ assertEqualInt(ARCHIVE_FATAL, archive_read_open_filename(a, "emptyfile", 0));
+ assert(NULL != archive_error_string(a));
+
+ archive_read_free(a);
+}
+
+static void
+test_empty_file2(void)
+{
+ struct archive* a = archive_read_new();
+ struct archive_entry* e;
+
+ /* Try opening an empty file with raw and empty handlers. */
+ assertEqualInt(ARCHIVE_OK, archive_read_support_format_raw(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_support_format_empty(a));
+ assertEqualInt(0, archive_errno(a));
+ assertEqualString(NULL, archive_error_string(a));
+
+ assertEqualInt(ARCHIVE_OK, archive_read_open_filename(a, "emptyfile", 0));
+ assertEqualInt(0, archive_errno(a));
+ assertEqualString(NULL, archive_error_string(a));
+
+ assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &e));
+ assertEqualInt(0, archive_errno(a));
+ assertEqualString(NULL, archive_error_string(a));
+
+ archive_read_free(a);
+}
+
+static void
+test_empty_tarfile(void)
+{
+ struct archive* a = archive_read_new();
+ struct archive_entry* e;
+
+ /* Try opening an empty file with raw and empty handlers. */
+ assertEqualInt(ARCHIVE_OK, archive_read_support_format_tar(a));
+ assertEqualInt(0, archive_errno(a));
+ assertEqualString(NULL, archive_error_string(a));
+
+ assertEqualInt(ARCHIVE_OK, archive_read_open_filename(a, "empty.tar", 0));
+ assertEqualInt(0, archive_errno(a));
+ assertEqualString(NULL, archive_error_string(a));
+
+ assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &e));
+ assertEqualInt(0, archive_errno(a));
+ assertEqualString(NULL, archive_error_string(a));
+
+ archive_read_free(a);
+}
+
+/* 512 zero bytes. */
+static char nulls[512];
+
+DEFINE_TEST(test_archive_read_next_header_empty)
+{
+ FILE *f;
+
+ /* Create an empty file. */
+ f = fopen("emptyfile", "wb");
+ fclose(f);
+
+ /* Create a file with 512 zero bytes. */
+ f = fopen("empty.tar", "wb");
+ assertEqualInt(512, fwrite(nulls, 1, 512, f));
+ fclose(f);
+
+ test_empty_file1();
+ test_empty_file2();
+ test_empty_tarfile();
+
+}
diff --git a/libarchive/test/test_archive_read_next_header_raw.c b/libarchive/test/test_archive_read_next_header_raw.c
new file mode 100644
index 000000000000..3c7ed871b950
--- /dev/null
+++ b/libarchive/test/test_archive_read_next_header_raw.c
@@ -0,0 +1,65 @@
+/*-
+ * Copyright (c) 2011 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+#define DATA "random garbage for testing purposes"
+
+static const char data[sizeof(DATA)] = DATA;
+
+static void
+test(int skip_explicitely)
+{
+ struct archive* a = archive_read_new();
+ struct archive_entry* e;
+
+ assertEqualInt(ARCHIVE_OK, archive_read_support_format_raw(a));
+ assertEqualInt(0, archive_errno(a));
+ assertEqualString(NULL, archive_error_string(a));
+
+ assertEqualInt(ARCHIVE_OK, archive_read_open_memory(a, (void*) data,
+ sizeof(data)));
+ assertEqualString(NULL, archive_error_string(a));
+
+ assertEqualInt(ARCHIVE_OK, archive_read_next_header(a, &e));
+ assertEqualInt(0, archive_errno(a));
+ assertEqualString(NULL, archive_error_string(a));
+
+ if (skip_explicitely)
+ assertEqualInt(ARCHIVE_OK, archive_read_data_skip(a));
+
+ assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &e));
+ assertEqualInt(0, archive_errno(a));
+ assertEqualString(NULL, archive_error_string(a));
+
+ archive_read_free(a);
+}
+
+DEFINE_TEST(test_archive_read_next_header_raw)
+{
+ test(1);
+ test(0);
+}
diff --git a/libarchive/test/test_archive_read_open2.c b/libarchive/test/test_archive_read_open2.c
new file mode 100644
index 000000000000..0a801ac5d26d
--- /dev/null
+++ b/libarchive/test/test_archive_read_open2.c
@@ -0,0 +1,109 @@
+/*-
+ * Copyright (c) 2011 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+static int
+open_cb(struct archive *a, void *client)
+{
+ (void)a; /* UNUSED */
+ (void)client; /* UNUSED */
+ return 0;
+}
+static ssize_t
+read_cb(struct archive *a, void *client, const void **buff)
+{
+ (void)a; /* UNUSED */
+ (void)client; /* UNUSED */
+ (void)buff; /* UNUSED */
+ return (ssize_t)0;
+}
+static int64_t
+skip_cb(struct archive *a, void *client, int64_t request)
+{
+ (void)a; /* UNUSED */
+ (void)client; /* UNUSED */
+ (void)request; /* UNUSED */
+ return (int64_t)0;
+}
+static int
+close_cb(struct archive *a, void *client)
+{
+ (void)a; /* UNUSED */
+ (void)client; /* UNUSED */
+ return 0;
+}
+
+static void
+test(int formatted, archive_open_callback *o, archive_read_callback *r,
+ archive_skip_callback *s, archive_close_callback *c,
+ int rv, const char *msg)
+{
+ struct archive* a = archive_read_new();
+ if (formatted)
+ assertEqualInt(ARCHIVE_OK,
+ archive_read_support_format_empty(a));
+ assertEqualInt(rv,
+ archive_read_open2(a, NULL, o, r, s, c));
+ assertEqualString(msg, archive_error_string(a));
+ archive_read_free(a);
+}
+
+DEFINE_TEST(test_archive_read_open2)
+{
+ const char *no_reader =
+ "No reader function provided to archive_read_open";
+ const char *no_formats = "No formats registered";
+
+ test(1, NULL, NULL, NULL, NULL,
+ ARCHIVE_FATAL, no_reader);
+ test(1, open_cb, NULL, NULL, NULL,
+ ARCHIVE_FATAL, no_reader);
+ test(1, open_cb, read_cb, NULL, NULL,
+ ARCHIVE_OK, NULL);
+ test(1, open_cb, read_cb, skip_cb, NULL,
+ ARCHIVE_OK, NULL);
+ test(1, open_cb, read_cb, skip_cb, close_cb,
+ ARCHIVE_OK, NULL);
+ test(1, NULL, read_cb, skip_cb, close_cb,
+ ARCHIVE_OK, NULL);
+ test(1, open_cb, read_cb, skip_cb, NULL,
+ ARCHIVE_OK, NULL);
+ test(1, NULL, read_cb, skip_cb, NULL,
+ ARCHIVE_OK, NULL);
+ test(1, NULL, read_cb, NULL, NULL,
+ ARCHIVE_OK, NULL);
+
+ test(0, NULL, NULL, NULL, NULL,
+ ARCHIVE_FATAL, no_reader);
+ test(0, open_cb, NULL, NULL, NULL,
+ ARCHIVE_FATAL, no_reader);
+ test(0, open_cb, read_cb, NULL, NULL,
+ ARCHIVE_FATAL, no_formats);
+ test(0, open_cb, read_cb, skip_cb, NULL,
+ ARCHIVE_FATAL, no_formats);
+ test(0, open_cb, read_cb, skip_cb, close_cb,
+ ARCHIVE_FATAL, no_formats);
+}
diff --git a/libarchive/test/test_archive_read_set_filter_option.c b/libarchive/test/test_archive_read_set_filter_option.c
new file mode 100644
index 000000000000..7ff3c267947d
--- /dev/null
+++ b/libarchive/test/test_archive_read_set_filter_option.c
@@ -0,0 +1,55 @@
+/*-
+ * Copyright (c) 2011 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+#define should(__a, __code, __m, __o, __v) \
+assertEqualInt(__code, archive_read_set_filter_option(__a, __m, __o, __v))
+
+static void
+test(int pristine)
+{
+ struct archive* a = archive_read_new();
+
+ if (!pristine)
+ archive_read_support_filter_all(a);
+
+ should(a, ARCHIVE_OK, NULL, NULL, NULL);
+ should(a, ARCHIVE_OK, "", "", "");
+
+ should(a, ARCHIVE_FAILED, NULL, "fubar", NULL);
+ should(a, ARCHIVE_FAILED, NULL, "fubar", "snafu");
+ should(a, ARCHIVE_FAILED, "fubar", "snafu", NULL);
+ should(a, ARCHIVE_FAILED, "fubar", "snafu", "betcha");
+
+ archive_read_finish(a);
+}
+
+DEFINE_TEST(test_archive_read_set_filter_option)
+{
+ test(1);
+ test(0);
+}
diff --git a/libarchive/test/test_archive_read_set_format_option.c b/libarchive/test/test_archive_read_set_format_option.c
new file mode 100644
index 000000000000..e1aac574e158
--- /dev/null
+++ b/libarchive/test/test_archive_read_set_format_option.c
@@ -0,0 +1,67 @@
+/*-
+ * Copyright (c) 2011 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+#define should(__a, __code, __m, __o, __v) \
+assertEqualInt(__code, archive_read_set_format_option(__a, __m, __o, __v))
+
+static void
+test(int pristine)
+{
+ struct archive* a = archive_read_new();
+ int known_option_rv = pristine ? ARCHIVE_FAILED : ARCHIVE_OK;
+
+ if (!pristine)
+ archive_read_support_format_all(a);
+
+ /* NULL and "" denote `no option', so they're ok no matter
+ * what, if any, formats are registered */
+ should(a, ARCHIVE_OK, NULL, NULL, NULL);
+ should(a, ARCHIVE_OK, "", "", "");
+
+ /* unknown modules and options */
+ should(a, ARCHIVE_FAILED, "fubar", "snafu", NULL);
+ should(a, ARCHIVE_FAILED, "fubar", "snafu", "betcha");
+
+ /* unknown modules and options */
+ should(a, ARCHIVE_FAILED, NULL, "snafu", NULL);
+ should(a, ARCHIVE_FAILED, NULL, "snafu", "betcha");
+
+ /* ARCHIVE_OK with iso9660 loaded, ARCHIVE_WARN otherwise */
+ should(a, known_option_rv, "iso9660", "joliet", NULL);
+ should(a, known_option_rv, "iso9660", "joliet", NULL);
+ should(a, known_option_rv, NULL, "joliet", NULL);
+ should(a, known_option_rv, NULL, "joliet", NULL);
+
+ archive_read_finish(a);
+}
+
+DEFINE_TEST(test_archive_read_set_format_option)
+{
+ test(1);
+ test(0);
+}
diff --git a/libarchive/test/test_archive_read_set_option.c b/libarchive/test/test_archive_read_set_option.c
new file mode 100644
index 000000000000..2ad5b0bda8e2
--- /dev/null
+++ b/libarchive/test/test_archive_read_set_option.c
@@ -0,0 +1,69 @@
+/*-
+ * Copyright (c) 2011 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+#define should(__a, __code, __m, __o, __v) \
+assertEqualInt(__code, archive_read_set_option(__a, __m, __o, __v))
+
+static void
+test(int pristine)
+{
+ struct archive* a = archive_read_new();
+ int known_option_rv = pristine ? ARCHIVE_FAILED : ARCHIVE_OK;
+
+ if (!pristine) {
+ archive_read_support_filter_all(a);
+ archive_read_support_format_all(a);
+ }
+
+ /* NULL and "" denote `no option', so they're ok no matter
+ * what, if any, formats are registered */
+ should(a, ARCHIVE_OK, NULL, NULL, NULL);
+ should(a, ARCHIVE_OK, "", "", "");
+
+ /* unknown modules and options */
+ should(a, ARCHIVE_FAILED, "fubar", "snafu", NULL);
+ should(a, ARCHIVE_FAILED, "fubar", "snafu", "betcha");
+
+ /* unknown modules and options */
+ should(a, ARCHIVE_FAILED, NULL, "snafu", NULL);
+ should(a, ARCHIVE_FAILED, NULL, "snafu", "betcha");
+
+ /* ARCHIVE_OK with iso9660 loaded, ARCHIVE_WARN otherwise */
+ should(a, known_option_rv, "iso9660", "joliet", NULL);
+ should(a, known_option_rv, "iso9660", "joliet", NULL);
+ should(a, known_option_rv, NULL, "joliet", NULL);
+ should(a, known_option_rv, NULL, "joliet", NULL);
+
+ archive_read_finish(a);
+}
+
+DEFINE_TEST(test_archive_read_set_option)
+{
+ test(1);
+ test(0);
+}
diff --git a/libarchive/test/test_archive_read_set_options.c b/libarchive/test/test_archive_read_set_options.c
new file mode 100644
index 000000000000..a199afe44524
--- /dev/null
+++ b/libarchive/test/test_archive_read_set_options.c
@@ -0,0 +1,79 @@
+/*-
+ * Copyright (c) 2011 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+#define should(__a, __code, __opts) \
+assertEqualInt(__code, archive_read_set_options(__a, __opts))
+
+static void
+test(int pristine)
+{
+ struct archive* a = archive_read_new();
+ int halfempty_options_rv = pristine ? ARCHIVE_WARN : ARCHIVE_OK;
+ int known_option_rv = pristine ? ARCHIVE_FAILED : ARCHIVE_OK;
+ int mixed_options_rv = pristine ? ARCHIVE_FAILED : ARCHIVE_WARN;
+
+ if (!pristine) {
+ archive_read_support_filter_all(a);
+ archive_read_support_format_all(a);
+ }
+
+ /* NULL and "" denote `no option', so they're ok no matter
+ * what, if any, formats are registered */
+ should(a, ARCHIVE_OK, NULL);
+ should(a, ARCHIVE_OK, "");
+
+ /* unknown modules and options */
+ should(a, ARCHIVE_FAILED, "fubar:snafu");
+ should(a, ARCHIVE_FAILED, "fubar:snafu=betcha");
+
+ /* unknown modules and options */
+ should(a, ARCHIVE_FAILED, "snafu");
+ should(a, ARCHIVE_FAILED, "snafu=betcha");
+
+ /* ARCHIVE_OK with iso9660 loaded, ARCHIVE_WARN otherwise */
+ should(a, known_option_rv, "iso9660:joliet");
+ should(a, known_option_rv, "iso9660:joliet");
+ should(a, known_option_rv, "joliet");
+ should(a, known_option_rv, "!joliet");
+
+ should(a, ARCHIVE_OK, ",");
+ should(a, ARCHIVE_OK, ",,");
+
+ should(a, halfempty_options_rv, ",joliet");
+ should(a, halfempty_options_rv, "joliet,");
+
+ should(a, mixed_options_rv, "joliet,snafu");
+
+ archive_read_finish(a);
+}
+
+DEFINE_TEST(test_archive_read_set_options)
+{
+ test(1);
+ test(0);
+}
diff --git a/libarchive/test/test_archive_read_support.c b/libarchive/test/test_archive_read_support.c
new file mode 100644
index 000000000000..1619b0729e94
--- /dev/null
+++ b/libarchive/test/test_archive_read_support.c
@@ -0,0 +1,98 @@
+/*-
+ * Copyright (c) 2011 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+/*
+ * Verify that the various archive_read_support_* functions
+ * return appropriate errors when invoked on the wrong kind of
+ * archive handle.
+ */
+
+typedef struct archive *constructor(void);
+typedef int enabler(struct archive *);
+typedef int destructor(struct archive *);
+
+static void
+test_success(constructor new_, enabler enable_, destructor free_)
+{
+ struct archive *a = new_();
+ int result = enable_(a);
+ if (result == ARCHIVE_WARN) {
+ assert(NULL != archive_error_string(a));
+ assertEqualIntA(a, -1, archive_errno(a));
+ } else {
+ assertEqualIntA(a, ARCHIVE_OK, result);
+ assert(NULL == archive_error_string(a));
+ assertEqualIntA(a, 0, archive_errno(a));
+ }
+ free_(a);
+}
+
+static void
+test_failure(constructor new_, enabler enable_, destructor free_)
+{
+ struct archive *a = new_();
+ assertEqualIntA(a, ARCHIVE_FATAL, enable_(a));
+ assert(NULL != archive_error_string(a));
+ assertEqualIntA(a, -1, archive_errno(a));
+ free_(a);
+}
+
+static void
+test_filter_or_format(enabler enable)
+{
+ test_success(archive_read_new, enable, archive_read_free);
+ test_failure(archive_write_new, enable, archive_write_free);
+ test_failure(archive_read_disk_new, enable, archive_read_free);
+ test_failure(archive_write_disk_new, enable, archive_write_free);
+}
+
+DEFINE_TEST(test_archive_read_support)
+{
+ test_filter_or_format(archive_read_support_format_7zip);
+ test_filter_or_format(archive_read_support_format_all);
+ test_filter_or_format(archive_read_support_format_ar);
+ test_filter_or_format(archive_read_support_format_cab);
+ test_filter_or_format(archive_read_support_format_cpio);
+ test_filter_or_format(archive_read_support_format_empty);
+ test_filter_or_format(archive_read_support_format_iso9660);
+ test_filter_or_format(archive_read_support_format_lha);
+ test_filter_or_format(archive_read_support_format_mtree);
+ test_filter_or_format(archive_read_support_format_tar);
+ test_filter_or_format(archive_read_support_format_xar);
+ test_filter_or_format(archive_read_support_format_zip);
+
+ test_filter_or_format(archive_read_support_filter_all);
+ test_filter_or_format(archive_read_support_filter_bzip2);
+ test_filter_or_format(archive_read_support_filter_compress);
+ test_filter_or_format(archive_read_support_filter_gzip);
+ test_filter_or_format(archive_read_support_filter_lzip);
+ test_filter_or_format(archive_read_support_filter_lzma);
+ test_filter_or_format(archive_read_support_filter_none);
+ test_filter_or_format(archive_read_support_filter_rpm);
+ test_filter_or_format(archive_read_support_filter_uu);
+ test_filter_or_format(archive_read_support_filter_xz);
+}
diff --git a/libarchive/test/test_archive_set_error.c b/libarchive/test/test_archive_set_error.c
new file mode 100644
index 000000000000..18897fbda8d2
--- /dev/null
+++ b/libarchive/test/test_archive_set_error.c
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 2011 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+static void
+test(struct archive *a, int code, const char *msg)
+{
+ archive_set_error(a, code, "%s", msg);
+
+ assertEqualInt(code, archive_errno(a));
+ assertEqualString(msg, archive_error_string(a));
+}
+
+DEFINE_TEST(test_archive_set_error)
+{
+ struct archive* a = archive_read_new();
+
+ /* unlike printf("%s", NULL),
+ * archive_set_error(a, code, "%s", NULL)
+ * segfaults, so it's not tested here */
+ test(a, 12, "abcdefgh");
+ test(a, 0, "123456");
+ test(a, -1, "tuvw");
+ test(a, 34, "XYZ");
+
+ archive_read_finish(a);
+}
diff --git a/libarchive/test/test_archive_string.c b/libarchive/test/test_archive_string.c
new file mode 100644
index 000000000000..54f68bdaed1a
--- /dev/null
+++ b/libarchive/test/test_archive_string.c
@@ -0,0 +1,344 @@
+/*-
+ * Copyright (c) 2011 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+#define __LIBARCHIVE_TEST
+#include "archive_string.h"
+
+#define EXTENT 32
+
+#define assertStringSizes(strlen, buflen, as) \
+ assertEqualInt(strlen, (as).length); \
+ assertEqualInt(buflen, (as).buffer_length);
+
+#define assertExactString(strlen, buflen, data, as) \
+ do { \
+ assertStringSizes(strlen, buflen, as); \
+ assertEqualString(data, (as).s); \
+ } while (0)
+
+#define assertNonNULLString(strlen, buflen, as) \
+ do { \
+ assertStringSizes(strlen, buflen, as); \
+ assert(NULL != (as).s); \
+ } while (0)
+
+static void
+test_archive_string_ensure(void)
+{
+ struct archive_string s;
+
+ archive_string_init(&s);
+ assertExactString(0, 0, NULL, s);
+
+ /* single-extent allocation */
+ assert(&s == archive_string_ensure(&s, 5));
+ assertNonNULLString(0, EXTENT, s);
+
+ /* what happens around extent boundaries? */
+ assert(&s == archive_string_ensure(&s, EXTENT - 1));
+ assertNonNULLString(0, EXTENT, s);
+
+ assert(&s == archive_string_ensure(&s, EXTENT));
+ assertNonNULLString(0, EXTENT, s);
+
+ assert(&s == archive_string_ensure(&s, EXTENT + 1));
+ assertNonNULLString(0, 2 * EXTENT, s);
+}
+
+static void
+test_archive_strcat(void)
+{
+ struct archive_string s;
+
+ archive_string_init(&s);
+ assertExactString(0, 0, NULL, s);
+
+ /* null target, empty source */
+ assert(&s == archive_strcat(&s, ""));
+ assertExactString(0, EXTENT, "", s);
+
+ /* empty target, empty source */
+ assert(&s == archive_strcat(&s, ""));
+ assertExactString(0, EXTENT, "", s);
+
+ /* empty target, non-empty source */
+ assert(&s == archive_strcat(&s, "fubar"));
+ assertExactString(5, EXTENT, "fubar", s);
+
+ /* non-empty target, non-empty source */
+ assert(&s == archive_strcat(&s, "baz"));
+ assertExactString(8, EXTENT, "fubarbaz", s);
+}
+
+static void
+test_archive_strappend_char(void)
+{
+ struct archive_string s;
+
+ archive_string_init(&s);
+ assertExactString(0, 0, NULL, s);
+
+ /* null target */
+ archive_strappend_char(&s, 'X');
+ assertExactString(1, EXTENT, "X", s);
+
+ /* non-empty target */
+ archive_strappend_char(&s, 'Y');
+ assertExactString(2, EXTENT, "XY", s);
+}
+
+/* archive_strnXXX() tests focus on length handling.
+ * other behaviors are tested by proxy through archive_strXXX()
+ */
+
+static void
+test_archive_strncat(void)
+{
+ struct archive_string s;
+
+ archive_string_init(&s);
+ assertExactString(0, 0, NULL, s);
+
+ /* perfect length */
+ assert(&s == archive_strncat(&s, "snafu", 5));
+ assertExactString(5, EXTENT, "snafu", s);
+
+ /* short read */
+ assert(&s == archive_strncat(&s, "barbazqux", 3));
+ assertExactString(8, EXTENT, "snafubar", s);
+
+ /* long read is ok too! */
+ assert(&s == archive_strncat(&s, "snafu", 8));
+ assertExactString(13, EXTENT, "snafubarsnafu", s);
+}
+
+static void
+test_archive_strncpy(void)
+{
+ struct archive_string s;
+
+ archive_string_init(&s);
+ assertExactString(0, 0, NULL, s);
+
+ /* perfect length */
+ assert(&s == archive_strncpy(&s, "fubar", 5));
+ assertExactString(5, EXTENT, "fubar", s);
+
+ /* short read */
+ assert(&s == archive_strncpy(&s, "snafubar", 5));
+ assertExactString(5, EXTENT, "snafu", s);
+
+ /* long read is ok too! */
+ assert(&s == archive_strncpy(&s, "snafu", 8));
+ assertExactString(5, EXTENT, "snafu", s);
+}
+
+static void
+test_archive_strcpy(void)
+{
+ struct archive_string s;
+
+ archive_string_init(&s);
+ assertExactString(0, 0, NULL, s);
+
+ /* null target */
+ assert(&s == archive_strcpy(&s, "snafu"));
+ assertExactString(5, EXTENT, "snafu", s);
+
+ /* dirty target */
+ assert(&s == archive_strcpy(&s, "foo"));
+ assertExactString(3, EXTENT, "foo", s);
+
+ /* dirty target, empty source */
+ assert(&s == archive_strcpy(&s, ""));
+ assertExactString(0, EXTENT, "", s);
+}
+
+static void
+test_archive_string_concat(void)
+{
+ struct archive_string s, t, u, v;
+
+ archive_string_init(&s);
+ assertExactString(0, 0, NULL, s);
+ archive_string_init(&t);
+ assertExactString(0, 0, NULL, t);
+ archive_string_init(&u);
+ assertExactString(0, 0, NULL, u);
+ archive_string_init(&v);
+ assertExactString(0, 0, NULL, v);
+
+ /* null target, null source */
+ archive_string_concat(&t, &s);
+ assertExactString(0, 0, NULL, s);
+ assertExactString(0, EXTENT, "", t);
+
+ /* null target, empty source */
+ assert(&s == archive_strcpy(&s, ""));
+ archive_string_concat(&u, &s);
+ assertExactString(0, EXTENT, "", s);
+ assertExactString(0, EXTENT, "", u);
+
+ /* null target, non-empty source */
+ assert(&s == archive_strcpy(&s, "foo"));
+ archive_string_concat(&v, &s);
+ assertExactString(3, EXTENT, "foo", s);
+ assertExactString(3, EXTENT, "foo", v);
+
+ /* empty target, empty source */
+ assert(&s == archive_strcpy(&s, ""));
+ assert(&t == archive_strcpy(&t, ""));
+ archive_string_concat(&t, &s);
+ assertExactString(0, EXTENT, "", s);
+ assertExactString(0, EXTENT, "", t);
+
+ /* empty target, non-empty source */
+ assert(&s == archive_strcpy(&s, "snafu"));
+ assert(&t == archive_strcpy(&t, ""));
+ archive_string_concat(&t, &s);
+ assertExactString(5, EXTENT, "snafu", s);
+ assertExactString(5, EXTENT, "snafu", t);
+}
+
+static void
+test_archive_string_copy(void)
+{
+ struct archive_string s, t, u, v;
+
+ archive_string_init(&s);
+ assertExactString(0, 0, NULL, s);
+ archive_string_init(&t);
+ assertExactString(0, 0, NULL, t);
+ archive_string_init(&u);
+ assertExactString(0, 0, NULL, u);
+ archive_string_init(&v);
+ assertExactString(0, 0, NULL, v);
+
+ /* null target, null source */
+ archive_string_copy(&t, &s);
+ assertExactString(0, 0, NULL, s);
+ assertExactString(0, EXTENT, "", t);
+
+ /* null target, empty source */
+ archive_string_copy(&u, &t);
+ assertExactString(0, EXTENT, "", t);
+ assertExactString(0, EXTENT, "", u);
+
+ /* empty target, empty source */
+ archive_string_copy(&u, &t);
+ assertExactString(0, EXTENT, "", t);
+ assertExactString(0, EXTENT, "", u);
+
+ /* null target, non-empty source */
+ assert(NULL != archive_strcpy(&s, "snafubar"));
+ assertExactString(8, EXTENT, "snafubar", s);
+
+ archive_string_copy(&v, &s);
+ assertExactString(8, EXTENT, "snafubar", s);
+ assertExactString(8, EXTENT, "snafubar", v);
+
+ /* empty target, non-empty source */
+ assertExactString(0, EXTENT, "", t);
+ archive_string_copy(&t, &s);
+ assertExactString(8, EXTENT, "snafubar", s);
+ assertExactString(8, EXTENT, "snafubar", t);
+
+ /* non-empty target, non-empty source */
+ assert(NULL != archive_strcpy(&s, "fubar"));
+ assertExactString(5, EXTENT, "fubar", s);
+
+ archive_string_copy(&t, &s);
+ assertExactString(5, EXTENT, "fubar", s);
+ assertExactString(5, EXTENT, "fubar", t);
+}
+
+static void
+test_archive_string_sprintf(void)
+{
+ struct archive_string s;
+#define S16 "0123456789abcdef"
+#define S32 S16 S16
+#define S64 S32 S32
+#define S128 S64 S64
+ const char *s32 = S32;
+ const char *s33 = S32 "0";
+ const char *s64 = S64;
+ const char *s65 = S64 "0";
+ const char *s128 = S128;
+ const char *s129 = S128 "0";
+#undef S16
+#undef S32
+#undef S64
+#undef S128
+
+ archive_string_init(&s);
+ assertExactString(0, 0, NULL, s);
+
+ archive_string_sprintf(&s, "%s", "");
+ assertExactString(0, 2 * EXTENT, "", s);
+
+ archive_string_empty(&s);
+ archive_string_sprintf(&s, "%s", s32);
+ assertExactString(32, 2 * EXTENT, s32, s);
+
+ archive_string_empty(&s);
+ archive_string_sprintf(&s, "%s", s33);
+ assertExactString(33, 2 * EXTENT, s33, s);
+
+ archive_string_empty(&s);
+ archive_string_sprintf(&s, "%s", s64);
+ assertExactString(64, 4 * EXTENT, s64, s);
+
+ archive_string_empty(&s);
+ archive_string_sprintf(&s, "%s", s65);
+ assertExactString(65, 4 * EXTENT, s65, s);
+
+ archive_string_empty(&s);
+ archive_string_sprintf(&s, "%s", s128);
+ assertExactString(128, 8 * EXTENT, s128, s);
+
+ archive_string_empty(&s);
+ archive_string_sprintf(&s, "%s", s129);
+ assertExactString(129, 8 * EXTENT, s129, s);
+
+ archive_string_empty(&s);
+ archive_string_sprintf(&s, "%d", 1234567890);
+ assertExactString(10, 8 * EXTENT, "1234567890", s);
+}
+
+DEFINE_TEST(test_archive_string)
+{
+ test_archive_string_ensure();
+ test_archive_strcat();
+ test_archive_strappend_char();
+ test_archive_strncat();
+ test_archive_strncpy();
+ test_archive_strcpy();
+ test_archive_string_concat();
+ test_archive_string_copy();
+ test_archive_string_sprintf();
+}
diff --git a/libarchive/test/test_archive_string_conversion.c b/libarchive/test/test_archive_string_conversion.c
new file mode 100644
index 000000000000..8b833ea6f705
--- /dev/null
+++ b/libarchive/test/test_archive_string_conversion.c
@@ -0,0 +1,629 @@
+/*-
+ * Copyright (c) 2011 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+#include <locale.h>
+
+#define __LIBARCHIVE_TEST
+#include "archive_string.h"
+
+/*
+Execute the following to rebuild the data for this program:
+ tail -n +36 test_archive_string_conversion.c | /bin/sh
+#
+# This requires http://unicode.org/Public/UNIDATA/NormalizationTest.txt
+#
+if="NormalizationTest.txt"
+if [ ! -f ${if} ]; then
+ echo "Not found: \"${if}\""
+ exit 0
+fi
+of=test_archive_string_conversion.txt.Z
+echo "\$FreeBSD\$" > ${of}.uu
+awk -F ';' '$0 ~/^[0-9A-F]+/ {printf "%s;%s\n", $2, $3}' ${if} | compress | uuencode ${of} >> ${of}.uu
+exit 1
+*/
+
+static int
+unicode_to_utf8(char *p, uint32_t uc)
+{
+ char *_p = p;
+
+ /* Translate code point to UTF8 */
+ if (uc <= 0x7f) {
+ *p++ = (char)uc;
+ } else if (uc <= 0x7ff) {
+ *p++ = 0xc0 | ((uc >> 6) & 0x1f);
+ *p++ = 0x80 | (uc & 0x3f);
+ } else if (uc <= 0xffff) {
+ *p++ = 0xe0 | ((uc >> 12) & 0x0f);
+ *p++ = 0x80 | ((uc >> 6) & 0x3f);
+ *p++ = 0x80 | (uc & 0x3f);
+ } else {
+ *p++ = 0xf0 | ((uc >> 18) & 0x07);
+ *p++ = 0x80 | ((uc >> 12) & 0x3f);
+ *p++ = 0x80 | ((uc >> 6) & 0x3f);
+ *p++ = 0x80 | (uc & 0x3f);
+ }
+ return ((int)(p - _p));
+}
+
+static void
+archive_be16enc(void *pp, uint16_t u)
+{
+ unsigned char *p = (unsigned char *)pp;
+
+ p[0] = (u >> 8) & 0xff;
+ p[1] = u & 0xff;
+}
+
+static int
+unicode_to_utf16be(char *p, uint32_t uc)
+{
+ char *utf16 = p;
+
+ if (uc > 0xffff) {
+ /* We have a code point that won't fit into a
+ * wchar_t; convert it to a surrogate pair. */
+ uc -= 0x10000;
+ archive_be16enc(utf16, ((uc >> 10) & 0x3ff) + 0xD800);
+ archive_be16enc(utf16+2, (uc & 0x3ff) + 0xDC00);
+ return (4);
+ } else {
+ archive_be16enc(utf16, uc);
+ return (2);
+ }
+}
+
+static void
+archive_le16enc(void *pp, uint16_t u)
+{
+ unsigned char *p = (unsigned char *)pp;
+
+ p[0] = u & 0xff;
+ p[1] = (u >> 8) & 0xff;
+}
+
+static size_t
+unicode_to_utf16le(char *p, uint32_t uc)
+{
+ char *utf16 = p;
+
+ if (uc > 0xffff) {
+ /* We have a code point that won't fit into a
+ * wchar_t; convert it to a surrogate pair. */
+ uc -= 0x10000;
+ archive_le16enc(utf16, ((uc >> 10) & 0x3ff) + 0xD800);
+ archive_le16enc(utf16+2, (uc & 0x3ff) + 0xDC00);
+ return (4);
+ } else {
+ archive_le16enc(utf16, uc);
+ return (2);
+ }
+}
+
+static int
+wc_size(void)
+{
+ return (sizeof(wchar_t));
+}
+
+static int
+unicode_to_wc(wchar_t *wp, uint32_t uc)
+{
+ if (wc_size() == 4) {
+ *wp = (wchar_t)uc;
+ return (1);
+ }
+ if (uc > 0xffff) {
+ /* We have a code point that won't fit into a
+ * wchar_t; convert it to a surrogate pair. */
+ uc -= 0x10000;
+ *wp++ = (wchar_t)(((uc >> 10) & 0x3ff) + 0xD800);
+ *wp = (wchar_t)((uc & 0x3ff) + 0xDC00);
+ return (2);
+ } else {
+ *wp = (wchar_t)uc;
+ return (1);
+ }
+}
+
+/*
+ * Note: U+2000 - U+2FFF, U+F900 - U+FAFF and U+2F800 - U+2FAFF are not
+ * converted to NFD on Mac OS.
+ * see also http://developer.apple.com/library/mac/#qa/qa2001/qa1173.html
+ */
+static int
+scan_unicode_pattern(char *out, wchar_t *wout, char *u16be, char *u16le,
+ const char *pattern, int exclude_mac_nfd)
+{
+ unsigned uc = 0;
+ const char *p = pattern;
+ char *op = out;
+ wchar_t *owp = wout;
+ char *op16be = u16be;
+ char *op16le = u16le;
+
+ for (;;) {
+ if (*p >= '0' && *p <= '9')
+ uc = (uc << 4) + (*p - '0');
+ else if (*p >= 'A' && *p <= 'F')
+ uc = (uc << 4) + (*p - 'A' + 0x0a);
+ else {
+ if (exclude_mac_nfd) {
+ /*
+ * These are not converted to NFD on Mac OS.
+ */
+ if ((uc >= 0x2000 && uc <= 0x2FFF) ||
+ (uc >= 0xF900 && uc <= 0xFAFF) ||
+ (uc >= 0x2F800 && uc <= 0x2FAFF))
+ return (-1);
+ /*
+ * Those code points are not converted to
+ * NFD on Mac OS. I do not know the reason
+ * because it is undocumented.
+ * NFC NFD
+ * 1109A ==> 11099 110BA
+ * 1109C ==> 1109B 110BA
+ * 110AB ==> 110A5 110BA
+ */
+ if (uc == 0x1109A || uc == 0x1109C ||
+ uc == 0x110AB)
+ return (-1);
+ }
+ op16be += unicode_to_utf16be(op16be, uc);
+ op16le += unicode_to_utf16le(op16le, uc);
+ owp += unicode_to_wc(owp, uc);
+ op += unicode_to_utf8(op, uc);
+ if (!*p) {
+ *op16be++ = 0;
+ *op16be = 0;
+ *op16le++ = 0;
+ *op16le = 0;
+ *owp = L'\0';
+ *op = '\0';
+ break;
+ }
+ uc = 0;
+ }
+ p++;
+ }
+ return (0);
+}
+
+static int
+is_wc_unicode(void)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ return (1);
+#else
+ return (0);
+#endif
+}
+
+/*
+ * A conversion test that we correctly normalize UTF-8 and UTF-16BE characters.
+ * On Mac OS, the characters to be Form D.
+ * On other platforms, the characters to be Form C.
+ */
+static void
+test_archive_string_normalization(void)
+{
+ struct archive *a, *a2;
+ struct archive_entry *ae;
+ struct archive_string utf8;
+ struct archive_mstring mstr;
+ struct archive_string_conv *f_sconv8, *t_sconv8;
+ struct archive_string_conv *f_sconv16be, *f_sconv16le;
+ FILE *fp;
+ char buff[512];
+ static const char reffile[] = "test_archive_string_conversion.txt.Z";
+ ssize_t size;
+ int line = 0;
+ int locale_is_utf8, wc_is_unicode;
+
+ locale_is_utf8 = (NULL != setlocale(LC_ALL, "en_US.UTF-8"));
+ wc_is_unicode = is_wc_unicode();
+ /* If it doesn't exist, just warn and return. */
+ if (!locale_is_utf8 && !wc_is_unicode) {
+ skipping("invalid encoding tests require a suitable locale;"
+ " en_US.UTF-8 not available on this system");
+ return;
+ }
+
+ archive_string_init(&utf8);
+ memset(&mstr, 0, sizeof(mstr));
+
+ /*
+ * Extract a test pattern file.
+ */
+ extract_reference_file(reffile);
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_raw(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, reffile, 512));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assert((fp = fopen("testdata.txt", "w")) != NULL);
+ while ((size = archive_read_data(a, buff, 512)) > 0)
+ fwrite(buff, 1, size, fp);
+ fclose(fp);
+
+ /* Open a test pattern file. */
+ assert((fp = fopen("testdata.txt", "r")) != NULL);
+
+ /*
+ * Create string conversion objects.
+ */
+ assertA(NULL != (f_sconv8 =
+ archive_string_conversion_from_charset(a, "UTF-8", 0)));
+ assertA(NULL != (f_sconv16be =
+ archive_string_conversion_from_charset(a, "UTF-16BE", 0)));
+ assertA(NULL != (f_sconv16le =
+ archive_string_conversion_from_charset(a, "UTF-16LE", 0)));
+ assert((a2 = archive_write_new()) != NULL);
+ assertA(NULL != (t_sconv8 =
+ archive_string_conversion_to_charset(a2, "UTF-8", 0)));
+ if (f_sconv8 == NULL || f_sconv16be == NULL || f_sconv16le == NULL ||
+ t_sconv8 == NULL || fp == NULL) {
+ /* We cannot continue this test. */
+ if (fp != NULL)
+ fclose(fp);
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+ return;
+ }
+
+ /*
+ * Read test data.
+ * Test data format:
+ * <NFC Unicode pattern> ';' <NFD Unicode pattern> '\n'
+ * Unicode pattern format:
+ * [0-9A-F]{4,5}([ ][0-9A-F]{4,5}){0,}
+ */
+ while (fgets(buff, sizeof(buff), fp) != NULL) {
+ char nfc[80], nfd[80];
+ char utf8_nfc[80], utf8_nfd[80];
+ char utf16be_nfc[80], utf16be_nfd[80];
+ char utf16le_nfc[80], utf16le_nfd[80];
+ wchar_t wc_nfc[40], wc_nfd[40];
+ char *e, *p;
+
+ line++;
+ if (buff[0] == '#')
+ continue;
+ p = strchr(buff, ';');
+ if (p == NULL)
+ continue;
+ *p++ = '\0';
+ /* Copy an NFC pattern */
+ strncpy(nfc, buff, sizeof(nfc)-1);
+ nfc[sizeof(nfc)-1] = '\0';
+ e = p;
+ p = strchr(p, '\n');
+ if (p == NULL)
+ continue;
+ *p = '\0';
+ /* Copy an NFD pattern */
+ strncpy(nfd, e, sizeof(nfd)-1);
+ nfd[sizeof(nfd)-1] = '\0';
+
+ /*
+ * Convert an NFC pattern to UTF-8 bytes.
+ */
+#if defined(__APPLE__)
+ if (scan_unicode_pattern(utf8_nfc, wc_nfc, utf16be_nfc, utf16le_nfc,
+ nfc, 1) != 0)
+ continue;
+#else
+ scan_unicode_pattern(utf8_nfc, wc_nfc, utf16be_nfc, utf16le_nfc,
+ nfc, 0);
+#endif
+
+ /*
+ * Convert an NFD pattern to UTF-8 bytes.
+ */
+ scan_unicode_pattern(utf8_nfd, wc_nfd, utf16be_nfd, utf16le_nfd,
+ nfd, 0);
+
+ if (locale_is_utf8) {
+#if defined(__APPLE__)
+ /*
+ * Normalize an NFC string for import.
+ */
+ assertEqualInt(0, archive_strcpy_in_locale(
+ &utf8, utf8_nfc, f_sconv8));
+ failure("NFC(%s) should be converted to NFD(%s):%d",
+ nfc, nfd, line);
+ assertEqualUTF8String(utf8_nfd, utf8.s);
+
+ /*
+ * Normalize an NFD string for import.
+ */
+ assertEqualInt(0, archive_strcpy_in_locale(
+ &utf8, utf8_nfd, f_sconv8));
+ failure("NFD(%s) should not be any changed:%d",
+ nfd, line);
+ assertEqualUTF8String(utf8_nfd, utf8.s);
+
+ /*
+ * Copy an NFD string for export.
+ */
+ assertEqualInt(0, archive_strcpy_in_locale(
+ &utf8, utf8_nfd, t_sconv8));
+ failure("NFD(%s) should not be any changed:%d",
+ nfd, line);
+ assertEqualUTF8String(utf8_nfd, utf8.s);
+
+ /*
+ * Normalize an NFC string in UTF-16BE for import.
+ */
+ assertEqualInt(0, archive_strncpy_in_locale(
+ &utf8, utf16be_nfc, 100000, f_sconv16be));
+ failure("NFC(%s) should be converted to NFD(%s):%d",
+ nfc, nfd, line);
+ assertEqualUTF8String(utf8_nfd, utf8.s);
+
+ /*
+ * Normalize an NFC string in UTF-16LE for import.
+ */
+ assertEqualInt(0, archive_strncpy_in_locale(
+ &utf8, utf16le_nfc, 100000, f_sconv16le));
+ failure("NFC(%s) should be converted to NFD(%s):%d",
+ nfc, nfd, line);
+ assertEqualUTF8String(utf8_nfd, utf8.s);
+#else
+ /*
+ * Normalize an NFD string for import.
+ */
+ assertEqualInt(0, archive_strcpy_in_locale(
+ &utf8, utf8_nfd, f_sconv8));
+ failure("NFD(%s) should be converted to NFC(%s):%d",
+ nfd, nfc, line);
+ assertEqualUTF8String(utf8_nfc, utf8.s);
+
+ /*
+ * Normalize an NFC string for import.
+ */
+ assertEqualInt(0, archive_strcpy_in_locale(
+ &utf8, utf8_nfc, f_sconv8));
+ failure("NFC(%s) should not be any changed:%d",
+ nfc, line);
+ assertEqualUTF8String(utf8_nfc, utf8.s);
+
+ /*
+ * Copy an NFC string for export.
+ */
+ assertEqualInt(0, archive_strcpy_in_locale(
+ &utf8, utf8_nfc, t_sconv8));
+ failure("NFC(%s) should not be any changed:%d",
+ nfc, line);
+ assertEqualUTF8String(utf8_nfc, utf8.s);
+
+ /*
+ * Normalize an NFD string in UTF-16BE for import.
+ */
+ assertEqualInt(0, archive_strncpy_in_locale(
+ &utf8, utf16be_nfd, 100000, f_sconv16be));
+ failure("NFD(%s) should be converted to NFC(%s):%d",
+ nfd, nfc, line);
+ assertEqualUTF8String(utf8_nfc, utf8.s);
+
+ /*
+ * Normalize an NFD string in UTF-16LE for import.
+ */
+ assertEqualInt(0, archive_strncpy_in_locale(
+ &utf8, utf16le_nfd, 100000, f_sconv16le));
+ failure("NFD(%s) should be converted to NFC(%s):%d",
+ nfd, nfc, line);
+ assertEqualUTF8String(utf8_nfc, utf8.s);
+#endif
+ }
+
+ /*
+ * Test for archive_mstring interface.
+ * In specific, Windows platform UTF-16BE is directly
+ * converted to/from wide-character to avoid the effect of
+ * current locale since windows platform cannot make
+ * locale UTF-8.
+ */
+ if (locale_is_utf8 || wc_is_unicode) {
+ const wchar_t *wp;
+ const char *mp;
+ size_t mplen;
+
+#if defined(__APPLE__)
+ /*
+ * Normalize an NFD string in UTF-8 for import.
+ */
+ assertEqualInt(0, archive_mstring_copy_mbs_len_l(
+ &mstr, utf8_nfc, 100000, f_sconv8));
+ assertEqualInt(0,
+ archive_mstring_get_wcs(a, &mstr, &wp));
+ failure("UTF-8 NFC(%s) should be converted "
+ "to WCS NFD(%s):%d", nfc, nfd, line);
+ assertEqualWString(wc_nfd, wp);
+
+ /*
+ * Normalize an NFD string in UTF-16BE for import.
+ */
+ assertEqualInt(0, archive_mstring_copy_mbs_len_l(
+ &mstr, utf16be_nfc, 100000, f_sconv16be));
+ assertEqualInt(0,
+ archive_mstring_get_wcs(a, &mstr, &wp));
+ failure("UTF-16BE NFC(%s) should be converted "
+ "to WCS NFD(%s):%d", nfc, nfd, line);
+ assertEqualWString(wc_nfd, wp);
+
+ /*
+ * Normalize an NFD string in UTF-16LE for import.
+ */
+ assertEqualInt(0, archive_mstring_copy_mbs_len_l(
+ &mstr, utf16le_nfc, 100000, f_sconv16le));
+ assertEqualInt(0,
+ archive_mstring_get_wcs(a, &mstr, &wp));
+ failure("UTF-16LE NFC(%s) should be converted "
+ "to WCS NFD(%s):%d", nfc, nfd, line);
+ assertEqualWString(wc_nfd, wp);
+
+ /*
+ * Copy an NFD wide-string for export.
+ */
+ assertEqualInt(0, archive_mstring_copy_wcs(
+ &mstr, wc_nfd));
+ assertEqualInt(0, archive_mstring_get_mbs_l(
+ &mstr, &mp, &mplen, t_sconv8));
+ failure("WCS NFD(%s) should be UTF-8 NFD:%d"
+ ,nfd, line);
+ assertEqualUTF8String(utf8_nfd, mp);
+#else
+ /*
+ * Normalize an NFD string in UTF-8 for import.
+ */
+ assertEqualInt(0, archive_mstring_copy_mbs_len_l(
+ &mstr, utf8_nfd, 100000, f_sconv8));
+ assertEqualInt(0,
+ archive_mstring_get_wcs(a, &mstr, &wp));
+ failure("UTF-8 NFD(%s) should be converted "
+ "to WCS NFC(%s):%d", nfd, nfc, line);
+ assertEqualWString(wc_nfc, wp);
+
+ /*
+ * Normalize an NFD string in UTF-16BE for import.
+ */
+ assertEqualInt(0, archive_mstring_copy_mbs_len_l(
+ &mstr, utf16be_nfd, 100000, f_sconv16be));
+ assertEqualInt(0,
+ archive_mstring_get_wcs(a, &mstr, &wp));
+ failure("UTF-8 NFD(%s) should be converted "
+ "to WCS NFC(%s):%d", nfd, nfc, line);
+ assertEqualWString(wc_nfc, wp);
+
+ /*
+ * Normalize an NFD string in UTF-16LE for import.
+ */
+ assertEqualInt(0, archive_mstring_copy_mbs_len_l(
+ &mstr, utf16le_nfd, 100000, f_sconv16le));
+ assertEqualInt(0,
+ archive_mstring_get_wcs(a, &mstr, &wp));
+ failure("UTF-8 NFD(%s) should be converted "
+ "to WCS NFC(%s):%d", nfd, nfc, line);
+ assertEqualWString(wc_nfc, wp);
+
+ /*
+ * Copy an NFC wide-string for export.
+ */
+ assertEqualInt(0, archive_mstring_copy_wcs(
+ &mstr, wc_nfc));
+ assertEqualInt(0, archive_mstring_get_mbs_l(
+ &mstr, &mp, &mplen, t_sconv8));
+ failure("WCS NFC(%s) should be UTF-8 NFC:%d"
+ ,nfc, line);
+ assertEqualUTF8String(utf8_nfc, mp);
+#endif
+ }
+ }
+
+ archive_string_free(&utf8);
+ archive_mstring_clean(&mstr);
+ fclose(fp);
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a2));
+}
+
+static void
+test_archive_string_canonicalization(void)
+{
+ struct archive *a;
+ struct archive_string_conv *sconv;
+
+ setlocale(LC_ALL, "en_US.UTF-8");
+
+ assert((a = archive_read_new()) != NULL);
+
+ assertA(NULL != (sconv =
+ archive_string_conversion_to_charset(a, "UTF-8", 1)));
+ failure("Charset name should be UTF-8");
+ assertEqualString("UTF-8",
+ archive_string_conversion_charset_name(sconv));
+
+ assertA(NULL != (sconv =
+ archive_string_conversion_to_charset(a, "UTF8", 1)));
+ failure("Charset name should be UTF-8");
+ assertEqualString("UTF-8",
+ archive_string_conversion_charset_name(sconv));
+
+ assertA(NULL != (sconv =
+ archive_string_conversion_to_charset(a, "utf8", 1)));
+ failure("Charset name should be UTF-8");
+ assertEqualString("UTF-8",
+ archive_string_conversion_charset_name(sconv));
+
+ assertA(NULL != (sconv =
+ archive_string_conversion_to_charset(a, "UTF-16BE", 1)));
+ failure("Charset name should be UTF-16BE");
+ assertEqualString("UTF-16BE",
+ archive_string_conversion_charset_name(sconv));
+
+ assertA(NULL != (sconv =
+ archive_string_conversion_to_charset(a, "UTF16BE", 1)));
+ failure("Charset name should be UTF-16BE");
+ assertEqualString("UTF-16BE",
+ archive_string_conversion_charset_name(sconv));
+
+ assertA(NULL != (sconv =
+ archive_string_conversion_to_charset(a, "utf16be", 1)));
+ failure("Charset name should be UTF-16BE");
+ assertEqualString("UTF-16BE",
+ archive_string_conversion_charset_name(sconv));
+
+ assertA(NULL != (sconv =
+ archive_string_conversion_to_charset(a, "UTF-16LE", 1)));
+ failure("Charset name should be UTF-16LE");
+ assertEqualString("UTF-16LE",
+ archive_string_conversion_charset_name(sconv));
+
+ assertA(NULL != (sconv =
+ archive_string_conversion_to_charset(a, "UTF16LE", 1)));
+ failure("Charset name should be UTF-16LE");
+ assertEqualString("UTF-16LE",
+ archive_string_conversion_charset_name(sconv));
+
+ assertA(NULL != (sconv =
+ archive_string_conversion_to_charset(a, "utf16le", 1)));
+ failure("Charset name should be UTF-16LE");
+ assertEqualString("UTF-16LE",
+ archive_string_conversion_charset_name(sconv));
+
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+}
+
+DEFINE_TEST(test_archive_string_conversion)
+{
+ test_archive_string_normalization();
+ test_archive_string_canonicalization();
+}
diff --git a/libarchive/test/test_archive_string_conversion.txt.Z.uu b/libarchive/test/test_archive_string_conversion.txt.Z.uu
new file mode 100644
index 000000000000..33c2e03bf7a2
--- /dev/null
+++ b/libarchive/test/test_archive_string_conversion.txt.Z.uu
@@ -0,0 +1,2605 @@
+$FreeBSD$
+begin 644 test_archive_string_conversion.txt.Z
+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
+M6X6+)XI.?S)<$HWMC"V*6WA-!2&,7G$[7$*-H6F4!AN-[U3#BSF*9W&4!B*-
+MZ52ABS^*;7&4!BF-!U5:C$6*<W&4!C"-%5R%BTN*>'A\*`V)9FJ4!@:-+&.1
+MBU2*(5Q#"5>*A'B4!AN,<FJ4!N.,)US[BQ<L\8AX:FI<98W-BV:*DW%P7'N-
+MTXMLBIEQ=ER`C=J+<HJ?>)D"+8U4/Z2+>(I7/X6+>XJG<5P+A8U"C(&*K7&9
+M`CR-L'&;BX>*LW&17(6-]XN-BJ1JEUR+BQ9.0PF3BJEJV@=-C:QJV@=<C*]J
+MUR@-B;)JI5ROC9%FV@=9C;AJV@>*C<:&FXNHBM!_V@>?C--_I8TVC<"&W66V
+M7+*-S(RTBN!QV@<8B\UJV@<;C-!JPER+B]-JQ5S%C89MR%S3C7IGRUS6C5J,
+MCRSQB-]JFXMS,]R-6&1W"?6,PHV)B].*_7C:7-"-863=7-:-NHO<B@6`=PG!
+MC<5CPXOBB@QR*RG3C:J,Z(K[:C,I`HG,8W<)XXS/8X$)_(T:@/A<`HZSC?>*
+M/4>;B_J*)')P"5.-WF-P">.-/G(`9W`)*8WD8PI=!8[,C`F+^3\)CKZ-.X<F
+MC`^+_S\)CFB-6G*$C!6+!4`)CK>*"4!#"1N+.(<JCO^-_V,E71>.)F<H73&.
+MYXLGBSMK+ETTCI&++8M5>31=-(Z^BS.+3H<Z73&.GHLYBX)'0PD\BRU`1X[Q
+MC?8P6HQ"BXM'FXM%BV"'.1<HCBID.1?IB_8PC8LB+>DG86M47?R-,V2)";>,
+M9H>^BU>+%3G#BRXM6XX\9%]=7H[*BV&+>X=E76N.$6=H77".V(QKB[-'0PEN
+MBQ]6=XY+CHJ'=%USCN&+=XN?@'I=?HZ)BWV+RT=WCO^-J'F#77Z.UF6&78>+
+M,S&Z8XE=&(QXAUUVC5V.CK2`D%V2CH1RQF.478Z.=&2779V.)F::79F.1U;"
+M8^TI_(U]9*!=HXZ`9*-=IXX7;J9=H(Z89JE=L(ZY:ZQ=JHYK:*]=LX[=9;)=
+MN8X>9+5=K8YQ:[A=N8['9+M=N8[M9;Y=N8[Q9<%=MHX89\1=N8[Y9<==OXZ.
+M;<I=N8X`9LU=N8Y29;$"'(Z+73)L,"K1CJ5PUUVYC@EEVEW+CC5GW5W>CI".
+M_C=;C@)Z(P7LBP5ZYUW1CIN.\HL-<^U=CH[*9/!=]8["9?-=^([&9?9=_(W3
+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
+MN:JXGA0T8ZVX;K;BC%^X<;;76S1C)+@[#3<P)[BL%#<P*KA[MNZ,7;A^MO"J
+M0[G"N.&S]XQ?N.2S9*M*N3FXBK;P6T.YSKCMLPZL2KE"N).V!8U#N:>X]K,<
+M*$JY2[B<M@)<0[FPN/^S!UQ*N22X[@DSE">XY!`SE"JXJ[9-!2VXKK8AC5VX
+ML;9-!3.XM+8HC7*YR+@7M"^-7[@:M$T%SK@=M$T%T;@@M"E<,Y1%N,:V305(
+MN,FV305+N,RV,EQRN;"X+[1&C7RY)+A-%CXP+;BU#3XP,+CAMI0&,[CDMEB-
+M7;CGMDY<H+G+N$JT5%Q?N$VT9(T^,$*X\[9GC:"YI[A6M%]<I[E+N/RV<(V@
+MN;"X7[1G7*>Y)+@%MVI<7;C9#3F4*KC=#3F4+;@.MW-<OKG"N'&T>5Q?N'2T
+MB8W+N3FX&K>K*+ZYSKA]M)*-.91"N".WMRB^N:>XAK2.7,NY2[@LMY%<OKFP
+MN(^TEUPYE"2X-;?:!R>X.+>HC5VX.[>KC>VYM++7*.VYPKB""T4PQ;@2"D4P
+MR+B^%D4PR[CA!D4PSKC$%D4PT;C'%D4PI+B5"T4PI[B8"T4PJKB;"T4PK;C3
+M%D4PL+@O"44PL[BE"\8%9;?(7%VX:+?+7!JZ>[+.7!JZ\;FS`1JZPKC_!!>Z
+MQ;CL%A>ZR+CP%A>ZR[CS%E!C=+)@CEVX^+=973*Z'KKXM&J.4&,PN`&X5JY0
+M8\6X`;5RCE!C.;@*N&M=,KK.N`JU<5U?N`VU?8Y08T6X%KAW73*ZJK@6M;A=
+M/A)QL[M=/A)YLKY=/A*RLALJ/A*`LL1=/A*1LM"./A*'LLI=/A(UM<U=/A*H
+MLMF.E;79CG*RW8X^$C^U(8]LNK6UA"ISNEBZ:08Q$BL8>;JTLHT)>;J"LF4,
+M;KK#M3*/@;J)LBY>@;J9LC%>@;K#LC1>@;K'LJ$J@;J.LZ4J@;J2LSQ>@;J5
+MLZPJ@;J9LTB/@;J<LTN/@;ILLT=>;KI,"C$2YK6DNJVRSK"DNGNR6(^BNGRZ
+MJPJDNG^Z1""DNHBZ[A*DNHNZO`JDNHZZ1!2DNI&ZPPJDNI2Z>!BDNI>Z"[9Q
+M7J2ZGK9T7FRZ$;9W7J2ZI+9Z7F)C5;K5"F)C6+KEN(!>;KKKN`0KU;J%L@@K
+MU;J%NH.SEH]B8VJZ+;;&`L6RQ@*.NO$*8F.1NOZXH8]LN@&YQ@*7NCNV)RMB
+M8\:ZL!AB8YZSK8_KNLRZH[,T*VZZ$;FL7ONZJKJKLW4%?+JNL[R/,1*QL[^/
+M!;MDNE>VOU[[NHNZO;-U!8ZZP+-4*P6[D+/1CVRZVAAG8W2RWUYNNCZYR@)8
+MNGNV00T;NW^ZX;/SCVRZY[/*`HBZZK/*`HNZ[;/]CV=C<;J3MOY>&[N4NO:S
+M9@TENY>SR@*:NORS"U\EN_6Z<0UG8\RZ9[FI*VZZ:KF*#5BZJ[:2K$.[?+H.
+MM""0;+H1M(H-V;H4M+TK3;MGNKJVP2M#NXNZ';3)*TV[<;K#MHH-%+O&MHH-
+M"+:=#4V[-[O,MCM?0[N=NB^TWBM-N\RZJ0UM8U6ZK0UM8UBZE;FQ#6ZZF+E/
+MD':[?[I!M%:0;+I$M%J0?;MGNNJV"0AJNNVV"0CCNO"VRPUVNY&Z4[0)")2Z
+M5K0)")>Z6;1L7WV[QKK_M@D(];I7(6UCS+H%M^$-5;J_N>$-6+K"N>$-6[H.
+MM^$-7KH1MR<L;KH4MRLLJKN%NG>T\`ULNGJTX0V+NGVTX0V.NH"TX0V1NH.T
+MX0V4NH:TX0V7NHFTX0V:NHRTY*VQN_6Z,K=/+&ZZ-;>)!56Z.+>LD,J[JKIZ
+M!G5C?+H&`G5C?[KUN8D%V;KXN8D%A;K[N8D%B+K^N8D%B[H!NHD%CKH$NH.O
+M;+H'NHD%E+H*NHD%E[H-ND(.Z;O&NE^WB07UNF*W@RQNNF6WARSYNZ>ZB"-Y
+M8ZJZC"-Y8WRZ(KIY8W^Z);K@`MFZ*+K@`H6Z*[K@`HBZ+KK@`HNZ]A9Y8XZZ
+M$P5Y8Y&Z=0EY8Y2Z_Q9Y8Y>Z'@5Y8YJZ!1=Y8YVZ"!=Y8Z"Z"Q=^,!F[-@=^
+M,*>Z.@=^,*JZ%1=^,'RZF[22!7^ZGK22!=FZH;22!86ZI+22!8BZI[22!8NZ
+MJK2I#FRZK;2M#D6\%+NVMY(%8KNYMY4);KJ\MYD)?C"=NKRTD@6@NK^TRPX9
+MN\*TRPZGNL6TRPZJNLBTRPY\NLNTRPY_NLZTRP[9NM&TRPZ%NM2TRPZ(NM>T
+MRPZ+NMJTRPZ.NMVTRPZ1NN"TRPZ4NN.TRPZ7NN:TRPZ:NNFT8&!LNNRTRPZ@
+MNN^TFP49N_*T:F!LNO6TFP6JNOBT<6",O%ZZ`;AU8&ZZ!+B;!62Z![B;!6>Z
+M"KB;!6JZ#;B;!>.Z$+B;!7&Z$[B;!12[%KB;!6*[&;B;!9>S7RV%8WFR8BV%
+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
+M@8X3C=-#LH4!1;)"K#!P2*PP<)/342W4@5>R8@+EK9O3CZP:)LO,&B9"K,V,
+M-@O.&&$7Z!*FTY[3,PCS`V$?2@:<$ZW3G]&>4:?3L1Q@%[2<N#EG$RR"7*WK
+MNX^LF8PU!`H)[U`GLJ2\HZR'TY+./()YK9L7/()SK+P7C*P9L/"\NP$$L6*2
+M8!=(=OIKU1"K`M@!M05!`8$!LP*X`K\!;@NU$7,2C@C:T[8"UM/>T^#3?!`9
+M#K<!U]/K$$4!V=,/"\4"X]-5`MC3"@':TT(&1J;>TUH1Y=.[`MS3Z=.4&_+3
+MYM,?,JD!W=/PT^K3_-,(`[L"[].'#@34\]/GT_73`]2;#OC3W`U)LP'4"=3^
+MT[D"#-0(U)@1$]0&U`#4&P16`?C3]-,2U!C4Q`SKT_W3NP*T`2#4O@<>U`O4
+M(-2A#_'3!=3BTQO4_PLIU/_3Z-/VTTP![--*`QL1%M08U#+4%=0@U#@1(]0N
+MU.[3,-0P`>D%-]0?U/O3.4E`U.'3*M0;!)<"+=0*U#/4.M1.U$K4[=/5TT/4
+M<0-/U!34^M/VT[D'#]0G#EO45-3;TU?4#PX#U`_40M0TU&<&8=1'U/;3F`\W
+MU-`%2P)CU"C41M1,U&\%9=1NU&?4.M2T`SS48-1S$@$59M3!`G'46=1BU&C4
+M1!+?TW?45M2$U(\(@M1KU`W4X@]NU`@.)M3[TWO48]3C`H+4+]2)U.4#D]2)
+MU,,'F=2'U,8"@=1JU'3410+DTY[4!]1@=J'44=0GU$,$EM2BU"D(I-0DU(S4
+MKM1VU"34E]0ZU#D!FM0ZU,,'M]1WU&*:H-09U+'49P&&U+34>-0@U(H,N-2J
+MU#`!QM2'U#W4&P2.#'+4L-2MU(."L]1!U(C4.M06!,?42-37U,O4?-2UB]/4
+M4-3,U",!DM2EU&/4!P9SU*G42-3EU,/4U06^U-C4UP6OU-34`@%7U,<'J-3@
+MU&74S]34U/74J!_OU-_4?-3SU,+4\-0'U#V>]-3<U"C4WP5WU/P4F]2+U*W4
+M`M7_U$O4U=02U,^E`]7LU$T$?]3YU!'5#=5:U/+44PZLU`_5U]0=U.;4^=0[
+MU!_5P]3GU%$1O]0+U2S48=2UU!#5-M30U"759=0MU?C4_=0_U"?5+]6`$3O4
+MX]1`U`34C2`NU<,"]]0[U9T')-7QU#K5C@@\U074XPT_U4750=4RU54:2@9!
+M`5W4$;//#3W591I.U44!4-6O`>$##M6T`HD"F=17U<,!6=49U5S53]5CU5_5
+M)-5;U94#7=5!`4FS4M5'U1D.8M56U6K56-5FU535F=28#U'58-5BU&_5]QMD
+MU;H!>-5]`6?55=7&&T$!%K-LU?S43=5IU44!A-5^U6[5:-6#U7S5A=5AU8W5
+MB=6/U8O5_]-ZU>`'5QQRU6W5EM62U8+510&=LI#56P*`U9G4X@]WU5/5A]5!
+M`:75FM4.U4/5.]6'`QP!2]6&U=/4Q1^PU2\!K-4HU)W4M=6GU674N=4+`;'5
+M5=2=(OZ-80%&`6_5AM5=!=?4[P/$U9+56M5`"L+5KP[*U575QM7.U;X.9`'%
+MU<#5=-5DU4D[J]61U8'5F-6E"'W5<]6HU44!M]2FU9O5H]5!`>35V]6BU=C5
+M<-5%`>@!X-7FU>S5GM7.'^K5?]7RU3,%E-6GU9?5QM3EU<S5XM7SU0$!ZM5N
+M!9?57=0NLZ'5]M7_U0'6[=7PU8;5E]77U/W5U]4)UEW4A`(,UMS5B-74'_75
+MC-7=U0<&$-9YU9W5FP/YU4S5!-8A`<@!H=4#UA_6;PTEUI75Y]46`2C4'=8G
+MUH'5GP,AUO[5S@F(!#@#S=4C!;O5T@DA`3?6-K\YUDS5-=8\UD+6Q]4ZUDHJ
+M%@$]UD360-8[UD?6(0$6(\[5LM5+UK@<3=8^UO0"--91UK((4M9)UE#61M;D
+M'$/63]81UB/6+0X5UA[6W=5S#?75"`[WU2_6&M:S#1W4'=8(UF'61QT"UFO6
+MV=7'$AG6G-4QUDP!:M9WUK,->=9VUBS6\]51"'+6>]9TUN,!?M40`6G6@M9_
+MUH'6"]8'UG/6[=69'8G6B-86`6[6CM:0UHS6>-4PUK,-7M5CU@C60=9,UNL#
+M5-9%UC;6QPM:UA'6GM;P`U[6/]9;UN4+J=95UJ;65]8]`Z'6\=7*":/6%@$^
+MOZK6[=,J2Z?6J0BEUH/45]8[##C6KM;KU1+6(0&@U9C6E=:8U9T%?M;RU<K6
+ME];ZU9W5S=:>U9S6R-9O#1^S)M;4UB$!UM8KULS6B-5CUIG6V=8SUF#6*-8A
+M`2.SU]:#UH_6M0C3UN?6@A[AUF36LPW)U936Z];)UKD!YM9_UO/6R];_U?P3
+M[=;?UA8!Z=5EU2+6X]8##)'6Q-8"U__6_M5ZU0T(SM:SU@C7_-7XUG#6J`8#
+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
++.++T-:O0]*`Y=/,`
+`
+end
diff --git a/libarchive/test/test_archive_write_set_filter_option.c b/libarchive/test/test_archive_write_set_filter_option.c
new file mode 100644
index 000000000000..87a3e5350bd4
--- /dev/null
+++ b/libarchive/test/test_archive_write_set_filter_option.c
@@ -0,0 +1,55 @@
+/*-
+ * Copyright (c) 2011 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+#define should(__a, __code, __m, __o, __v) \
+assertEqualInt(__code, archive_write_set_filter_option(__a, __m, __o, __v))
+
+static void
+test(int pristine)
+{
+ struct archive* a = archive_write_new();
+
+ if (!pristine)
+ archive_write_set_compression_gzip(a);
+
+ should(a, ARCHIVE_OK, NULL, NULL, NULL);
+ should(a, ARCHIVE_OK, "", "", "");
+
+ should(a, ARCHIVE_FAILED, NULL, "fubar", NULL);
+ should(a, ARCHIVE_FAILED, NULL, "fubar", "snafu");
+ should(a, ARCHIVE_FAILED, "fubar", "snafu", NULL);
+ should(a, ARCHIVE_FAILED, "fubar", "snafu", "betcha");
+
+ archive_write_finish(a);
+}
+
+DEFINE_TEST(test_archive_write_set_filter_option)
+{
+ test(1);
+ test(0);
+}
diff --git a/libarchive/test/test_archive_write_set_format_option.c b/libarchive/test/test_archive_write_set_format_option.c
new file mode 100644
index 000000000000..ee53ca4c39d2
--- /dev/null
+++ b/libarchive/test/test_archive_write_set_format_option.c
@@ -0,0 +1,67 @@
+/*-
+ * Copyright (c) 2011 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+#define should(__a, __code, __m, __o, __v) \
+assertEqualInt(__code, archive_write_set_format_option(__a, __m, __o, __v))
+
+static void
+test(int pristine)
+{
+ struct archive* a = archive_write_new();
+ int known_option_rv = pristine ? ARCHIVE_FAILED : ARCHIVE_OK;
+
+ if (!pristine)
+ archive_write_set_format_iso9660(a);
+
+ /* NULL and "" denote `no option', so they're ok no matter
+ * what, if any, formats are registered */
+ should(a, ARCHIVE_OK, NULL, NULL, NULL);
+ should(a, ARCHIVE_OK, "", "", "");
+
+ /* unknown modules and options */
+ should(a, ARCHIVE_FAILED, "fubar", "snafu", NULL);
+ should(a, ARCHIVE_FAILED, "fubar", "snafu", "betcha");
+
+ /* unknown modules and options */
+ should(a, ARCHIVE_FAILED, NULL, "snafu", NULL);
+ should(a, ARCHIVE_FAILED, NULL, "snafu", "betcha");
+
+ /* ARCHIVE_OK with iso9660 loaded, ARCHIVE_WARN otherwise */
+ should(a, known_option_rv, "iso9660", "joliet", NULL);
+ should(a, known_option_rv, "iso9660", "joliet", NULL);
+ should(a, known_option_rv, NULL, "joliet", NULL);
+ should(a, known_option_rv, NULL, "joliet", NULL);
+
+ archive_write_finish(a);
+}
+
+DEFINE_TEST(test_archive_write_set_format_option)
+{
+ test(1);
+ test(0);
+}
diff --git a/libarchive/test/test_archive_write_set_option.c b/libarchive/test/test_archive_write_set_option.c
new file mode 100644
index 000000000000..a7957ed7b266
--- /dev/null
+++ b/libarchive/test/test_archive_write_set_option.c
@@ -0,0 +1,69 @@
+/*-
+ * Copyright (c) 2011 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+#define should(__a, __code, __m, __o, __v) \
+assertEqualInt(__code, archive_write_set_option(__a, __m, __o, __v))
+
+static void
+test(int pristine)
+{
+ struct archive* a = archive_write_new();
+ int known_option_rv = pristine ? ARCHIVE_FAILED : ARCHIVE_OK;
+
+ if (!pristine) {
+ archive_write_set_compression_gzip(a);
+ archive_write_set_format_iso9660(a);
+ }
+
+ /* NULL and "" denote `no option', so they're ok no matter
+ * what, if any, formats are registered */
+ should(a, ARCHIVE_OK, NULL, NULL, NULL);
+ should(a, ARCHIVE_OK, "", "", "");
+
+ /* unknown modules and options */
+ should(a, ARCHIVE_FAILED, "fubar", "snafu", NULL);
+ should(a, ARCHIVE_FAILED, "fubar", "snafu", "betcha");
+
+ /* unknown modules and options */
+ should(a, ARCHIVE_FAILED, NULL, "snafu", NULL);
+ should(a, ARCHIVE_FAILED, NULL, "snafu", "betcha");
+
+ /* ARCHIVE_OK with iso9660 loaded, ARCHIVE_WARN otherwise */
+ should(a, known_option_rv, "iso9660", "joliet", NULL);
+ should(a, known_option_rv, "iso9660", "joliet", NULL);
+ should(a, known_option_rv, NULL, "joliet", NULL);
+ should(a, known_option_rv, NULL, "joliet", NULL);
+
+ archive_write_finish(a);
+}
+
+DEFINE_TEST(test_archive_write_set_option)
+{
+ test(1);
+ test(0);
+}
diff --git a/libarchive/test/test_archive_write_set_options.c b/libarchive/test/test_archive_write_set_options.c
new file mode 100644
index 000000000000..f98342eac0b7
--- /dev/null
+++ b/libarchive/test/test_archive_write_set_options.c
@@ -0,0 +1,79 @@
+/*-
+ * Copyright (c) 2011 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+#define should(__a, __code, __opts) \
+assertEqualInt(__code, archive_write_set_options(__a, __opts))
+
+static void
+test(int pristine)
+{
+ struct archive* a = archive_write_new();
+ int halfempty_options_rv = pristine ? ARCHIVE_WARN : ARCHIVE_OK;
+ int known_option_rv = pristine ? ARCHIVE_FAILED : ARCHIVE_OK;
+ int mixed_options_rv = pristine ? ARCHIVE_FAILED : ARCHIVE_WARN;
+
+ if (!pristine) {
+ archive_write_set_compression_gzip(a);
+ archive_write_set_format_iso9660(a);
+ }
+
+ /* NULL and "" denote `no option', so they're ok no matter
+ * what, if any, formats are registered */
+ should(a, ARCHIVE_OK, NULL);
+ should(a, ARCHIVE_OK, "");
+
+ /* unknown modules and options */
+ should(a, ARCHIVE_FAILED, "fubar:snafu");
+ should(a, ARCHIVE_FAILED, "fubar:snafu=betcha");
+
+ /* unknown modules and options */
+ should(a, ARCHIVE_FAILED, "snafu");
+ should(a, ARCHIVE_FAILED, "snafu=betcha");
+
+ /* ARCHIVE_OK with iso9660 loaded, ARCHIVE_WARN otherwise */
+ should(a, known_option_rv, "iso9660:joliet");
+ should(a, known_option_rv, "iso9660:joliet");
+ should(a, known_option_rv, "joliet");
+ should(a, known_option_rv, "!joliet");
+
+ should(a, ARCHIVE_OK, ",");
+ should(a, ARCHIVE_OK, ",,");
+
+ should(a, halfempty_options_rv, ",joliet");
+ should(a, halfempty_options_rv, "joliet,");
+
+ should(a, mixed_options_rv, "joliet,snafu");
+
+ archive_write_finish(a);
+}
+
+DEFINE_TEST(test_archive_write_set_options)
+{
+ test(1);
+ test(0);
+}
diff --git a/libarchive/test/test_bad_fd.c b/libarchive/test/test_bad_fd.c
index 3ea7daacf2e5..f8144a3c39a4 100644
--- a/libarchive/test/test_bad_fd.c
+++ b/libarchive/test/test_bad_fd.c
@@ -30,12 +30,8 @@ DEFINE_TEST(test_bad_fd)
{
struct archive *a;
assert((a = archive_read_new()) != NULL);
- assertA(0 == archive_read_support_compression_all(a));
+ assertA(0 == archive_read_support_filter_all(a));
assertA(ARCHIVE_FATAL == archive_read_open_fd(a, -1, 1024));
- assertA(0 == archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assertA(0 == archive_read_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_compat_bzip2.c b/libarchive/test/test_compat_bzip2.c
index 343f451ae692..d0726a1d36a0 100644
--- a/libarchive/test/test_compat_bzip2.c
+++ b/libarchive/test/test_compat_bzip2.c
@@ -47,7 +47,7 @@ compat_bzip2(const char *name)
int i;
assert((a = archive_read_new()) != NULL);
- if (ARCHIVE_OK != archive_read_support_compression_bzip2(a)) {
+ if (ARCHIVE_OK != archive_read_support_filter_bzip2(a)) {
skipping("Unsupported bzip2");
return;
}
@@ -71,8 +71,12 @@ compat_bzip2(const char *name)
assertEqualString(archive_compression_name(a), "bzip2");
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR);
- assertEqualInt(ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_BZIP2);
+ assertEqualString(archive_compression_name(a), "bzip2");
+ assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR);
+
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_compat_cpio.c b/libarchive/test/test_compat_cpio.c
index 8f97036c4f39..e1e4e13997f6 100644
--- a/libarchive/test/test_compat_cpio.c
+++ b/libarchive/test/test_compat_cpio.c
@@ -48,7 +48,7 @@ test_compat_cpio_1(void)
struct archive *a;
assert((a = archive_read_new()) != NULL);
- assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
extract_reference_file(name);
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 17));
@@ -94,7 +94,7 @@ test_compat_cpio_1(void)
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_CPIO_SVR4_NOCRC);
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_compat_gtar.c b/libarchive/test/test_compat_gtar.c
index c0a69598e98f..f8f3ec06d280 100644
--- a/libarchive/test/test_compat_gtar.c
+++ b/libarchive/test/test_compat_gtar.c
@@ -46,7 +46,7 @@ test_compat_gtar_1(void)
int r;
assert((a = archive_read_new()) != NULL);
- assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
extract_reference_file(name);
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240));
@@ -54,7 +54,7 @@ test_compat_gtar_1(void)
/* Read first entry. */
assertEqualIntA(a, ARCHIVE_OK, r = archive_read_next_header(a, &ae));
if (r != ARCHIVE_OK) {
- archive_read_finish(a);
+ archive_read_free(a);
return;
}
assertEqualString(
@@ -73,7 +73,7 @@ test_compat_gtar_1(void)
/* Read second entry. */
assertEqualIntA(a, ARCHIVE_OK, r = archive_read_next_header(a, &ae));
if (r != ARCHIVE_OK) {
- archive_read_finish(a);
+ archive_read_free(a);
return;
}
assertEqualString(
@@ -103,11 +103,7 @@ test_compat_gtar_1(void)
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_GNUTAR);
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
-#endif
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_compat_gzip.c b/libarchive/test/test_compat_gzip.c
index a76b2f8f8d7b..885c681415ec 100644
--- a/libarchive/test/test_compat_gzip.c
+++ b/libarchive/test/test_compat_gzip.c
@@ -47,10 +47,10 @@ verify(const char *name)
int i,r;
assert((a = archive_read_new()) != NULL);
- r = archive_read_support_compression_gzip(a);
+ r = archive_read_support_filter_gzip(a);
if (r == ARCHIVE_WARN) {
skipping("gzip reading not fully supported on this platform");
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
return;
}
assertEqualIntA(a, ARCHIVE_OK, r);
@@ -64,7 +64,7 @@ verify(const char *name)
assertEqualIntA(a, ARCHIVE_OK,
archive_read_next_header(a, &ae));
if (r != ARCHIVE_OK) {
- archive_read_finish(a);
+ archive_read_free(a);
return;
}
assertEqualString(n[i], archive_entry_pathname(ae));
@@ -79,7 +79,7 @@ verify(const char *name)
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR);
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_compat_lzip.c b/libarchive/test/test_compat_lzip.c
new file mode 100644
index 000000000000..f474cd49e1d7
--- /dev/null
+++ b/libarchive/test/test_compat_lzip.c
@@ -0,0 +1,141 @@
+/*-
+ * Copyright (c) 2010 Michihiro NAKAJIMA
+ * Copyright (c) 2003-2008 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+/*
+Execute the following to rebuild the data for this program:
+ tail -n +33 test_compat_lzip.c | /bin/sh
+
+# Use lzip command.
+zcmd=lzip
+zsuffix=lz
+ztar_suffix=tlz
+mktarfile()
+{
+mkdir $dir
+echo "f1" > $dir/f1
+echo "f2" > $dir/f2
+echo "f3" > $dir/f3
+mkdir $dir/d1
+echo "f1" > $dir/d1/f1
+echo "f2" > $dir/d1/f2
+echo "f3" > $dir/d1/f3
+(cd $dir; tar cf ../$name.tar f1 f2 f3 d1/f1 d1/f2 d1/f3)
+rm -r $dir
+}
+#
+# Make a lzip file from splitted tar file.
+#
+name=test_compat_lzip_1
+dir="$name`date +%Y%m%d%H%M%S`.$USER"
+mktarfile
+split -b 3600 $name.tar $name.tar.
+rm $name.tar
+$zcmd $name.tar.*
+cat $name.tar.*.$zsuffix > $name.$ztar_suffix
+rm $name.tar.*.$zsuffix
+uuencode $name.$ztar_suffix $name.$ztar_suffix > $name.$ztar_suffix.uu
+rm -f $name.$ztar_suffix
+#
+# Make a lzip file with junk data at the end of the file.
+#
+name=test_compat_lzip_2
+dir="$name`date +%Y%m%d%H%M%S`.$USER"
+mktarfile
+$zcmd $name.tar
+mv $name.tar.$zsuffix $name.$ztar_suffix
+echo "This is unrelated junk data at the end of the file" >> $name.$ztar_suffix
+uuencode $name.$ztar_suffix $name.$ztar_suffix > $name.$ztar_suffix.uu
+rm -f $name.$ztar_suffix
+
+exit 0
+*/
+
+/*
+ * Verify our ability to read sample files compatibly with lzip.
+ *
+ * In particular:
+ * * lzip will read multiple lzip streams, concatenating the output
+ * * lzip will stop at the end of a stream if the following data
+ * doesn't start with a gzip signature.
+ *
+ */
+
+/*
+ * All of the sample files have the same contents; they're just
+ * compressed in different ways.
+ */
+static void
+compat_lzip(const char *name)
+{
+ const char *n[7] = { "f1", "f2", "f3", "d1/f1", "d1/f2", "d1/f3", NULL };
+ struct archive_entry *ae;
+ struct archive *a;
+ int i, r;
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ r = archive_read_support_filter_lzip(a);
+ if (r == ARCHIVE_WARN) {
+ skipping("lzip reading not fully supported on this platform");
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+ return;
+ }
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ extract_reference_file(name);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 2));
+
+ /* Read entries, match up names with list above. */
+ for (i = 0; i < 6; ++i) {
+ failure("Could not read file %d (%s) from %s", i, n[i], name);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_next_header(a, &ae));
+ assertEqualString(n[i], archive_entry_pathname(ae));
+ }
+
+ /* Verify the end-of-archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify that the format detection worked. */
+ assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_LZIP);
+ assertEqualString(archive_compression_name(a), "lzip");
+ assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR);
+
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+
+DEFINE_TEST(test_compat_lzip)
+{
+ /* This sample has been 'split', each piece compressed separately,
+ * then concatenated. lzip will emit the concatenated result. */
+ compat_lzip("test_compat_lzip_1.tlz");
+ /* This sample has been compressed as a single stream, but then
+ * some unrelated garbage text has been appended to the end. */
+ compat_lzip("test_compat_lzip_2.tlz");
+}
diff --git a/libarchive/test/test_compat_lzip_1.tlz.uu b/libarchive/test/test_compat_lzip_1.tlz.uu
new file mode 100644
index 000000000000..01e5e3bfadee
--- /dev/null
+++ b/libarchive/test/test_compat_lzip_1.tlz.uu
@@ -0,0 +1,10 @@
+begin 644 test_compat_lzip_1.tlz
+M3%I)4`$,`#,,/!NGC#0&C6L"2_R2/O9*^":#5/GP,U"QL$1\Q:(3S>V*OTP*
+M1&9J-1:S\^>DEIOT;'&#"`B6#7ZO7%">,>LZ=:BU,Z7*^>M<3FV:GKO_?W;`
+M,N31CE_$<-$(3$J*AB5TTG2\;X[CSPOI6IIPV8\]86+J37::!/_LA^/@O"(1
+MAA`.````````F`````````!,6DE0`0P``&_]_BC86HZ6L8?*M6SC8*JJ7,GS
+M0IZA9CQ/^VS2N26K[BXKGC_1Z&JR]S2)5Q",)*$1RS"):7X:?OBQDJXU`>8K
+M\2*:_6!:)ZD5FBGJ?II6>-<K71*E]Z%2+8"G-.(X-N74SK.)7_YTN3Z\/1D0
+0\`T```````"&````````````
+`
+end
diff --git a/libarchive/test/test_compat_lzip_2.tlz.uu b/libarchive/test/test_compat_lzip_2.tlz.uu
new file mode 100644
index 000000000000..bf954f2f92cb
--- /dev/null
+++ b/libarchive/test/test_compat_lzip_2.tlz.uu
@@ -0,0 +1,9 @@
+begin 644 test_compat_lzip_2.tlz
+M3%I)4`%-`#,,/!NGC#0&C6L"2_R2/O9*^":#5/GP,U"QL$1\Q:(3S>V*OTP*
+M1&9J-1:S\^>DEIOT;'&#"`B6#7ZO7%">,>LZ=:BU,Z7*^>M<3FV:GKO_?W;`
+M,N31CE_$<-$(3$J*AB5TTG2\;X[CSPOI6IIPV8\]9>BP>V?/L._78%+F2N-;
+M6V[`1"7)=_,5LD9U%73FQV-?_X5OKW0_.'N"`!P```````"R`````````%1H
+M:7,@:7,@=6YR96QA=&5D(&IU;FL@9&%T82!A="!T:&4@96YD(&]F('1H92!F
+$:6QE"@``
+`
+end
diff --git a/libarchive/test/test_compat_lzma.c b/libarchive/test/test_compat_lzma.c
index 6aefbc2ebc30..8d37dd1879f6 100644
--- a/libarchive/test/test_compat_lzma.c
+++ b/libarchive/test/test_compat_lzma.c
@@ -107,11 +107,11 @@ compat_lzma(const char *name)
int i, r;
assert((a = archive_read_new()) != NULL);
- assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a));
- r = archive_read_support_compression_lzma(a);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ r = archive_read_support_filter_lzma(a);
if (r == ARCHIVE_WARN) {
skipping("lzma reading not fully supported on this platform");
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
return;
}
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
@@ -135,7 +135,7 @@ compat_lzma(const char *name)
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR);
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_compat_mac-1.tar.Z.uu b/libarchive/test/test_compat_mac-1.tar.Z.uu
new file mode 100644
index 000000000000..c5eda8017f72
--- /dev/null
+++ b/libarchive/test/test_compat_mac-1.tar.Z.uu
@@ -0,0 +1,38 @@
+begin 644 test_compat_mac-1.tar.Z
+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
+$2UM(`0``
+`
+end
diff --git a/libarchive/test/test_compat_mac-2.tar.Z.uu b/libarchive/test/test_compat_mac-2.tar.Z.uu
new file mode 100644
index 000000000000..09761b9736bd
--- /dev/null
+++ b/libarchive/test/test_compat_mac-2.tar.Z.uu
@@ -0,0 +1,19 @@
+begin 644 test_compat_mac-2.tar.Z
+M'YV0+EX`&$BPH,&#"!,J7,BPH4.$,"+>J%$#!("(,&[8J'@1HPP:%C&*%`DB
+M1@R*-&[0J`$CQ@T0+4W:@`$`1(V'.'/JW,D30)TY=,+(Z4@G39N>"H&&,6,&
+MZ<&1,$*.M.BTJM6K6+/V#.CB2YL\9-(,U4JV+$&,$SFBW2@UXL>V(VG$F%'R
+M9(V4*UN^;/EQ94V:9@,+)O@SZ-"(18]J5<HT*U2X$:D.GDRY\M4"%@X`$#"P
+M29@Q()Y,`8$%A.G3IC<33$!0!L%L!#D#"+#`<A`J5*0,%/!G(&V"_`@^P$D`
+M.,$"`RN,>=/&Q1LXR\F4D3/'19@O9L0")1@@`$$#`RTL;_X\^O3J8K[,*;/<
+M#9F'RID[A_Y&.G478[Z4:0.'3A[NF@U4'``4C#>?>?>1\04;86P'0';4T;%>
+M>V0PZ*!E&&:HX88<!O156'((Q.&(!:%%45L:J>412!U!A5%=**G$DDLPQ2##
+M###04---)/:84&%"$64468PUA=5C+;[HXY),6L655WEDQT8936:(D0TTL+B6
+MBFYIZ:)<=)D48UXT\C73#']5R220A\&0&)%!-7;D5$E&IN:=>"Z$F6:R>0::
+M:*2AAIIJ`[$VD&L#P;:;;[55=EMNN_G!J'$##??0@``$-Q!R`,1''GWV57<=
+MA!=V]UUX!I97WWDNI#?A&^[!ERJHK.:W7W__^18@``,6*)^JH;J@H(5T#$2J
+MA.S!6F&#Q>;I[+/0[N1AE&E,&:U@5V:)(EM)OE7G8V+>):->-=Y8@PUI7HLA
+MFT(JEE61CM&)I+KTUFOOO?CFJ^^^_/;K[[\`!RSPP`07;/#!"">L\,(,-^SP
+MPQ!'+/'$%%=L\<489ZSQQAQW[/''((<L\L@DEVSRR2BGK/+*++?L\LLPQRSS
+*S#37;//-..>,$```
+`
+end
diff --git a/libarchive/test/test_compat_mac.c b/libarchive/test/test_compat_mac.c
new file mode 100644
index 000000000000..0149d2ecb9b7
--- /dev/null
+++ b/libarchive/test/test_compat_mac.c
@@ -0,0 +1,207 @@
+/*-
+ * Copyright (c) 2003-2010 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+/* The sample has some files in a directory with a very long name. */
+#define TESTPATH "abcdefghijklmnopqrstuvwxyz/" \
+ "abcdefghijklmnopqrstuvwxyz/" \
+ "abcdefghijklmnopqrstuvwxyz/" \
+ "abcdefghijklmnopqrstuvwxyz/" \
+ "abcdefghijklmnopqrstuvwxyz/" \
+ "abcdefghijklmnopqrstuvwxyz/" \
+ "abcdefghijklmnopqrstuvwxyz/"
+
+/*
+ * Apple shipped an extended version of GNU tar with Mac OS X 10.5
+ * and earlier.
+ */
+void test_compat_mac_1()
+{
+ char name[] = "test_compat_mac-1.tar.Z";
+ struct archive_entry *ae;
+ struct archive *a;
+ const void *attr;
+ size_t attrSize;
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ extract_reference_file(name);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(TESTPATH, archive_entry_pathname(ae));
+ assertEqualInt(1275688109, archive_entry_mtime(ae));
+ assertEqualInt(95594, archive_entry_uid(ae));
+ assertEqualString("kientzle", archive_entry_uname(ae));
+ assertEqualInt(5000, archive_entry_gid(ae));
+ assertEqualString("", archive_entry_gname(ae));
+ assertEqualInt(040755, archive_entry_mode(ae));
+
+ attr = archive_entry_mac_metadata(ae, &attrSize);
+ assert(attr == NULL);
+ assertEqualInt(0, attrSize);
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(TESTPATH "dir/", archive_entry_pathname(ae));
+ assertEqualInt(1275687611, archive_entry_mtime(ae));
+ assertEqualInt(95594, archive_entry_uid(ae));
+ assertEqualString("kientzle", archive_entry_uname(ae));
+ assertEqualInt(5000, archive_entry_gid(ae));
+ assertEqualString("", archive_entry_gname(ae));
+ assertEqualInt(040755, archive_entry_mode(ae));
+
+ attr = archive_entry_mac_metadata(ae, &attrSize);
+ assert(attr != NULL);
+ assertEqualInt(225, attrSize);
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(TESTPATH "file", archive_entry_pathname(ae));
+ assertEqualInt(1275687588, archive_entry_mtime(ae));
+ assertEqualInt(95594, archive_entry_uid(ae));
+ assertEqualString("kientzle", archive_entry_uname(ae));
+ assertEqualInt(5000, archive_entry_gid(ae));
+ assertEqualString("", archive_entry_gname(ae));
+ assertEqualInt(0100644, archive_entry_mode(ae));
+
+ attr = archive_entry_mac_metadata(ae, &attrSize);
+ assert(attr != NULL);
+ assertEqualInt(225, attrSize);
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("dir/", archive_entry_pathname(ae));
+ assertEqualInt(1275688064, archive_entry_mtime(ae));
+ assertEqualInt(95594, archive_entry_uid(ae));
+ assertEqualString("kientzle", archive_entry_uname(ae));
+ assertEqualInt(5000, archive_entry_gid(ae));
+ assertEqualString("", archive_entry_gname(ae));
+ assertEqualInt(040755, archive_entry_mode(ae));
+
+ attr = archive_entry_mac_metadata(ae, &attrSize);
+ assert(attr != NULL);
+ assertEqualInt(225, attrSize);
+ assertEqualMem("\x00\x05\x16\x07\x00\x02\x00\x00Mac OS X", attr, 16);
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("file", archive_entry_pathname(ae));
+ assertEqualInt(1275625860, archive_entry_mtime(ae));
+ assertEqualInt(95594, archive_entry_uid(ae));
+ assertEqualString("kientzle", archive_entry_uname(ae));
+ assertEqualInt(5000, archive_entry_gid(ae));
+ assertEqualString("", archive_entry_gname(ae));
+ assertEqualInt(0100644, archive_entry_mode(ae));
+
+ attr = archive_entry_mac_metadata(ae, &attrSize);
+ assert(attr != NULL);
+ assertEqualInt(225, attrSize);
+ assertEqualMem("\x00\x05\x16\x07\x00\x02\x00\x00Mac OS X", attr, 16);
+
+ /* Verify the end-of-archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify that the format detection worked. */
+ assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_COMPRESS);
+ assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_GNUTAR);
+
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+/*
+ * Apple shipped a customized version of bsdtar starting with MacOS 10.6.
+ */
+void test_compat_mac_2()
+{
+ char name[] = "test_compat_mac-2.tar.Z";
+ struct archive_entry *ae;
+ struct archive *a;
+ const void *attr;
+ size_t attrSize;
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ extract_reference_file(name);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("./", archive_entry_pathname(ae));
+ assertEqualInt(1303628303, archive_entry_mtime(ae));
+ assertEqualInt(501, archive_entry_uid(ae));
+ assertEqualString("tim", archive_entry_uname(ae));
+ assertEqualInt(20, archive_entry_gid(ae));
+ assertEqualString("staff", archive_entry_gname(ae));
+ assertEqualInt(040755, archive_entry_mode(ae));
+
+ attr = archive_entry_mac_metadata(ae, &attrSize);
+ assert(attr == NULL);
+ assertEqualInt(0, attrSize);
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("./mydir/", archive_entry_pathname(ae));
+ assertEqualInt(1303628303, archive_entry_mtime(ae));
+ assertEqualInt(501, archive_entry_uid(ae));
+ assertEqualString("tim", archive_entry_uname(ae));
+ assertEqualInt(20, archive_entry_gid(ae));
+ assertEqualString("staff", archive_entry_gname(ae));
+ assertEqualInt(040755, archive_entry_mode(ae));
+
+ attr = archive_entry_mac_metadata(ae, &attrSize);
+ assert(attr != NULL);
+ assertEqualInt(267, attrSize);
+ assertEqualMem("\x00\x05\x16\x07\x00\x02\x00\x00Mac OS X", attr, 16);
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("./myfile", archive_entry_pathname(ae));
+ assertEqualInt(1303628303, archive_entry_mtime(ae));
+ assertEqualInt(501, archive_entry_uid(ae));
+ assertEqualString("tim", archive_entry_uname(ae));
+ assertEqualInt(20, archive_entry_gid(ae));
+ assertEqualString("staff", archive_entry_gname(ae));
+ assertEqualInt(0100644, archive_entry_mode(ae));
+
+ attr = archive_entry_mac_metadata(ae, &attrSize);
+ assert(attr != NULL);
+ assertEqualInt(267, attrSize);
+ assertEqualMem("\x00\x05\x16\x07\x00\x02\x00\x00Mac OS X", attr, 16);
+
+ /* Verify the end-of-archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify that the format detection worked. */
+ assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_COMPRESS);
+ assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR);
+
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+DEFINE_TEST(test_compat_mac)
+{
+ test_compat_mac_1();
+ test_compat_mac_2();
+}
+
diff --git a/libarchive/test/test_compat_pax_libarchive_2x.c b/libarchive/test/test_compat_pax_libarchive_2x.c
new file mode 100644
index 000000000000..6ea25e4d2501
--- /dev/null
+++ b/libarchive/test/test_compat_pax_libarchive_2x.c
@@ -0,0 +1,146 @@
+/*-
+ * Copyright (c) 2011 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD");
+
+#include <locale.h>
+
+/*
+ * Test "tar:compat-2x" option that enables the string conversion of
+ * libarchive 2.x, which made incorrect UTF-8 form filenames for the
+ * pax format on some platform the wchar_t of which was not Unicode form.
+ * The option is unneeded if people have been using UTF-8 locale during
+ * making tar files(in pax format).
+ *
+ * NOTE: The sample tar file was made with bsdtar 2.x in LANG=KOI8-R on
+ * FreeBSD.
+ */
+
+DEFINE_TEST(test_compat_pax_libarchive_2x)
+{
+#if (defined(_WIN32) && !defined(__CYGWIN__)) \
+ || defined(__STDC_ISO_10646__) || defined(__APPLE__)
+ skipping("This test only for the platform the WCS of which is "
+ "not Unicode.");
+#else
+ struct archive *a;
+ struct archive_entry *ae;
+ char c;
+ wchar_t wc;
+ const char *refname = "test_compat_pax_libarchive_2x.tar.Z";
+
+ /*
+ * Read incorrect format UTF-8 filename in ru_RU.KOI8-R with
+ * "tar:compat-2x" option. We should correctly
+ * read two filenames.
+ */
+ if (NULL == setlocale(LC_ALL, "ru_RU.KOI8-R")) {
+ skipping("ru_RU.KOI8-R locale not available on this system.");
+ return;
+ }
+
+ /*
+ * Test if wchar_t format is the same as FreeBSD wchar_t.
+ */
+ assert(-1 != wctomb(NULL, L'\0'));
+ wc = (wchar_t)0xd0;
+ c = 0;
+ if (wctomb(&c, wc) != 1 || (unsigned char)c != 0xd0) {
+ skipping("wchar_t format is different on this platform.");
+ return;
+ }
+
+ extract_reference_file(refname);
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_set_options(a, "tar:compat-2x"));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular first file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xd0\xd2\xc9\xd7\xc5\xd4",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular second file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xf0\xf2\xe9\xf7\xe5\xf4",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
+ assertEqualIntA(a, ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE,
+ archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+ /*
+ * Without "tar:compat-2x" option.
+ * Neither first file name nor second file name can be translated
+ * to KOI8-R.
+ */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* We cannot correctly read the filename. */
+ assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae));
+ assert(strcmp("\xd0\xd2\xc9\xd7\xc5\xd4",
+ archive_entry_pathname(ae)) != 0);
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* We cannot correctly read the filename. */
+ assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae));
+ assert(strcmp("\xf0\xf2\xe9\xf7\xe5\xf4",
+ archive_entry_pathname(ae)) != 0);
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
+ assertEqualIntA(a, ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE,
+ archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+#endif
+}
diff --git a/libarchive/test/test_compat_pax_libarchive_2x.tar.Z.uu b/libarchive/test/test_compat_pax_libarchive_2x.tar.Z.uu
new file mode 100644
index 000000000000..f44054118c17
--- /dev/null
+++ b/libarchive/test/test_compat_pax_libarchive_2x.tar.Z.uu
@@ -0,0 +1,15 @@
+begin 644 test_compat_pax_libarchive_2x.tar.Z
+M'YV04,+@05(F#)DR<EY`DY;L6C%J`")*G$BQHL6+&#-JW%@1AL<;-6J``.`Q
+M!L@8(TN>3.FQ94D;-D#$B%&#QHT9,CS.B`DCADT;-P"`P,.QJ-&C2)-:K#.'
+M3A@Y)&&,J5-&:<:I5:U>=.F1I<N16L.*'4NV;%D9*.&$H8.FQS!(PR0-2S3L
+MTK!"PR@IR`EB#)TT;<KTB#$#!EJ0.&+@V`L#Q%K`@@D;QG$C!PX9.128!#%E
+M")(D3+*X.&BG1XX:>V5P]@Q:=!HW;P87IE'C!@W-.%9_#NW"#9O7:P8K,$N\
+MN/'CR),K7\Z\N?.)"QL^?$[=:$N0(J.:K(%2^\JH7%O&G%GS9DX8.T'T+`PC
+MJ/KJ\)$R=0K5(];B]XF']]H2;/S_`"H'CSSIW%,./0$FJ.""##;HX(,01@A`
+M0`,5=%!"`Q9XH(3Z?1022]MUIQ)W_+D4`TPRT6033CKQ1),,0`E%%(?PS?=4
+M5/F9E6-9^X'7'XU`-H@6"&JQY18LP\@R3"K#W#),*</0PEA??P4FFV';);88
+M7X]9*9D,E%F&F68WZ-;::&64=EIJ9O+V6FR2T082;FV*YAMPP@6IYYY\]NFG
+M4AD:B."?9EWWH7<D(BIB>.*E6!Z+Z+DX0V'NP4!H<C;6)Q55^'':X5<^=G7I
+>J,<%NB&IJ*:JZJJLMNKJJ[#&*NNLM-9JZZVXYDH<
+`
+end
diff --git a/libarchive/test/test_compat_solaris_pax_sparse.c b/libarchive/test/test_compat_solaris_pax_sparse.c
new file mode 100644
index 000000000000..0ab333bb180b
--- /dev/null
+++ b/libarchive/test/test_compat_solaris_pax_sparse.c
@@ -0,0 +1,188 @@
+/*-
+ * Copyright (c) 2011 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+/*
+ * Verify our ability to read sample files created by Solaris pax for
+ * a sparse file.
+ */
+static void
+test_compat_solaris_pax_sparse_1(void)
+{
+ char name[] = "test_compat_solaris_pax_sparse_1.pax.Z";
+ struct archive_entry *ae;
+ struct archive *a;
+ int64_t offset, length;
+ const void *buff;
+ size_t bytes_read;
+ char data[1024*8];
+ int r;
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ extract_reference_file(name);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240));
+
+ /* Read first entry. */
+ assertEqualIntA(a, ARCHIVE_OK, r = archive_read_next_header(a, &ae));
+ if (r != ARCHIVE_OK) {
+ archive_read_free(a);
+ return;
+ }
+ assertEqualString("hole", archive_entry_pathname(ae));
+ assertEqualInt(1310411683, archive_entry_mtime(ae));
+ assertEqualInt(101, archive_entry_uid(ae));
+ assertEqualString("cue", archive_entry_uname(ae));
+ assertEqualInt(10, archive_entry_gid(ae));
+ assertEqualString("staff", archive_entry_gname(ae));
+ assertEqualInt(0100644, archive_entry_mode(ae));
+
+ /* Verify the sparse information. */
+ failure("This sparse file should have tree data blocks");
+ assertEqualInt(3, archive_entry_sparse_reset(ae));
+ assertEqualInt(ARCHIVE_OK,
+ archive_entry_sparse_next(ae, &offset, &length));
+ assertEqualInt(0, offset);
+ assertEqualInt(131072, length);
+ assertEqualInt(ARCHIVE_OK,
+ archive_entry_sparse_next(ae, &offset, &length));
+ assertEqualInt(393216, offset);
+ assertEqualInt(131072, length);
+ assertEqualInt(ARCHIVE_OK,
+ archive_entry_sparse_next(ae, &offset, &length));
+ assertEqualInt(786432, offset);
+ assertEqualInt(32775, length);
+ while (ARCHIVE_OK ==
+ archive_read_data_block(a, &buff, &bytes_read, &offset)) {
+ failure("The data blocks should not include the hole");
+ assert((offset >= 0 && offset + bytes_read <= 131072) ||
+ (offset >= 393216 && offset + bytes_read <= 393216+131072) ||
+ (offset >= 786432 && offset + bytes_read <= 786432+32775));
+ if (offset == 0 && bytes_read >= 1024*8) {
+ memset(data, 'a', sizeof(data));
+ failure("First data block should be 8K bytes of 'a'");
+ assertEqualMem(buff, data, sizeof(data));
+ } else if (offset + bytes_read == 819207 && bytes_read >= 7) {
+ const char *last = buff;
+ last += bytes_read - 7;
+ memset(data, 'c', 7);
+ failure("Last seven bytes should be all 'c'");
+ assertEqualMem(last, data, 7);
+ }
+ }
+
+ /* Verify the end-of-archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify that the format detection worked. */
+ assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_COMPRESS);
+ assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE);
+
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+/*
+ * Verify our ability to read sample files created by Solaris pax for
+ * a sparse file which begin with hole.
+ */
+static void
+test_compat_solaris_pax_sparse_2(void)
+{
+ char name[] = "test_compat_solaris_pax_sparse_2.pax.Z";
+ struct archive_entry *ae;
+ struct archive *a;
+ int64_t offset, length;
+ const void *buff;
+ size_t bytes_read;
+ int r;
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ extract_reference_file(name);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240));
+
+ /* Read first entry. */
+ assertEqualIntA(a, ARCHIVE_OK, r = archive_read_next_header(a, &ae));
+ if (r != ARCHIVE_OK) {
+ archive_read_free(a);
+ return;
+ }
+ assertEqualString("hole", archive_entry_pathname(ae));
+ assertEqualInt(1310416789, archive_entry_mtime(ae));
+ assertEqualInt(101, archive_entry_uid(ae));
+ assertEqualString("cue", archive_entry_uname(ae));
+ assertEqualInt(10, archive_entry_gid(ae));
+ assertEqualString("staff", archive_entry_gname(ae));
+ assertEqualInt(0100644, archive_entry_mode(ae));
+
+ /* Verify the sparse information. */
+ failure("This sparse file should have two data blocks");
+ assertEqualInt(2, archive_entry_sparse_reset(ae));
+ assertEqualInt(ARCHIVE_OK,
+ archive_entry_sparse_next(ae, &offset, &length));
+ assertEqualInt(393216, offset);
+ assertEqualInt(131072, length);
+ assertEqualInt(ARCHIVE_OK,
+ archive_entry_sparse_next(ae, &offset, &length));
+ assertEqualInt(786432, offset);
+ assertEqualInt(32799, length);
+ while (ARCHIVE_OK ==
+ archive_read_data_block(a, &buff, &bytes_read, &offset)) {
+ failure("The data blocks should not include the hole");
+ assert((offset >= 393216 && offset + bytes_read <= 393216+131072) ||
+ (offset >= 786432 && offset + bytes_read <= 786432+32799));
+ if (offset + bytes_read == 819231 && bytes_read >= 31) {
+ char data[32];
+ const char *last = buff;
+ last += bytes_read - 31;
+ memset(data, 'c', 31);
+ failure("Last 31 bytes should be all 'c'");
+ assertEqualMem(last, data, 31);
+ }
+ }
+
+ /* Verify the end-of-archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify that the format detection worked. */
+ assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_COMPRESS);
+ assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE);
+
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+
+DEFINE_TEST(test_compat_solaris_pax_sparse)
+{
+ test_compat_solaris_pax_sparse_1();
+ test_compat_solaris_pax_sparse_2();
+}
+
+
diff --git a/libarchive/test/test_compat_solaris_pax_sparse_1.pax.Z.uu b/libarchive/test/test_compat_solaris_pax_sparse_1.pax.Z.uu
new file mode 100644
index 000000000000..8ab27deb654c
--- /dev/null
+++ b/libarchive/test/test_compat_solaris_pax_sparse_1.pax.Z.uu
@@ -0,0 +1,53 @@
+begin 644 test_compat_solaris_pax_sparse_1.pax.Z
+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
+E_O.@#[WH1T_ZTIO^]*A/O>I7S_K6N_[UL(\]Z<=`^]J/0?9$`P``
+`
+end
diff --git a/libarchive/test/test_compat_solaris_pax_sparse_2.pax.Z.uu b/libarchive/test/test_compat_solaris_pax_sparse_2.pax.Z.uu
new file mode 100644
index 000000000000..5df385f773c7
--- /dev/null
+++ b/libarchive/test/test_compat_solaris_pax_sparse_2.pax.Z.uu
@@ -0,0 +1,53 @@
+begin 644 test_compat_solaris_pax_sparse_2.pax.Z
+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
+F_O.@#[WH1T_ZTIO^]*A/O>I7S_K6NY[I8XB][&=/^]K;7O:O1Q4`
+`
+end
diff --git a/libarchive/test/test_compat_solaris_tar_acl.c b/libarchive/test/test_compat_solaris_tar_acl.c
index ca1506a355ed..a0cf9a8ad8ff 100644
--- a/libarchive/test/test_compat_solaris_tar_acl.c
+++ b/libarchive/test/test_compat_solaris_tar_acl.c
@@ -45,7 +45,7 @@ DEFINE_TEST(test_compat_solaris_tar_acl)
extract_reference_file(reference1);
assert(NULL != (a = archive_read_new()));
assertA(0 == archive_read_support_format_all(a));
- assertA(0 == archive_read_support_compression_all(a));
+ assertA(0 == archive_read_support_filter_all(a));
assertA(0 == archive_read_open_filename(a, reference1, 512));
/* Archive has 1 entry with some ACLs set on it. */
@@ -124,5 +124,5 @@ DEFINE_TEST(test_compat_solaris_tar_acl)
/* Close the archive. */
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_compat_tar_hardlink.c b/libarchive/test/test_compat_tar_hardlink.c
index 30785d1fb0c1..21466d7c508d 100644
--- a/libarchive/test/test_compat_tar_hardlink.c
+++ b/libarchive/test/test_compat_tar_hardlink.c
@@ -51,7 +51,7 @@ test_compat_tar_hardlink_1(void)
struct archive *a;
assert((a = archive_read_new()) != NULL);
- assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
extract_reference_file(name);
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240));
@@ -93,11 +93,7 @@ test_compat_tar_hardlink_1(void)
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR);
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
-#endif
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
DEFINE_TEST(test_compat_tar_hardlink)
diff --git a/libarchive/test/test_compat_xz.c b/libarchive/test/test_compat_xz.c
index c3b790ffbd2b..551edcc5733b 100644
--- a/libarchive/test/test_compat_xz.c
+++ b/libarchive/test/test_compat_xz.c
@@ -46,11 +46,11 @@ compat_xz(const char *name)
int i, r;
assert((a = archive_read_new()) != NULL);
- assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a));
- r = archive_read_support_compression_xz(a);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ r = archive_read_support_filter_xz(a);
if (r == ARCHIVE_WARN) {
skipping("xz reading not fully supported on this platform");
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
return;
}
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
@@ -74,7 +74,7 @@ compat_xz(const char *name)
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR);
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_compat_zip.c b/libarchive/test/test_compat_zip.c
index c6916cbbda6c..5b828bf9f2e5 100644
--- a/libarchive/test/test_compat_zip.c
+++ b/libarchive/test/test_compat_zip.c
@@ -25,6 +25,12 @@
#include "test.h"
__FBSDID("$FreeBSD: head/lib/libarchive/test/test_compat_zip.c 196962 2009-09-08 05:02:41Z kientzle $");
+#ifdef HAVE_LIBZ
+static const int libz_enabled = 1;
+#else
+static const int libz_enabled = 0;
+#endif
+
/* Copy this function for each test file and adjust it accordingly. */
static void
test_compat_zip_1(void)
@@ -35,7 +41,7 @@ test_compat_zip_1(void)
int r;
assert((a = archive_read_new()) != NULL);
- assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
extract_reference_file(name);
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240));
@@ -46,13 +52,10 @@ test_compat_zip_1(void)
/* Read second entry. */
r = archive_read_next_header(a, &ae);
- if (r != ARCHIVE_OK) {
- if (strcmp(archive_error_string(a),
- "libarchive compiled without deflate support (no libz)") == 0) {
- skipping("Skipping ZIP compression check: %s",
- archive_error_string(a));
- goto finish;
- }
+ if (r == ARCHIVE_FATAL && !libz_enabled) {
+ skipping("Skipping ZIP compression check: %s",
+ archive_error_string(a));
+ goto finish;
}
assertEqualIntA(a, ARCHIVE_OK, r);
assertEqualString("tmp.class", archive_entry_pathname(ae));
@@ -62,13 +65,9 @@ test_compat_zip_1(void)
assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_NONE);
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ZIP);
- assertEqualInt(ARCHIVE_OK, archive_read_close(a));
finish:
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
-#endif
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
/*
@@ -85,7 +84,7 @@ test_compat_zip_2(void)
struct archive *a;
assert((a = archive_read_new()) != NULL);
- assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
extract_reference_file(name);
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240));
@@ -103,11 +102,345 @@ test_compat_zip_2(void)
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
+/*
+ * Issue 185: Test a regression that got in between 2.6 and 2.7 that
+ * broke extraction of Zip entries with length-at-end.
+ */
+static void
+test_compat_zip_3(void)
+{
+ const char *refname = "test_compat_zip_3.zip";
+ struct archive_entry *ae;
+ struct archive *a;
+
+ extract_reference_file(refname);
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240));
+
+ /* First entry. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("soapui-4.0.0/", archive_entry_pathname(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assert(archive_entry_size_is_set(ae));
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
+
+ /* Second entry. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("soapui-4.0.0/soapui-settings.xml", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualInt(1030, archive_entry_size(ae));
+ assert(archive_entry_size_is_set(ae));
+
+ /* Extract under a different name. */
+ archive_entry_set_pathname(ae, "test_3.txt");
+ if(libz_enabled) {
+ char *p;
+ size_t s;
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_extract(a, ae, 0));
+ /* Verify the first 12 bytes actually got written to disk correctly. */
+ p = slurpfile(&s, "test_3.txt");
+ assertEqualInt(s, 1030);
+ assertEqualMem(p, "<?xml versio", 12);
+ free(p);
+ } else {
+ skipping("Skipping ZIP compression check, no libz support");
+ }
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
+}
+
+/**
+ * A file with leading garbage (similar to an SFX file).
+ */
+static void
+test_compat_zip_4(void)
+{
+ const char *refname = "test_compat_zip_4.zip";
+ struct archive_entry *ae;
+ struct archive *a;
+ void *p;
+ size_t s;
+
+ extract_reference_file(refname);
+ p = slurpfile(&s, refname);
+
+ /* SFX files require seek support. */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, p, s, 18));
+
+ /* First entry. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("foo", archive_entry_pathname(ae));
+ assertEqualInt(4, archive_entry_size(ae));
+ assert(archive_entry_size_is_set(ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualInt(0412, archive_entry_perm(ae));
+
+ /* Second entry. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("bar", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualInt(4, archive_entry_size(ae));
+ assert(archive_entry_size_is_set(ae));
+ assertEqualInt(0567, archive_entry_perm(ae));
+
+ /* Third entry. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("baz", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualInt(4, archive_entry_size(ae));
+ assert(archive_entry_size_is_set(ae));
+ assertEqualInt(0644, archive_entry_perm(ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
+
+ /* Try reading without seek support and watch it fail. */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_FATAL, read_open_memory(a, p, s, 3));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
+ free(p);
+}
+/**
+ * Issue 152: A file generated by a tool that doesn't really
+ * believe in populating local file headers at all. This
+ * is only readable with the seeking reader.
+ */
+static void
+test_compat_zip_5(void)
+{
+ const char *refname = "test_compat_zip_5.zip";
+ struct archive_entry *ae;
+ struct archive *a;
+ void *p;
+ size_t s;
+
+ extract_reference_file(refname);
+ p = slurpfile(&s, refname);
+
+ /* Verify with seek support.
+ * Everything works correctly here. */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, p, s, 18));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("Metadata/Job_PT.xml", archive_entry_pathname(ae));
+ assertEqualInt(3559, archive_entry_size(ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualInt(0777, archive_entry_perm(ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("Metadata/MXDC_Empty_PT.xml", archive_entry_pathname(ae));
+ assertEqualInt(456, archive_entry_size(ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualInt(0777, archive_entry_perm(ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("Documents/1/Metadata/Page1_Thumbnail.JPG", archive_entry_pathname(ae));
+ assertEqualInt(1495, archive_entry_size(ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualInt(0777, archive_entry_perm(ae));
+ /* TODO: Read some of the file data and verify it.
+ The code to read uncompressed Zip entries with "file at end" semantics
+ is tricky and should be verified more carefully. */
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("Documents/1/Pages/_rels/1.fpage.rels", archive_entry_pathname(ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("Documents/1/Pages/1.fpage", archive_entry_pathname(ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("Documents/1/Resources/Fonts/3DFDBC8B-4514-41F1-A808-DEA1C79BAC2B.odttf", archive_entry_pathname(ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("Documents/1/_rels/FixedDocument.fdoc.rels", archive_entry_pathname(ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("Documents/1/FixedDocument.fdoc", archive_entry_pathname(ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("_rels/FixedDocumentSequence.fdseq.rels", archive_entry_pathname(ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("FixedDocumentSequence.fdseq", archive_entry_pathname(ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("_rels/.rels", archive_entry_pathname(ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("[Content_Types].xml", archive_entry_pathname(ae));
+
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
+
+ /* Try reading without seek support. */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 3));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("Metadata/Job_PT.xml", archive_entry_pathname(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assert(!archive_entry_size_is_set(ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualInt(0777, archive_entry_perm(ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("Metadata/MXDC_Empty_PT.xml", archive_entry_pathname(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assert(!archive_entry_size_is_set(ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualInt(0777, archive_entry_perm(ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("Documents/1/Metadata/Page1_Thumbnail.JPG", archive_entry_pathname(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assert(!archive_entry_size_is_set(ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualInt(0777, archive_entry_perm(ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("Documents/1/Pages/_rels/1.fpage.rels", archive_entry_pathname(ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("Documents/1/Pages/1.fpage", archive_entry_pathname(ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("Documents/1/Resources/Fonts/3DFDBC8B-4514-41F1-A808-DEA1C79BAC2B.odttf", archive_entry_pathname(ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("Documents/1/_rels/FixedDocument.fdoc.rels", archive_entry_pathname(ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("Documents/1/FixedDocument.fdoc", archive_entry_pathname(ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("_rels/FixedDocumentSequence.fdseq.rels", archive_entry_pathname(ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("FixedDocumentSequence.fdseq", archive_entry_pathname(ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("_rels/.rels", archive_entry_pathname(ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("[Content_Types].xml", archive_entry_pathname(ae));
+
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
+ free(p);
+}
+
+/*
+ * Issue 225: Errors extracting MSDOS Zip archives with directories.
+ */
+static void
+compat_zip_6_verify(struct archive *a)
+{
+ struct archive_entry *ae;
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("New Folder/New Folder/", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
+ assertEqualInt(1327314468, archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("New Folder/New Folder/New Text Document.txt", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualInt(1327314476, archive_entry_mtime(ae));
+ assertEqualInt(11, archive_entry_size(ae));
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+}
+
+static void
+test_compat_zip_6(void)
+{
+ const char *refname = "test_compat_zip_6.zip";
+ struct archive *a;
+ void *p;
+ size_t s;
+
+ extract_reference_file(refname);
+ p = slurpfile(&s, refname);
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, p, s, 7));
+ compat_zip_6_verify(a);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 7));
+ compat_zip_6_verify(a);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
+ free(p);
+}
+
+/*
+ * Issue 226: Try to reproduce hang when reading archives where the
+ * length-at-end marker ends exactly on a block boundary.
+ */
+static void
+test_compat_zip_7(void)
+{
+ const char *refname = "test_compat_zip_7.xps";
+ struct archive *a;
+ struct archive_entry *ae;
+ void *p;
+ size_t s;
+ int i;
+
+ extract_reference_file(refname);
+ p = slurpfile(&s, refname);
+
+ for (i = 1; i < 1000; ++i) {
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
+ assertEqualIntA(a, ARCHIVE_OK, read_open_memory2(a, p, s, i));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
+ }
+ free(p);
+}
DEFINE_TEST(test_compat_zip)
{
test_compat_zip_1();
test_compat_zip_2();
+ test_compat_zip_3();
+ test_compat_zip_4();
+ test_compat_zip_5();
+ test_compat_zip_6();
+ test_compat_zip_7();
}
diff --git a/libarchive/test/test_compat_zip_2.zip.uu b/libarchive/test/test_compat_zip_2.zip.uu
index c33e9d99e2e2..f8ada311678e 100644
--- a/libarchive/test/test_compat_zip_2.zip.uu
+++ b/libarchive/test/test_compat_zip_2.zip.uu
@@ -1,5 +1,3 @@
-$FreeBSD$
-
begin 644 test_compat_zip_2.zip
M4$L#!`H``````'V59CT````````````````%````9FEL93$M2E5.2RU02P,$
M"@``````@95F/<>D!,D&````!@````4```!F:6QE,F9I;&4R"E!+`0(>`PH`
diff --git a/libarchive/test/test_compat_zip_3.zip.uu b/libarchive/test/test_compat_zip_3.zip.uu
new file mode 100644
index 000000000000..8e3613985f2f
--- /dev/null
+++ b/libarchive/test/test_compat_zip_3.zip.uu
@@ -0,0 +1,18 @@
+begin 644 test_compat_zip_3.zip
+M4$L#!`H``````-=0SCX````````````````-````<V]A<'5I+30N,"XP+U!+
+M`P04``@`"`#(4,X^C.NJ/7X!```&!```(````'-O87!U:2TT+C`N,"]S;V%P
+M=6DM<V5T=&EN9W,N>&ULI9/12\,P$,;?!?^'D0??DE1%D+EU0U`<*`RWH6\E
+MIK<MVB8UN:[;?^]UG6.H,*=0:.G=]\O7[ZZ=WC+/6@OPP3C;9:<B8BVPVJ7&
+MSKIL,K[EEZP7'Q]UM+/MX%11&AX`D<JA15(;VKH6SA&+MI2P,)7R(+3+9=,M
+MJ3PU,Q8WA$;:,FF7/84T&VU0?:WT''A%KP*+T9?0D3O]>\2%IZ<5+[RQR#V$
+MPMD`G-S]"G5'UK<H8W56II!X>"\A8&)L@B:'!-4;V/_@&E-_X$T&6YHJT25!
+M+6H,@E\H^L#HD*!@N;:3<EP50$&?9'A5"\"B7QTVSD#SRE5_TUA5E:C.A?,S
+M>19%I_+YX7ZT;JA/D-LCXD/,6I731AB<\Q=CZWT\//Y<+1-JL*"1UCLD!?AD
+M[@*R^"+:%]PW$#I4V2Z.Q?2M^S`4G?B,L8E0C.@V&?0KY]]"H32P6`A)UY@6
+M;GA]P[<%01/9@W\$3<D.O7LE4YN)DHI/O9KE5)%?(Y<__,CQ!U!+!PB,ZZH]
+M?@$```8$``!02P$"%`,*``````#74,X^````````````````#0``````````
+M`!``[4$`````<V]A<'5I+30N,"XP+U!+`0(4`Q0`"``(`,A0SCZ,ZZH]?@$`
+M``8$```@``````````````"D@2L```!S;V%P=6DM-"XP+C`O<V]A<'5I+7-E
+@='1I;F=S+GAM;%!+!08``````@`"`(D```#W`0``````
+`
+end
diff --git a/libarchive/test/test_compat_zip_4.zip.uu b/libarchive/test/test_compat_zip_4.zip.uu
new file mode 100644
index 000000000000..3c80cbecf741
--- /dev/null
+++ b/libarchive/test/test_compat_zip_4.zip.uu
@@ -0,0 +1,25 @@
+begin 644 test_compat_zip_4.zip
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````%!+`P0*``````"#KG(_J&4R?@0````$`````P`<
+M`&9O;U54"0`#!43'3A5$QTYU>`L``03U`0``!!0```!F;V\*4$L#!`H`````
+M`(2N<C_ILZ($!`````0````#`!P`8F%R550)``,'1,=.%43'3G5X"P`!!/4!
+M```$%````&)A<@I02P,$"@``````AJYR/^$Y>\P$````!`````,`'`!B87I5
+M5`D``PM$QTX+1,=.=7@+``$$]0$```04````8F%Z"E!+`0(>`PH``````(.N
+M<C^H93)^!`````0````#`!@```````$``0`*@?\!``!F;V]55`4``P5$QTYU
+M>`L``03U`0``!!0```!02P$"'@,*``````"$KG(_Z;.B!`0````$`````P`8
+M```````!``$`=X%``@``8F%R550%``,'1,=.=7@+``$$]0$```04````4$L!
+M`AX#"@``````AJYR/^$Y>\P$````!`````,`&````````0```*2!@0(``&)A
+M>E54!0`#"T3'3G5X"P`!!/4!```$%````%!+!08``````P`#`-L```#"`@``
+"````
+`
+end
diff --git a/libarchive/test/test_compat_zip_5.zip.uu b/libarchive/test/test_compat_zip_5.zip.uu
new file mode 100644
index 000000000000..9dce4521dd3e
--- /dev/null
+++ b/libarchive/test/test_compat_zip_5.zip.uu
@@ -0,0 +1,242 @@
+begin 644 test_compat_zip_5.zip
+M4$L#!!0`"``(`-H0?CX````````````````3````365T861A=&$O2F]B7U!4
+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
+M%$*1H;'!"2,S4O`58G+1"A8D-.$E\1<8&1HF)R@I*C4V-S@Y.D-$149'2$E*
+M4U155E=865IC9&5F9VAI:G-T=79W>'EZ@H.$A8:'B(F*DI.4E9:7F)F:HJ.D
+MI::GJ*FJLK.TM;:WN+FZPL/$Q<;'R,G*TM/4U=;7V-G:XN/DY>;GZ.GJ\O/T
+M]?;W^/GZ_]H`#`,!``(1`Q$`/P#TZBBB@`HHHH`****`"BBB@`HHHH`****`
+M"BBB@`HHHH`****`"BBB@`HHHH`****`"BBB@`HJ+RG\O;]HESOW;\+G&[.W
+MIC&/EZ9QWSS3XD9(D1I&D95`+MC+'U.`!GZ`"@!U%%%`!1110`4444`%4QJE
+MF=4;33(RW2J&VM&RA@02,,1M)PK<`D_*W]TXN44`%%%%`!1110`4444`%%%%
+M`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`
+M%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4
+M444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!11
+M10`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%
+M`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`
+M%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4
+M444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!11
+M10`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%
+M`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`
+M%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4
+M444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!11
+M10`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%
+M`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`
+M%%%%`!1110`4444`%%%%`!1110`4453FTNSF9FDC;+W"738D90TB!0I(!Y`V
+M+QTR`<9H`N4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`44
+M44`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110!__V5!+!PC?FNW>
+MUP4``-<%``!02P,$%``(``@`VA!^/@```````````````"0```!$;V-U;65N
+M=',O,2]086=E<R]?<F5L<R\Q+F9P86=E+G)E;'-ED$M.Q#`,AO=(W*'*/G4S
+M=*"@*:,^J,2VF@M$J?L0DP=QBH:SL>!(7($,8L%CZ=^_?W_VQ]O[;G_2Q^0%
+M/2W6E$RD&4O0*#LL9BK9&D9>L/W]Y<6NQZ,,T4/SXBB)0X9*-H?@[@!(S:@E
+MI=:AB9W1>BU#+/T$3JHG.2%LLNP:_,\,]C<U.4@_82@9M%:M&DT@$-`CV=4K
+M).CL6;EJN[9NBIKG6Y'S7'2"5T56\/:A$LW-;5TUFSJU0P@C2QZ'DO7QH,.K
+MPW^P>E'>DAU#JJR&DZ,SXQ:^,)_7Q>/`_?=N!F=6^/6"J'P"4$L'"%!53P;H
+M````/P$``%!+`P04``@`"`#:$'X^````````````````&0```$1O8W5M96YT
+M<R\Q+U!A9V5S+S$N9G!A9V75DTM.PS`0AM=P"LMLJ5]Q'J4-4A\$V`"B0L`R
+M2MS$4F)7L2L5+L`18%E8L^5*(&Z!DXH*Q`F8A34>:SS^/_T>)G(E\HNT$.!:
+MYK:,8=CW4!A`<")D4=H84LH8\EUA55?*Q+"T=G&`L<E*4:<&U3)KM-%SBS)=
+MX]7"8$:(C\FFX:!*51'#I<KAX>[.\+BZ6Y0&)+*J8K@WGY,N($BTLE>-C"&>
+MZFQ9"V4-IOA2&+UL,F%P>VZP-TVFXTDT[G&?\AZG">V-(A+UID<C.@G[X]&$
+MC9'.K9UO;KP4*A>-5,51/9/WPDEAR(WS(9C9NTK,9+VL4BMUJ^I,*P'!>2,+
+MJ6YBZ(51IWE3N'6MA*,(@E.52_<@1XGTV3XE=!`&W',)&SC9+;8K)3.=BYEM
+M!\?P_7']OG[X?'F"`/\K`J&/@N@G`+HALB401/L^'031X#O9;O]`2+OX;P0\
+MA\!GOSS`..(_74"9SWEG`Z]5STB[>JT5./U#X>/U%5#P^?S6@1CB[<\[W/T"
+M4$L'"%=?-U>$`0``A@,``%!+`P04``@`"`#:$'X^````````````````1@``
+M`$1O8W5M96YT<R\Q+U)E<V]U<F-E<R]&;VYT<R\S1$9$0D,X0BTT-3$T+30Q
+M1C$M03@P."U$14$Q0S<Y0D%#,D(N;V1T=&;MW7UP'.5]!_#?L[MWM[NW=[=W
+MNCN=9<M:Z80E6[;U9DFV:Z*3+-LR!LEO=]@0%0M;E@36"_)+`0,ZC&G4]`7!
+M0,8S;2=VQF2@D*E+(1C:@@GN!!)"TA1H4IM434@,M`:;A%@&6=??KLY&O`3"
+MD%29X?OY>F^?M]U]]NVLT1]VV3?^^ML'OJ?==WI9>.?SXX]UGSYR3]^!EZ]\
+M[G1#KO3\^#_<<N`P32-YS0(BJ6+%NF3CB1=>.T-RZD$BT=6ZKKRJ]2WE*UP^
+M3$2IS3WM_=\LG?M3$JM>Y;8;-^_:87EFRZ=(M)3R]D]L[>_LN>3`7:^2N&P+
+MC_=UMF_OIP+22/)P/YF=VV[8>M71-XI)K.;MW5_OZFC?\O1K]R=Y7TNXO[:+
+M&R31NHKK.[A>W-6SXWHU3<.\;Y/$RI>V]6UN[Y<'UI"XG-L>'.MIO[Y_0X&X
+ME,?OX_%6;WM/1W%:OI$DY2]XFQOZ^[;OR)PD'Q]?M?O[!SKZ7<=;G^/YV?M_
+M:!<?3]S3>@GW+[2/MXN/IY&HX?H7[>.1X%:):-<#FP)7!9:\35Z[@>C^D\Z*
+M'GOYFK\ERARG#!WCJF&/==C#CG-[\<1X[L\6SFOIM5M2-U,W>9P&B4PJI]F\
+M:3L]E-U'6@R3BTMI#E^][#K-QVG@#81;DX6-VV35_]Z^K]BX;"DER-JW;V(.
+M9"_*^1E<F$CZPE))GT6:\C_3]E,M3=ZIG@(`````````````````````````
+M`````````````````````````````````````````````,#_!T&D3_4<````
+M`,[CGTWP?\L"````````````````````````````````````````````````
+M?([AWTL%````````````````````````````````````````````````````
+M``````````````````````"`ST(0!:9Z#N?Q7+2IG@,`````````_,&0[%\6
+ML##)=DGD\>(F(;+=0G+&O!]WRLH'VL*?\KA-GWZJ[W/A^!_8T8?F(7_TX2=\
+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
+M\J1V95+913%Z.5MV3VKWT`9ZVRZKRGO[Y[(@M[@L6[ZP?R[+D]J52>4+^^>R
+M>U*[L__2S;.MI7W]-PQT=W;ML*YH;FU9L7&EM6Q;Q^8=`WV]W9NY<[Y5N6A1
+M3<NZ[IYU.WO7=G3NW-8^D.H8V-[=UVM5SZ^L6C_0OJ6CIWW@6JMOZV_8PURK
+ML:/[FN[>3BJES7P!+;YP?=1/-]``=5,G==$.;KN"FJF56F@%;:257%]&VZB#
+MQ^_@47W4RR,W9[><S^M*6L2IX?'KN*>'/W?RF+6\12>7ME$[;Y7BV@!MYWY[
+M>XNJ><M*JJ+UW-I.6[BWQQEW+??UT=9/.8>Y7&KDWFZZAI=>ZNPX=.6?MZZ;
+M>)8<F=?YV:$+S^!D,JE\]V(D,AG[?G#+L<QQ>ZC]2<<^N%5++U<;*,W%]Y;2
+MC]CO;R]-<S[3]E,MS3<,````````````````````````````````````````
+M``````````````````````````````#@<T`0F5,]!P```(#S^&<3;:KG````
+M``````````````````````````````````````````````!3!_\F&0``````
+M````````````````````````````````````````````````````````````
+M`````````'P6@L@WU7,X[P]I+@`````````PQ23GTTTD2GD]EYQ?'1#IXT9V
+M[92=QE_Q,OWAEFV&(;@JUD\>;XS[LVNG[#2^E1WO]SOCTY/'^\?-[-HI.XVG
+MLN--TQG_X.3QYG@HNW;*3N,;V?$AITO\:/)XWW@@NW;*3N/I[/B`TR4ID\=[
+MQWW9M5-V&G^9'>_C+GO-595<'")[VY!AD&Z\0P:77=,?SC]622TK[5$?&/O'
+MO$SS^\GPGR7_)XP]QHMEFN0W1\G\^+%B-Y=GAT)DALY0Z./'2LU<S@\$R!<X
+M2X%/&/MC+D=]/O+ZWG%^A_2^L?;S,G@DH5`B,[)?%U:HJ.CI$;(:QT])U'?"
+MO/?+ZV?'0R5$A9XG[O[2F+)BK,DS'B[ZXE&BS$BB?H]:O*>9_^@B-I*@P5>&
+M=[_RM1OWSQF_5VU;573'"`V>4LFBM"1G1E9+"8V:A#G4>(2?"XN^^BWZ`EGB
+MR1/JG/N^-GQ7T=#0_D*>3H,X\UJQI`Z.J%\:-].#IV*)`\;!;VWBPXV:E`Z,
+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
+MR#H[\JFA>QY;5(RPCPJZE/H]8M0=N4L4SNK`D4T2FAT.?<2UE!N46YA,L^1,
+MAL+7TG`.FA3@'$4L\6=0F)8UX(3CWR=C\@%02P<(`"(GQI@```#.````4$L#
+M!!0`"``(`-H0?CX````````````````+````7W)E;',O+G)E;'.5D,]*Q#`0
+MA^^"[U!RM],*BLC6O8BB("QK[Q*321ML_FQF*O79//A(OH)9M:`K>_"89.;W
+M??F]O[XMEI,;BF=,9(-O1%U6HD"O@K:^:\3(YNA,+"\.#Q9K'"3G&>IMI"(O
+M>6I$SQS/`4CUZ"25(:+/+R8D)SD?4P=1JB?9(1Q7U2FDGQEB-[5H9>J0&P%7
+M=D)]&=3HT/,];L9LA*71A!M1W.A&K+-E^Q+QCX&S*@4*ADL5'$R1MN`3R&RS
+MS4P8$U(._80*V*\PTPEJN$.66K*$5?Y)_=#VHWOTT@[E[>KZVZ?>X_.O1L#-
+M()X17XKPJ_Q\\P%02P<(MR#R__,```"Y`0``4$L#!!0`"``(`-H0?CX`````
+M```````````3````6T-O;G1E;G1?5'EP97-=+GAM;*62STK$,!"'[X+O4'*5
+M-M6#B&S=@RN")P^^0$PF;=SFSS;3I3Z;!Q_)5W#2"L+"MK+>$F9^WP<S\_7Q
+MN5H/MLWVT$7C7<4NBY)EX*17QM45ZU'G-VQ]=WZV>GD/$#-J=K%B#6*XY3S*
+M!JR(A0_@J*)]9P72MZMY$'(K:N!797G-I7<(#G-,#)9H&]"B;S%[&*@PJ3MH
+M(\ONI]9DJY@(H352(-7YWJD#3_[C*"@Y]L3&A'A!#8P?<6@58;<@L;_@(<1<
+MFP&4\K*WE*!T3].!!8F7_W#,LP-E3H"GV"S8*T3]=[!_U7VD$J@\+24M]B@Z
+M:9?!G7%(-U>,#S1R"_.3>'I^/*`:FP[N+4`]A?AXLO3Z!E!+!PA?-651$0$`
+M`.<"``!02P$"+0`4``@`"`#:$'X^,JA?,K\#``#G#0``$P``````````````
+M````````365T861A=&$O2F]B7U!4+GAM;%!+`0(M`!0`"``(`-H0?CZV6O$]
+MTP```,@!```:```````````````````$``!-971A9&%T82]-6$1#7T5M<'1Y
+M7U!4+GAM;%!+`0(M`!0`"````-H0?C[?FNW>UP4``-<%```H````````````
+M`````!L%``!$;V-U;65N=',O,2]-971A9&%T82]086=E,5]4:'5M8FYA:6PN
+M2E!'4$L!`BT`%``(``@`VA!^/E!53P;H````/P$``"0`````````````````
+M2`L``$1O8W5M96YT<R\Q+U!A9V5S+U]R96QS+S$N9G!A9V4N<F5L<U!+`0(M
+M`!0`"``(`-H0?CY77S=7A`$``(8#```9`````````````````((,``!$;V-U
+M;65N=',O,2]086=E<R\Q+F9P86=E4$L!`BT`%``(``@`VA!^/N*$;,_\$```
+M%%@#`$8`````````````````30X``$1O8W5M96YT<R\Q+U)E<V]U<F-E<R]&
+M;VYT<R\S1$9$0D,X0BTT-3$T+30Q1C$M03@P."U$14$Q0S<Y0D%#,D(N;V1T
+M=&902P$"+0`4``@`"`#:$'X^!!!%#\4````-`0``*0````````````````"]
+M'P``1&]C=6UE;G1S+S$O7W)E;',O1FEX961$;V-U;65N="YF9&]C+G)E;'-0
+M2P$"+0`4``@`"`#:$'X^#(8J/94```"S````'@````````````````#9(```
+M1&]C=6UE;G1S+S$O1FEX961$;V-U;65N="YF9&]C4$L!`BT`%``(``@`VA!^
+M/A*Y#,J]````!@$``"8`````````````````NB$``%]R96QS+T9I>&5D1&]C
+M=6UE;G1397%U96YC92YF9'-E<2YR96QS4$L!`BT`%``(``@`VA!^/@`B)\:8
+M````S@```!L`````````````````RR(``$9I>&5D1&]C=6UE;G1397%U96YC
+M92YF9'-E<5!+`0(M`!0`"``(`-H0?CZW(/+_\P```+D!```+````````````
+M`````*PC``!?<F5L<R\N<F5L<U!+`0(M`!0`"``(`-H0?CY?-651$0$``.<"
+M```3`````````````````-@D``!;0V]N=&5N=%]4>7!E<UTN>&UL4$L%!@``
+0```,``P`I@,``"HF````````
+`
+end
diff --git a/libarchive/test/test_compat_zip_6.zip.uu b/libarchive/test/test_compat_zip_6.zip.uu
new file mode 100644
index 000000000000..ef6d1912697f
--- /dev/null
+++ b/libarchive/test/test_compat_zip_6.zip.uu
@@ -0,0 +1,10 @@
+begin 755 test_compat_zip_6.zip
+M4$L#!`H``````'@3-T`````````````````6````3F5W($9O;&1E<B].97<@
+M1F]L9&5R+U!+`P0*``````!\$S=`%4-8OPL````+````*P```$YE=R!&;VQD
+M97(O3F5W($9O;&1E<B].97<@5&5X="!$;V-U;65N="YT>'1S;VUE('1E>'0-
+M"E!+`0(4"PH``````'@3-T`````````````````6````````````$```````
+M``!.97<@1F]L9&5R+TYE=R!&;VQD97(O4$L!`A0+"@``````?!,W0!5#6+\+
+M````"P```"L``````````0`@````-````$YE=R!&;VQD97(O3F5W($9O;&1E
+M<B].97<@5&5X="!$;V-U;65N="YT>'102P4&``````(``@"=````B```````
+`
+end
diff --git a/libarchive/test/test_compat_zip_7.xps.uu b/libarchive/test/test_compat_zip_7.xps.uu
new file mode 100644
index 000000000000..cfc8ecb2323f
--- /dev/null
+++ b/libarchive/test/test_compat_zip_7.xps.uu
@@ -0,0 +1,357 @@
+begin 644 test_compat_zip_7.xps
+M4$L#!!0`"``(`$"K-D`````````````````3````365T861A=&$O2F]B7U!4
+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
+M"!1"D:&QP0DC,U+P%6)RT0H6)#3A)?$7&!D:)B<H*2HU-C<X.3I#1$5&1TA)
+M2E-455976%E:8V1E9F=H:6IS='5V=WAY>H*#A(6&AXB)BI*3E)66EYB9FJ*C
+MI*6FIZBIJK*SM+6VM[BYNL+#Q,7&Q\C)RM+3U-76U]C9VN+CY.7FY^CIZO+S
+M]/7V]_CY^O_:``P#`0`"$0,1`#\`].HHHH`****`"BBB@`HHHH`****`"BBB
+M@`HHHH`****`"BBB@`HHHH`****`"BBB@`HHHH`**SIM'BE:9A>:A&95<#9=
+MOB-G!!903UY&`<JI`*@'.77.F?:+UKK[=?1$P"(1Q38C4AMP<+C&[(QSD$<$
+M$$T`7Z*IFP;[5-<+?7:M(K@*'!2,LJ#*J01D;,C.1EFZYIS6$+($+W.%01C%
+MS(#@!AUW9)PQYZYP<Y4$`%JBLZST>*V)=[S4+F5FW-)-=OR=V[[H(0#(`P%`
+MQQT)S*--B\UI&GNVS*)57[2X"D9.T`$97+$X.1R!T50`"Y15/4=/6_M9H?M5
+MW:M,JJ9;:8HZA6S\O4`GD$XR1P>@Q:2-49V!;+MN.6)`.`.`>@XZ#C.3U)H`
+MR]7\2Z-HLOE:G?+!(55@FQF)#;L$``\?*?IQGJ,SG5[1=/DOI/-2%)V@/[LN
+MQ<2F+`5<DY8<8]13;#2%LK+[*;_4+A"KAWN+@L[EL<[^JD`8&T@<D]>:)M(6
+M2XBFBO\`4(`DIE>-+@LLA+*VTALX7Y`,+@8+#H30!+I.IVVL:='?V19K>1G"
+M,RX+!6*YQZ'&1WQZ5<J*WMTMT*1M*0<?ZR5G/``ZL2>@'U.3U)-2T`%%%%`!
+M1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%
+M%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`444
+M4`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110
+M`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!
+M1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%
+M%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`444
+M4`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110
+M`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!
+M1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%
+M%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`444
+M4`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110
+M`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!
+M1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%
+M%%`!1110`4444`%%%%`!1110`4444`%%%%`!14%U96UXT#74*RFWE$T6[D*X
+M!`;'J,G'OSU`J6.-8U*J6(+%OF8L<DDGD]N>!T`X'%`#J***`"BBB@`HHHH`
+M****`"BBB@`HHHH`****`"BBB@`HHHH`****`"BBB@`HHHH`****`"BBB@`H
+MHHH`****`"BBB@`HHHH`_]E02P<(%>T[FRH'```J!P``4$L#!!0`"``(`$"K
+M-D`````````````````D````1&]C=6UE;G1S+S$O4&%G97,O7W)E;',O,2YF
+M<&%G92YR96QS99!-3L0P#(7W2-RARCYU0]NA@Z:,IBHCL:WF`E'J_HA)')(4
+M#6=CP9&X`BEBP<_2S\_/G_WQ]K[;7_0Y>4'G9S(U$VG&$C2*^MF,-5O"P"NV
+MO[^^VG5XEB%Z_#1;G\0AXVLVA6#O`+R:4$N?DD43.P,Y+4,LW0A6JB<Y(MQD
+MV0;<SPSV-S4Y23=BJ!FTI!:-)G@0T*&GQ2GT<*15:<K#@SAL!&^K/.-%(8Y\
+MVV:W?%L6Q[P13=Z454I]"`-+'ON:=?&@TZO%?[!Z5HX\#2%5I.%B_<I8PA?F
+M\S([[+G[WLU@985?+XC*)U!+!PCA-I_!Z````#\!``!02P,$%``(``@`0*LV
+M0````````````````!D```!$;V-U;65N=',O,2]086=E<R\Q+F9P86=EU9/-
+M;MP@$,?/S5,@>EZ^;`P.ZTA9;=SVTD:Q5DF.EHUM)!NO#*MN^O3%MK+:-D\0
+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
+MR.;H3"PO#@\6:QPDYQGJ;:0B+WEJ1,\<SP%(]>@DE2&BSR\F)"<Y'U,'4:HG
+MV2$<5]4II)\98C>U:&7JD!L!5W9"?1G4Z-#S/6[&;(2ET80;4=SH1JRS9?L2
+M\8^!LRH%"H9+%1Q,D;;@$\ALL\U,&!-2#OV$"MBO,-,):KA#EEJRA%7^2?W0
+M]J-[]-(.Y>WJ^MNGWN/SKT;`S2">$5^*\*O\?/,!4$L'"+<@\O_S````N0$`
+M`%!+`P04``@`"`!`JS9`````````````````$P```%M#;VYT96YT7U1Y<&5S
+M72YX;6REDL]*Q#`0A^^"[U!RE3;5@XALW8,K@B</OD!,)FW<YL\VTZ4^FP<?
+MR5=PT@K"PK:RWA)F?M\',_/U\;E:#[;-]M!%XUW%+HN29>"D5\;5%>M1YS=L
+M?7=^MGIY#Q`S:G:Q8@UBN.4\R@:LB(4/X*BB?6<%TK>K>1!R*VK@5V5YS:5W
+M"`YS3`R6:!O0HF\Q>QBH,*D[:"/+[J?69*N8"*$U4B#5^=ZI`T_^XR@H.?;$
+MQH1X00V,'W%H%6&W(+&_X"'$7)L!E/*RMY2@=$_3@06)E_]PS+,#94Z`I]@L
+MV"M$_7>P?]5]I!*H/"TE+?8H.FF7P9UQ2#=7C`\T<@OSDWAZ?CR@&IL.[BU`
+M/87X>++T^@902P<(7S5E41$!``#G`@``4$L!`BT`%``(``@`0*LV0'#&B=;`
+M`P``YPT``!,``````````````````````$UE=&%D871A+TIO8E]05"YX;6Q0
+M2P$"+0`4``@`"`!`JS9`MEKQ/=,```#(`0``&@`````````````````!!```
+M365T861A=&$O35A$0U]%;7!T>5]05"YX;6Q02P$"+0`4``@```!`JS9`%>T[
+MFRH'```J!P``*``````````````````<!0``1&]C=6UE;G1S+S$O365T861A
+M=&$O4&%G93%?5&AU;6)N86EL+DI01U!+`0(M`!0`"``(`$"K-D#A-I_!Z```
+M`#\!```D`````````````````)P,``!$;V-U;65N=',O,2]086=E<R]?<F5L
+M<R\Q+F9P86=E+G)E;'-02P$"+0`4``@`"`!`JS9`'L8"JZX!````!```&0``
+M``````````````#6#0``1&]C=6UE;G1S+S$O4&%G97,O,2YF<&%G95!+`0(M
+M`!0`"``(`$"K-D"&SHM0R",``#1%``!&`````````````````,L/``!$;V-U
+M;65N=',O,2]297-O=7)C97,O1F]N=',O0C5!13%!-C$M1#@S,"TT-#%&+3E$
+M,#<M.34T1C-",4(S0C4X+F]D='1F4$L!`BT`%``(``@`0*LV0`0010_%````
+M#0$``"D`````````````````!S0``$1O8W5M96YT<R\Q+U]R96QS+T9I>&5D
+M1&]C=6UE;G0N9F1O8RYR96QS4$L!`BT`%``(``@`0*LV0`R&*CV5````LP``
+M`!X`````````````````(S4``$1O8W5M96YT<R\Q+T9I>&5D1&]C=6UE;G0N
+M9F1O8U!+`0(M`!0`"``(`$"K-D`2N0S*O0````8!```F````````````````
+M``0V``!?<F5L<R]&:7AE9$1O8W5M96YT4V5Q=65N8V4N9F1S97$N<F5L<U!+
+M`0(M`!0`"``(`$"K-D``(B?&F````,X````;`````````````````!4W``!&
+M:7AE9$1O8W5M96YT4V5Q=65N8V4N9F1S97%02P$"+0`4``@`"`!`JS9`MR#R
+M__,```"Y`0``"P````````````````#V-P``7W)E;',O+G)E;'-02P$"+0`4
+M``@`"`!`JS9`7S5E41$!``#G`@``$P`````````````````B.0``6T-O;G1E
+C;G1?5'EP97-=+GAM;%!+!08`````#``,`*8#``!T.@``````
+`
+end
diff --git a/libarchive/test/test_empty_write.c b/libarchive/test/test_empty_write.c
index 0523ec362c35..5495177f207f 100644
--- a/libarchive/test/test_empty_write.c
+++ b/libarchive/test/test_empty_write.c
@@ -60,8 +60,8 @@ DEFINE_TEST(test_empty_write)
assertEqualIntA(a, 0, archive_write_data(a, "", 0));
/* Close out the archive. */
- assertA(0 == archive_write_close(a));
- assertA(0 == archive_write_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
}
/*
@@ -90,8 +90,8 @@ DEFINE_TEST(test_empty_write)
assertEqualIntA(a, 0, archive_write_data(a, "", 0));
/* Close out the archive. */
- assertA(0 == archive_write_close(a));
- assertA(0 == archive_write_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
}
/*
@@ -115,6 +115,6 @@ DEFINE_TEST(test_empty_write)
assertEqualIntA(a, 0, archive_write_data(a, "", 0));
/* Close out the archive. */
- assertA(0 == archive_write_close(a));
- assertA(0 == archive_write_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
}
diff --git a/libarchive/test/test_entry.c b/libarchive/test/test_entry.c
index bf36cbe3f37b..8249c7319eff 100644
--- a/libarchive/test/test_entry.c
+++ b/libarchive/test/test_entry.c
@@ -63,6 +63,7 @@ DEFINE_TEST(test_entry)
size_t xsize; /* For xattr tests. */
wchar_t wc;
long l;
+ int i;
assert((e = archive_entry_new()) != NULL);
@@ -111,6 +112,12 @@ DEFINE_TEST(test_entry)
archive_entry_set_atime(e, 13579, 24680);
assertEqualInt(archive_entry_atime(e), 13579);
assertEqualInt(archive_entry_atime_nsec(e), 24680);
+ archive_entry_set_atime(e, 13580, 1000000001L);
+ assertEqualInt(archive_entry_atime(e), 13581);
+ assertEqualInt(archive_entry_atime_nsec(e), 1);
+ archive_entry_set_atime(e, 13580, -7);
+ assertEqualInt(archive_entry_atime(e), 13579);
+ assertEqualInt(archive_entry_atime_nsec(e), 999999993);
archive_entry_unset_atime(e);
assertEqualInt(archive_entry_atime(e), 0);
assertEqualInt(archive_entry_atime_nsec(e), 0);
@@ -120,6 +127,12 @@ DEFINE_TEST(test_entry)
archive_entry_set_birthtime(e, 17579, 24990);
assertEqualInt(archive_entry_birthtime(e), 17579);
assertEqualInt(archive_entry_birthtime_nsec(e), 24990);
+ archive_entry_set_birthtime(e, 17580, 1234567890L);
+ assertEqualInt(archive_entry_birthtime(e), 17581);
+ assertEqualInt(archive_entry_birthtime_nsec(e), 234567890);
+ archive_entry_set_birthtime(e, 17581, -24990);
+ assertEqualInt(archive_entry_birthtime(e), 17580);
+ assertEqualInt(archive_entry_birthtime_nsec(e), 999975010);
archive_entry_unset_birthtime(e);
assertEqualInt(archive_entry_birthtime(e), 0);
assertEqualInt(archive_entry_birthtime_nsec(e), 0);
@@ -129,27 +142,27 @@ DEFINE_TEST(test_entry)
archive_entry_set_ctime(e, 13580, 24681);
assertEqualInt(archive_entry_ctime(e), 13580);
assertEqualInt(archive_entry_ctime_nsec(e), 24681);
+ archive_entry_set_ctime(e, 13581, 2008182348L);
+ assertEqualInt(archive_entry_ctime(e), 13583);
+ assertEqualInt(archive_entry_ctime_nsec(e), 8182348);
+ archive_entry_set_ctime(e, 13582, -24681);
+ assertEqualInt(archive_entry_ctime(e), 13581);
+ assertEqualInt(archive_entry_ctime_nsec(e), 999975319);
archive_entry_unset_ctime(e);
assertEqualInt(archive_entry_ctime(e), 0);
assertEqualInt(archive_entry_ctime_nsec(e), 0);
assert(!archive_entry_ctime_is_set(e));
-#if ARCHIVE_VERSION_NUMBER >= 1009000
/* dev */
+ assert(!archive_entry_dev_is_set(e));
archive_entry_set_dev(e, 235);
+ assert(archive_entry_dev_is_set(e));
assertEqualInt(archive_entry_dev(e), 235);
-#else
- skipping("archive_entry_dev()");
-#endif
/* devmajor/devminor are tested specially below. */
-#if ARCHIVE_VERSION_NUMBER >= 1009000
/* filetype */
archive_entry_set_filetype(e, AE_IFREG);
assertEqualInt(archive_entry_filetype(e), AE_IFREG);
-#else
- skipping("archive_entry_filetype()");
-#endif
/* fflags are tested specially below */
@@ -185,13 +198,17 @@ DEFINE_TEST(test_entry)
archive_entry_copy_hardlink_w(e, NULL);
assertEqualString(archive_entry_hardlink(e), NULL);
assertEqualWString(archive_entry_hardlink_w(e), NULL);
-#if ARCHIVE_VERSION_NUMBER >= 1009000
+
/* ino */
+ assert(!archive_entry_ino_is_set(e));
archive_entry_set_ino(e, 8593);
+ assert(archive_entry_ino_is_set(e));
assertEqualInt(archive_entry_ino(e), 8593);
-#else
- skipping("archive_entry_ino()");
-#endif
+ assertEqualInt(archive_entry_ino64(e), 8593);
+ archive_entry_set_ino64(e, 8594);
+ assert(archive_entry_ino_is_set(e));
+ assertEqualInt(archive_entry_ino(e), 8594);
+ assertEqualInt(archive_entry_ino64(e), 8594);
/* link */
archive_entry_set_hardlink(e, "hardlinkname");
@@ -231,18 +248,20 @@ DEFINE_TEST(test_entry)
archive_entry_set_mtime(e, 13581, 24682);
assertEqualInt(archive_entry_mtime(e), 13581);
assertEqualInt(archive_entry_mtime_nsec(e), 24682);
+ archive_entry_set_mtime(e, 13582, 1358297468);
+ assertEqualInt(archive_entry_mtime(e), 13583);
+ assertEqualInt(archive_entry_mtime_nsec(e), 358297468);
+ archive_entry_set_mtime(e, 13583, -24682);
+ assertEqualInt(archive_entry_mtime(e), 13582);
+ assertEqualInt(archive_entry_mtime_nsec(e), 999975318);
archive_entry_unset_mtime(e);
assertEqualInt(archive_entry_mtime(e), 0);
assertEqualInt(archive_entry_mtime_nsec(e), 0);
assert(!archive_entry_mtime_is_set(e));
-#if ARCHIVE_VERSION_NUMBER >= 1009000
/* nlink */
archive_entry_set_nlink(e, 736);
assertEqualInt(archive_entry_nlink(e), 736);
-#else
- skipping("archive_entry_nlink()");
-#endif
/* pathname */
archive_entry_set_pathname(e, "path");
@@ -260,13 +279,9 @@ DEFINE_TEST(test_entry)
memset(wbuff, 0, sizeof(wbuff));
assertEqualWString(archive_entry_pathname_w(e), L"wpath");
-#if ARCHIVE_VERSION_NUMBER >= 1009000
/* rdev */
archive_entry_set_rdev(e, 532);
assertEqualInt(archive_entry_rdev(e), 532);
-#else
- skipping("archive_entry_rdev()");
-#endif
/* rdevmajor/rdevminor are tested specially below. */
/* size */
@@ -283,13 +298,11 @@ DEFINE_TEST(test_entry)
/* symlink */
archive_entry_set_symlink(e, "symlinkname");
assertEqualString(archive_entry_symlink(e), "symlinkname");
-#if ARCHIVE_VERSION_NUMBER >= 1009000
strcpy(buff, "symlinkname2");
archive_entry_copy_symlink(e, buff);
assertEqualString(archive_entry_symlink(e), "symlinkname2");
memset(buff, 0, sizeof(buff));
assertEqualString(archive_entry_symlink(e), "symlinkname2");
-#endif
archive_entry_copy_symlink_w(e, NULL);
assertEqualWString(archive_entry_symlink_w(e), NULL);
assertEqualString(archive_entry_symlink(e), NULL);
@@ -380,25 +393,17 @@ DEFINE_TEST(test_entry)
archive_entry_set_atime(e, 13579, 24680);
archive_entry_set_birthtime(e, 13779, 24990);
archive_entry_set_ctime(e, 13580, 24681);
-#if ARCHIVE_VERSION_NUMBER >= 1009000
archive_entry_set_dev(e, 235);
-#endif
archive_entry_set_fflags(e, 0x55, 0xAA);
archive_entry_set_gid(e, 204);
archive_entry_set_gname(e, "group");
archive_entry_set_hardlink(e, "hardlinkname");
-#if ARCHIVE_VERSION_NUMBER >= 1009000
archive_entry_set_ino(e, 8593);
-#endif
archive_entry_set_mode(e, 0123456);
archive_entry_set_mtime(e, 13581, 24682);
-#if ARCHIVE_VERSION_NUMBER >= 1009000
archive_entry_set_nlink(e, 736);
-#endif
archive_entry_set_pathname(e, "path");
-#if ARCHIVE_VERSION_NUMBER >= 1009000
archive_entry_set_rdev(e, 532);
-#endif
archive_entry_set_size(e, 987654321);
archive_entry_copy_sourcepath(e, "source");
archive_entry_set_symlink(e, "symlinkname");
@@ -420,36 +425,26 @@ DEFINE_TEST(test_entry)
assertEqualInt(archive_entry_birthtime_nsec(e2), 24990);
assertEqualInt(archive_entry_ctime(e2), 13580);
assertEqualInt(archive_entry_ctime_nsec(e2), 24681);
-#if ARCHIVE_VERSION_NUMBER >= 1009000
assertEqualInt(archive_entry_dev(e2), 235);
-#endif
archive_entry_fflags(e, &set, &clear);
assertEqualInt(clear, 0xAA);
assertEqualInt(set, 0x55);
assertEqualInt(archive_entry_gid(e2), 204);
assertEqualString(archive_entry_gname(e2), "group");
assertEqualString(archive_entry_hardlink(e2), "hardlinkname");
-#if ARCHIVE_VERSION_NUMBER >= 1009000
assertEqualInt(archive_entry_ino(e2), 8593);
-#endif
assertEqualInt(archive_entry_mode(e2), 0123456);
assertEqualInt(archive_entry_mtime(e2), 13581);
assertEqualInt(archive_entry_mtime_nsec(e2), 24682);
-#if ARCHIVE_VERSION_NUMBER >= 1009000
assertEqualInt(archive_entry_nlink(e2), 736);
-#endif
assertEqualString(archive_entry_pathname(e2), "path");
-#if ARCHIVE_VERSION_NUMBER >= 1009000
assertEqualInt(archive_entry_rdev(e2), 532);
-#endif
assertEqualInt(archive_entry_size(e2), 987654321);
assertEqualString(archive_entry_sourcepath(e2), "source");
assertEqualString(archive_entry_symlink(e2), "symlinkname");
assertEqualInt(archive_entry_uid(e2), 83);
assertEqualString(archive_entry_uname(e2), "user");
-#if ARCHIVE_VERSION_NUMBER < 1009000
- skipping("ACL preserved by archive_entry_clone()");
-#else
+
/* Verify ACL was copied. */
assertEqualInt(4, archive_entry_acl_reset(e2,
ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
@@ -487,10 +482,7 @@ DEFINE_TEST(test_entry)
assertEqualInt(tag, ARCHIVE_ENTRY_ACL_USER);
assertEqualInt(qual, 77);
assertEqualString(name, "user77");
-#endif
-#if ARCHIVE_VERSION_NUMBER < 1009000
- skipping("xattr data preserved by archive_entry_clone");
-#else
+
/* Verify xattr was copied. */
assertEqualInt(1, archive_entry_xattr_reset(e2));
assertEqualInt(0, archive_entry_xattr_next(e2, &xname, &xval, &xsize));
@@ -502,34 +494,23 @@ DEFINE_TEST(test_entry)
assertEqualString(xname, NULL);
assertEqualString(xval, NULL);
assertEqualInt((int)xsize, 0);
-#endif
/* Change the original */
archive_entry_set_atime(e, 13580, 24690);
archive_entry_set_birthtime(e, 13980, 24999);
archive_entry_set_ctime(e, 13590, 24691);
-#if ARCHIVE_VERSION_NUMBER >= 1009000
archive_entry_set_dev(e, 245);
-#endif
archive_entry_set_fflags(e, 0x85, 0xDA);
-#if ARCHIVE_VERSION_NUMBER >= 1009000
archive_entry_set_filetype(e, AE_IFLNK);
-#endif
archive_entry_set_gid(e, 214);
archive_entry_set_gname(e, "grouper");
archive_entry_set_hardlink(e, "hardlinkpath");
-#if ARCHIVE_VERSION_NUMBER >= 1009000
archive_entry_set_ino(e, 8763);
-#endif
archive_entry_set_mode(e, 0123654);
archive_entry_set_mtime(e, 18351, 28642);
-#if ARCHIVE_VERSION_NUMBER >= 1009000
archive_entry_set_nlink(e, 73);
-#endif
archive_entry_set_pathname(e, "pathest");
-#if ARCHIVE_VERSION_NUMBER >= 1009000
archive_entry_set_rdev(e, 132);
-#endif
archive_entry_set_size(e, 987456321);
archive_entry_copy_sourcepath(e, "source2");
archive_entry_set_symlink(e, "symlinkpath");
@@ -545,36 +526,26 @@ DEFINE_TEST(test_entry)
assertEqualInt(archive_entry_birthtime_nsec(e2), 24990);
assertEqualInt(archive_entry_ctime(e2), 13580);
assertEqualInt(archive_entry_ctime_nsec(e2), 24681);
-#if ARCHIVE_VERSION_NUMBER >= 1009000
assertEqualInt(archive_entry_dev(e2), 235);
-#endif
archive_entry_fflags(e2, &set, &clear);
assertEqualInt(clear, 0xAA);
assertEqualInt(set, 0x55);
assertEqualInt(archive_entry_gid(e2), 204);
assertEqualString(archive_entry_gname(e2), "group");
assertEqualString(archive_entry_hardlink(e2), "hardlinkname");
-#if ARCHIVE_VERSION_NUMBER >= 1009000
assertEqualInt(archive_entry_ino(e2), 8593);
-#endif
assertEqualInt(archive_entry_mode(e2), 0123456);
assertEqualInt(archive_entry_mtime(e2), 13581);
assertEqualInt(archive_entry_mtime_nsec(e2), 24682);
-#if ARCHIVE_VERSION_NUMBER >= 1009000
assertEqualInt(archive_entry_nlink(e2), 736);
-#endif
assertEqualString(archive_entry_pathname(e2), "path");
-#if ARCHIVE_VERSION_NUMBER >= 1009000
assertEqualInt(archive_entry_rdev(e2), 532);
-#endif
assertEqualInt(archive_entry_size(e2), 987654321);
assertEqualString(archive_entry_sourcepath(e2), "source");
assertEqualString(archive_entry_symlink(e2), "symlinkname");
assertEqualInt(archive_entry_uid(e2), 83);
assertEqualString(archive_entry_uname(e2), "user");
-#if ARCHIVE_VERSION_NUMBER < 1009000
- skipping("ACL held by clone of archive_entry");
-#else
+
/* Verify ACL was unchanged. */
assertEqualInt(4, archive_entry_acl_reset(e2,
ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
@@ -620,13 +591,9 @@ DEFINE_TEST(test_entry)
assertEqualInt(tag, 0);
assertEqualInt(qual, -1);
assertEqualString(name, NULL);
-#endif
-#if ARCHIVE_VERSION_NUMBER < 1009000
- skipping("xattr preserved in archive_entry copy");
-#else
+
/* Verify xattr was unchanged. */
assertEqualInt(1, archive_entry_xattr_reset(e2));
-#endif
/* Release clone. */
archive_entry_free(e2);
@@ -645,9 +612,7 @@ DEFINE_TEST(test_entry)
archive_entry_fflags(e, &set, &clear);
assertEqualInt(clear, 0);
assertEqualInt(set, 0);
-#if ARCHIVE_VERSION_NUMBER >= 1009000
assertEqualInt(archive_entry_filetype(e), 0);
-#endif
assertEqualInt(archive_entry_gid(e), 0);
assertEqualString(archive_entry_gname(e), NULL);
assertEqualString(archive_entry_hardlink(e), NULL);
@@ -655,9 +620,7 @@ DEFINE_TEST(test_entry)
assertEqualInt(archive_entry_mode(e), 0);
assertEqualInt(archive_entry_mtime(e), 0);
assertEqualInt(archive_entry_mtime_nsec(e), 0);
-#if ARCHIVE_VERSION_NUMBER >= 1009000
assertEqualInt(archive_entry_nlink(e), 0);
-#endif
assertEqualString(archive_entry_pathname(e), NULL);
assertEqualInt(archive_entry_rdev(e), 0);
assertEqualInt(archive_entry_size(e), 0);
@@ -702,9 +665,7 @@ DEFINE_TEST(test_entry)
assertEqualInt(archive_entry_ino(e), 234);
assertEqualInt(archive_entry_mode(e), 077777);
assertEqualInt(archive_entry_mtime(e), 234567);
-#if ARCHIVE_VERSION_NUMBER >= 1009000
assertEqualInt(archive_entry_nlink(e), 345);
-#endif
assertEqualInt(archive_entry_size(e), 123456789);
assertEqualInt(archive_entry_uid(e), 23);
#if __FreeBSD__
@@ -724,19 +685,13 @@ DEFINE_TEST(test_entry)
/* Set a bunch of fields individually. */
archive_entry_set_atime(e, 456789, 321);
archive_entry_set_ctime(e, 345678, 432);
-#if ARCHIVE_VERSION_NUMBER >= 1009000
archive_entry_set_dev(e, 123);
-#endif
archive_entry_set_gid(e, 34);
-#if ARCHIVE_VERSION_NUMBER >= 1009000
archive_entry_set_ino(e, 234);
-#endif
archive_entry_set_mode(e, 012345);
archive_entry_set_mode(e, 012345);
archive_entry_set_mtime(e, 234567, 543);
-#if ARCHIVE_VERSION_NUMBER >= 1009000
archive_entry_set_nlink(e, 345);
-#endif
archive_entry_set_size(e, 123456789);
archive_entry_set_uid(e, 23);
/* Retrieve a stat structure. */
@@ -744,18 +699,12 @@ DEFINE_TEST(test_entry)
/* Check that the values match. */
assertEqualInt(pst->st_atime, 456789);
assertEqualInt(pst->st_ctime, 345678);
-#if ARCHIVE_VERSION_NUMBER >= 1009000
assertEqualInt(pst->st_dev, 123);
-#endif
assertEqualInt(pst->st_gid, 34);
-#if ARCHIVE_VERSION_NUMBER >= 1009000
assertEqualInt(pst->st_ino, 234);
-#endif
assertEqualInt(pst->st_mode, 012345);
assertEqualInt(pst->st_mtime, 234567);
-#if ARCHIVE_VERSION_NUMBER >= 1009000
assertEqualInt(pst->st_nlink, 345);
-#endif
assertEqualInt(pst->st_size, 123456789);
assertEqualInt(pst->st_uid, 23);
#ifdef __FreeBSD__
@@ -772,30 +721,24 @@ DEFINE_TEST(test_entry)
archive_entry_set_ctime(e, 345677, 431);
assert((pst = archive_entry_stat(e)) != NULL);
assertEqualInt(pst->st_ctime, 345677);
-#if ARCHIVE_VERSION_NUMBER >= 1009000
archive_entry_set_dev(e, 122);
assert((pst = archive_entry_stat(e)) != NULL);
assertEqualInt(pst->st_dev, 122);
-#endif
archive_entry_set_gid(e, 33);
assert((pst = archive_entry_stat(e)) != NULL);
assertEqualInt(pst->st_gid, 33);
-#if ARCHIVE_VERSION_NUMBER >= 1009000
archive_entry_set_ino(e, 233);
assert((pst = archive_entry_stat(e)) != NULL);
assertEqualInt(pst->st_ino, 233);
-#endif
archive_entry_set_mode(e, 012344);
assert((pst = archive_entry_stat(e)) != NULL);
assertEqualInt(pst->st_mode, 012344);
archive_entry_set_mtime(e, 234566, 542);
assert((pst = archive_entry_stat(e)) != NULL);
assertEqualInt(pst->st_mtime, 234566);
-#if ARCHIVE_VERSION_NUMBER >= 1009000
archive_entry_set_nlink(e, 344);
assert((pst = archive_entry_stat(e)) != NULL);
assertEqualInt(pst->st_nlink, 344);
-#endif
archive_entry_set_size(e, 123456788);
assert((pst = archive_entry_stat(e)) != NULL);
assertEqualInt(pst->st_size, 123456788);
@@ -819,7 +762,6 @@ DEFINE_TEST(test_entry)
* the necessary definitions on every platform.
*/
#if __FreeBSD__
-#if ARCHIVE_VERSION_NUMBER >= 1009000
archive_entry_set_dev(e, 0x12345678);
assertEqualInt(archive_entry_devmajor(e), major(0x12345678));
assertEqualInt(archive_entry_devminor(e), minor(0x12345678));
@@ -839,12 +781,11 @@ DEFINE_TEST(test_entry)
assertEqualInt(archive_entry_rdevminor(e), 0xdcba98);
assertEqualInt(archive_entry_rdev(e), makedev(0xfe, 0xdcba98));
#endif
-#endif
/*
* Exercise the character-conversion logic, if we can.
*/
- if (NULL == LOCALE_UTF8 || NULL == setlocale(LC_ALL, LOCALE_UTF8)) {
+ if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
skipping("Can't exercise charset-conversion logic without"
" a suitable locale.");
} else {
@@ -852,8 +793,10 @@ DEFINE_TEST(test_entry)
archive_entry_copy_pathname(e, "abc\314\214mno\374xyz");
failure("Converting invalid chars to Unicode should fail.");
assert(NULL == archive_entry_pathname_w(e));
- //failure("Converting invalid chars to UTF-8 should fail.");
- //assert(NULL == archive_entry_pathname_utf8(e));
+ /*
+ failure("Converting invalid chars to UTF-8 should fail.");
+ assert(NULL == archive_entry_pathname_utf8(e));
+ */
/* A group name that cannot be converted. */
archive_entry_copy_gname(e, "abc\314\214mno\374xyz");
@@ -876,7 +819,6 @@ DEFINE_TEST(test_entry)
assert(NULL == archive_entry_symlink_w(e));
}
-#if HAVE_WCSCPY
l = 0x12345678L;
wc = (wchar_t)l; /* Wide character too big for UTF-8. */
if (NULL == setlocale(LC_ALL, "C") || (long)wc != l) {
@@ -884,19 +826,18 @@ DEFINE_TEST(test_entry)
} else {
/*
* Build the string L"xxx\U12345678yyy\u5678zzz" without
- * using C99 \u#### syntax, which isn't uniformly
- * supported. (GCC 3.4.6, for instance, defaults to
- * "c89 plus GNU extensions.")
+ * using wcscpy or C99 \u#### syntax.
*/
- wcscpy(wbuff, L"xxxAyyyBzzz");
+ name = "xxxAyyyBzzz";
+ for (i = 0; i < (int)strlen(name); ++i)
+ wbuff[i] = name[i];
wbuff[3] = (wchar_t)0x12345678;
wbuff[7] = (wchar_t)0x5678;
- /* A wide filename that cannot be converted to narrow. */
+ /* A Unicode filename that cannot be converted to UTF-8. */
archive_entry_copy_pathname_w(e, wbuff);
failure("Converting wide characters from Unicode should fail.");
assertEqualString(NULL, archive_entry_pathname(e));
}
-#endif
/* Release the experimental entry. */
archive_entry_free(e);
diff --git a/libarchive/test/test_extattr_freebsd.c b/libarchive/test/test_extattr_freebsd.c
index 4b19d2762973..8ffe756d1216 100644
--- a/libarchive/test/test_extattr_freebsd.c
+++ b/libarchive/test/test_extattr_freebsd.c
@@ -104,6 +104,7 @@ DEFINE_TEST(test_extattr_freebsd)
archive_entry_set_mode(ae, 0755);
archive_entry_xattr_add_entry(ae, "user.foo", "12345", 5);
assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_finish_entry(a));
archive_entry_free(ae);
/* Another entry; similar but with mode = 0. */
@@ -123,7 +124,7 @@ DEFINE_TEST(test_extattr_freebsd)
assertEqualIntA(a, ARCHIVE_WARN, archive_write_close(a));
else
assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
- assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/* Verify the data on disk. */
assertEqualInt(0, stat("test0", &st));
@@ -166,7 +167,7 @@ DEFINE_TEST(test_extattr_freebsd)
assertEqualInt(xsize, 5);
assertEqualMem(xval, "12345", xsize);
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
archive_entry_free(ae);
#endif
}
diff --git a/libarchive/test/test_filter_count.c b/libarchive/test/test_filter_count.c
new file mode 100644
index 000000000000..3f587e33852f
--- /dev/null
+++ b/libarchive/test/test_filter_count.c
@@ -0,0 +1,72 @@
+/*-
+ * Copyright (c) 2003-2009 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_file_nonexistent.c 189473 2009-03-07 02:09:21Z kientzle $");
+
+void
+read_test(const char *name)
+{
+ struct archive* a = archive_read_new();
+ if(ARCHIVE_OK != archive_read_support_filter_bzip2(a)) {
+ skipping("bzip2 unsupported");
+ return;
+ }
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+
+ extract_reference_file(name);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 2));
+ /* bzip2 and none */
+ assertEqualInt(2, archive_filter_count(a));
+
+ archive_read_free(a);
+}
+
+void
+write_test(void)
+{
+ char buff[4096];
+ struct archive* a = archive_write_new();
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_bytes_per_block(a, 10));
+
+ if(ARCHIVE_OK != archive_write_set_compression_bzip2(a)) {
+ skipping("bzip2 unsupported");
+ return;
+ }
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, 4096, 0));
+ /* bzip2 and none */
+ assertEqualInt(2, archive_filter_count(a));
+ archive_write_free(a);
+}
+
+DEFINE_TEST(test_filter_count)
+{
+ read_test("test_compat_bzip2_1.tbz");
+ write_test();
+}
+
+
diff --git a/libarchive/test/test_fuzz.c b/libarchive/test/test_fuzz.c
index e5dede932161..78d941d1a8ac 100644
--- a/libarchive/test/test_fuzz.c
+++ b/libarchive/test/test_fuzz.c
@@ -52,6 +52,8 @@ static struct {
} files[] = {
{0, "test_fuzz_1.iso.Z"}, /* Exercise compress decompressor. */
{1, "test_fuzz_1.iso.Z"},
+ {0, "test_fuzz.cab"},
+ {0, "test_fuzz.lzh"},
{0, "test_compat_bzip2_1.tbz"}, /* Exercise bzip2 decompressor. */
{1, "test_compat_bzip2_1.tbz"},
{0, "test_compat_gtar_1.tar"},
@@ -60,9 +62,36 @@ static struct {
{0, "test_compat_tar_hardlink_1.tar"},
{0, "test_compat_xz_1.txz"}, /* Exercise xz decompressor. */
{0, "test_compat_zip_1.zip"},
+ {0, "test_read_format_7zip_bzip2.7z"},
+ {0, "test_read_format_7zip_bcj_lzma1.7z"},
+ {0, "test_read_format_7zip_bcj_lzma2.7z"},
+ {0, "test_read_format_7zip_bcj2_lzma1_1.7z"},
+ {0, "test_read_format_7zip_bcj2_lzma1_2.7z"},
+ {0, "test_read_format_7zip_bcj2_lzma2_1.7z"},
+ {0, "test_read_format_7zip_bcj2_lzma2_2.7z"},
+ {0, "test_read_format_7zip_copy.7z"},
+ {0, "test_read_format_7zip_deflate.7z"},
+ {0, "test_read_format_7zip_lzma1.7z"},
+ {0, "test_read_format_7zip_lzma1_lzma2.7z"},
+ {0, "test_read_format_7zip_ppmd.7z"},
{0, "test_read_format_ar.ar"},
{0, "test_read_format_cpio_bin_be.cpio"},
{0, "test_read_format_cpio_svr4_gzip_rpm.rpm"}, /* Test RPM unwrapper */
+ {0, "test_read_format_rar.rar"}, /* Uncompressed RAR test */
+ {0, "test_read_format_rar_binary_data.rar"}, /* RAR file with binary data */
+ {0, "test_read_format_rar_compress_best.rar"}, /* Best Compressed RAR test */
+ {0, "test_read_format_rar_compress_normal.rar"}, /* Normal Compressed RAR
+ * test */
+ {0, "test_read_format_rar_multi_lzss_blocks.rar"}, /* Normal Compressed Multi
+ * LZSS blocks RAR test */
+ {0, "test_read_format_rar_noeof.rar"}, /* RAR with no EOF header */
+ {0, "test_read_format_rar_ppmd_lzss_conversion.rar"}, /* Best Compressed
+ * RAR file with both
+ * PPMd and LZSS
+ * blocks */
+ {0, "test_read_format_rar_sfx.exe"}, /* RAR SFX archive */
+ {0, "test_read_format_rar_subblock.rar"}, /* RAR with subblocks */
+ {0, "test_read_format_rar_unicode.rar"}, /* RAR with Unicode filenames */
{0, "test_read_format_gtar_sparse_1_17_posix10_modified.tar"},
{0, "test_read_format_mtree.mtree"},
{0, "test_read_format_tar_empty_filename.tar"},
@@ -74,7 +103,7 @@ DEFINE_TEST(test_fuzz)
{
const void *blk;
size_t blk_size;
- off_t blk_offset;
+ int64_t blk_offset;
int n;
for (n = 0; files[n].name != NULL; ++n) {
@@ -84,7 +113,7 @@ DEFINE_TEST(test_fuzz)
struct archive *a;
char *rawimage, *image;
size_t size;
- int i;
+ int i, q;
extract_reference_file(filename);
if (files[n].uncompress) {
@@ -92,12 +121,12 @@ DEFINE_TEST(test_fuzz)
/* Use format_raw to decompress the data. */
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK,
- archive_read_support_compression_all(a));
+ archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_support_format_raw(a));
r = archive_read_open_filename(a, filename, 16384);
if (r != ARCHIVE_OK) {
- archive_read_finish(a);
+ archive_read_free(a);
skipping("Cannot uncompress %s", filename);
continue;
}
@@ -108,7 +137,7 @@ DEFINE_TEST(test_fuzz)
assertEqualIntA(a, ARCHIVE_EOF,
archive_read_next_header(a, &ae));
assertEqualInt(ARCHIVE_OK,
- archive_read_finish(a));
+ archive_read_free(a));
assert(size > 0);
failure("Internal buffer is not big enough for "
"uncompressed test file: %s", filename);
@@ -127,24 +156,38 @@ DEFINE_TEST(test_fuzz)
for (i = 0; i < 100; ++i) {
FILE *f;
- int j, numbytes;
+ int j, numbytes, trycnt;
/* Fuzz < 1% of the bytes in the archive. */
memcpy(image, rawimage, size);
- numbytes = (int)(rand() % (size / 100));
+ q = size / 100;
+ if (!q) q = 1;
+ numbytes = (int)(rand() % q);
for (j = 0; j < numbytes; ++j)
image[rand() % size] = (char)rand();
/* Save the messed-up image to a file.
* If we crash, that file will be useful. */
- f = fopen("after.test.failure.send.this.file."
- "to.libarchive.maintainers.with.system.details", "wb");
- fwrite(image, 1, (size_t)size, f);
+ for (trycnt = 0; trycnt < 3; trycnt++) {
+ f = fopen("after.test.failure.send.this.file."
+ "to.libarchive.maintainers.with.system.details", "wb");
+ if (f != NULL)
+ break;
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ /*
+ * Sometimes previous close operation does not completely
+ * end at this time. So we should take a wait while
+ * the operation running.
+ */
+ Sleep(100);
+#endif
+ }
+ assertEqualInt((size_t)size, fwrite(image, 1, (size_t)size, f));
fclose(f);
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK,
- archive_read_support_compression_all(a));
+ archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_support_format_all(a));
@@ -156,7 +199,7 @@ DEFINE_TEST(test_fuzz)
}
archive_read_close(a);
}
- archive_read_finish(a);
+ archive_read_free(a);
}
free(image);
free(rawimage);
diff --git a/libarchive/test/test_fuzz.cab.uu b/libarchive/test/test_fuzz.cab.uu
new file mode 100644
index 000000000000..4cfa4fb7c9dd
--- /dev/null
+++ b/libarchive/test/test_fuzz.cab.uu
@@ -0,0 +1,49 @@
+begin 644 test_fuzz.cab
+M35-#1@`````1"````````"P``````````P$!``0```#X!P``A0````$``Q)K
+M````````````G3U:L2``9FEL90#I!```:P``````G3TYL2``24Y35$%,3```
+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
+H^+5YR;W&3(M6?E57A59NO4H-K"3>576O"ZQ6R!-&3>Z7&K;GPA9\V```
+`
+end
diff --git a/libarchive/test/test_fuzz.lzh.uu b/libarchive/test/test_fuzz.lzh.uu
new file mode 100644
index 000000000000..781ebbbb6052
--- /dev/null
+++ b/libarchive/test/test_fuzz.lzh.uu
@@ -0,0 +1,152 @@
+begin 644 test_fuzz.lzh
+M)L`M;&AD+0```````````$@B[!``!&1I<EP``%4`@5$!`.A!Z0/I`R?X+6QH
+M9"T```````````!((NP0``5D:7(R7```50"!40$`[4'I`^D#.'PM;&AD+0``
+M`````````4@C[!``%F1I<C)<<WEM;&EN:S%\+BY<9FEL93$``%4``J,"`.VA
+MZ0/I`SA^+6QH9"T```````````%((^P0`!9D:7(R7'-Y;6QI;FLR?"XN7&9I
+M;&4R``!5``*C`@#MH>D#Z0,GO2UL:#4M(@```#P`````2"+L(``%9FEL93&D
+MYU4`@5$!`*2!Z0/I`P`80FYIQ>/Z`=-:'>9%#"P%J!\CH0"/GE$,.W6FMSD%
+M*_4G02UL:#4M(@```$X`````2"+L(``%9FEL93+5%54`@5$!`+:!Z0/I`P`8
+M0FYIQV/Z`=.:'.9%#"P%J-\+H0"/'E$,.W6FMSD%*_T9?RUL:&0M&@``````
+M````2"+L(`$```!5!P`"9&ER_P4`4.A!!P!1Z0/I`P<`5(%1`0```!F!+6QH
+M9"T;``````````!((NP@`0```%4(``)D:7(R_P4`4.U!!P!1Z0/I`P<`5(%1
+M`0```!YQ+6QH9"TG``````````%((^P@`05F:6QE,0``510``F1I<C+_<WEM
+M;&EN:S%\+B[_!0!0[:$'`%'I`^D#!P!4`J,"````'G(M;&AD+2<`````````
+M`4@C["`!!69I;&4R``!5%``"9&ER,O]S>6UL:6YK,GPN+O\%`%#MH0<`4>D#
+MZ0,'`%0"HP(````>!BUL:#4M-0```#P`````2"+L(`$%9FEL93&DYU4%`%"D
+M@0<`4>D#Z0,'`%2!40$`````&$)N:<7C^@'36AWF10PL!:@?(Z$`CYY1##MU
+MIK<Y!2OU'G@M;&@U+34```!.`````$@B["`!!69I;&4RU155!0!0MH$'`%'I
+M`^D#!P!4@5$!`````!A";FG'8_H!TYH<YD4,+`6HWPNA`(\>40P[=::W.04K
+M_34`+6QH9"T``````````(%1`0`@`@``504```7>`P`!!P`"9&ER_P4`4.A!
+M!P!1Z0/I`P``-@`M;&AD+0``````````@5$!`"`"``!5!0``")D#``$(``)D
+M:7(R_P4`4.U!!P!1Z0/I`P``1P`M;&AD+0```````````J,"`"`"``!5!0``
+MM*D(``%F:6QE,10``F1I<C+_<WEM;&EN:S%\+B[_!0!0[:$'`%'I`^D#``!'
+M`"UL:&0M```````````"HP(`(`(``%4%``"'[0@``69I;&4R%``"9&ER,O]S
+M>6UL:6YK,GPN+O\%`%#MH0<`4>D#Z0,``#,`+6QH-2TB````/````(%1`0`@
+M`J3G504``/T!"``!9FEL93$%`%"D@0<`4>D#Z0,````80FYIQ>/Z`=-:'>9%
+M#"P%J!\CH0"/GE$,.W6FMSD%*_4S`"UL:#4M(@```$X```"!40$`(`+5%54%
+M```OQ@@``69I;&4R!0!0MH$'`%'I`^D#````&$)N:<=C^@'3FASF10PL!:C?
+M"Z$`CQY1##MUIK<Y!2O]!``M;&AD+0``````````@5$!`"`#``!-?`````D`
+M``!&I`,```4````!"0````)D:7+_!P```$`0`!D```#_[4$`````````````
+M#!7^3$0:_DP=````0<S?4;3^E<L!@-9``*BRG0$`>@_0`9;+`0@`````+J\'
+M``````0`+6QH9"T``````````(%1`0`@`P``37T````)````1J0#```%````
+M`0H````"9&ER,O\'````0!``&0```/_M00`````````````A&OY,1!K^3!T`
+M``!!2H%NNP&6RP&`UD``J+*=`0!Z#]`!ELL!"`````!]%P<`````!``M;&@U
+M+20````\````@5$!`"`#I.=-<0````D```!&I`,```H````!9FEL93$9````
+M_Z2!`````````````,<4_DPC&OY,'0```$$T0J**_I7+`8#60`"HLIT!_G*D
+MO`&6RP$(``````KQ!P``````&4)MD:BT=H!Z:T.IZ9#S:`ZH%CJ$`A]OC1DU
+M4VION(3=>H`$`"UL:#4M)````$X```"!40$`(`/5%4UQ````"0```$:D`P``
+M"@````%F:6QE,AD```#_I($`````````````(1K^3",:_DP=````0?Y%<[L!
+MELL!@-9``*BRG0%8U::\`9;+`0@`````0=X'```````90FV1J.QV@'IS0XGI
+MD/-H#JC&&H0"'F^-&353:F^XA-U^@#4`+6QH9"T``````````(%1`0`@`@``
+M504```7>`P`!!P`"9&ER_P4`4.A!!P!1Z0/I`P``-@`M;&AD+0``````````
+M@5$!`"`"``!5!0``")D#``$(``)D:7(R_P4`4.U!!P!1Z0/I`P``1P`M;&AD
+M+0```````````J,"`"`"``!5!0``M*D(``%F:6QE,10``F1I<C+_<WEM;&EN
+M:S%\+B[_!0!0[:$'`%'I`^D#``!'`"UL:&0M```````````"HP(`(`(``%4%
+M``"'[0@``69I;&4R%``"9&ER,O]S>6UL:6YK,GPN+O\%`%#MH0<`4>D#Z0,`
+M`#,`+6QH,"T\````/````(%1`0`@`J3G504``+DI"``!9FEL93$%`%"D@0<`
+M4>D#Z0,``"`@("`@("`@("`@("`@("`@("`@("`@("`@9FEL92`Q(&-O;G1E
+M;G1S"FAE;&QO"FAE;&QO"FAE;&QO"C,`+6QH,"U.````3@```(%1`0`@`M45
+M504``+T9"``!9FEL93(%`%"V@0<`4>D#Z0,``"`@("`@("`@("`@("`@("`@
+M("`@("`@("`@9FEL92`R(&-O;G1E;G1S"FAE;&QO"FAE;&QO"FAE;&QO"FAE
+M;&QO"FAE;&QO"FAE;&QO"C4`+6QH-2UW`@``Z00``&-,V4L@`H6/504``#-5
+M"@`!24Y35$%,3`4`4*2!!P!1Z0/I`P```FUK=XVV['"Z\`>$(6[`2-EZ5P&P
+M^!J*0MPV*IM]&^L37/)<Y+,0WC;RYN647;X'R_\P`E;2>[SD(6GCE`4$+,RA
+M<%QVYXC%'H1Q`I@_B\H/L@(+W3`0@5CY6X%Q%WW+@7<`8(F7=77U]%5YG?`;
+M3N&I:_6YWA$,3F@?:)>FZ!<!"?.:#C/:',\PG@>:WRP0:TH8%&:/A#VMNUUD
+M[D?+:#XK%3NMR(PSF4;V"^\X0/E3JMRQ46+7\I]S@7ZJNTX[ROSD+=\7\.O#
+MI:W._S>P-B(W4`=N<T/$OT+5];U>*!<4AM0Y$,P.0&OJER*:CF[S6/=2*T4J
+M8HB@[:HC'_0*&[=@,,G+98$J+TE>OL/*B^SJ]0B]?)</$8'E0P=449"^@OSR
+MN>C"QW6ESMD62-#L*]0YO*`ZHY784:YX:>BM^:'>,:IX.=Y*@<AI4WJ=YI(K
+M,Z!G:"X9/4YJ66'7;3VVX#;P[=4G_^M!V=GNAJ]F8GUHS88Q..[_L,.ETV6T
+MD]@*$H$G,/AURJWR/%VN2S0M1ROK^-$D4`#*A2GF2-&>R(+B)*BX24P/1>F-
+M3ODP9D/YS5^9M>8OQ5I-[<^F!_.C?H\HT:!I/ZJ3)U)Z,OC8+[-;X<MC-?,>
+MMPT`HQXE(XTV!J`/FOL'T?3:#:L@[2#Y$F`?BFKE-DN]]H>'CIJ-:^/JCO\T
+M.4`Z,BR&AN^@;&H.P/W[;;[KCY1@;[MRE6MWEA0[SS@BW-=BZ;/992/*144"
+ME)9-=H3.#8,!KW4;K#^:HP[15TP>C!ZQL--2)IGK);'D<;J"O7.2A_4X'"IW
+MB(_W\=@I^.U+$T\Q/F2:*5OSDV<GO^8U0``FP"UL:&0M````````````2"+L
+M$``$9&ER7```50"!40$`Z$'I`^D#)_@M;&AD+0```````````$@B[!``!61I
+M<C)<``!5`(%1`0#M0>D#Z0,X?"UL:&0M```````````!2"/L$``69&ER,EQS
+M>6UL:6YK,7PN+EQF:6QE,0``50`"HP(`[:'I`^D#.'XM;&AD+0``````````
+M`4@C[!``%F1I<C)<<WEM;&EN:S)\+BY<9FEL93(``%4``J,"`.VAZ0/I`R>]
+M+6QH-2TB````/`````!((NP@``5F:6QE,:3G50"!40$`I('I`^D#`!A";FG%
+MX_H!TUH=YD4,+`6H'R.A`(^>40P[=::W.04K]2=!+6QH-2TB````3@````!(
+M(NP@``5F:6QE,M4550"!40$`MH'I`^D#`!A";FG'8_H!TYH<YD4,+`6HWPNA
+M`(\>40P[=::W.04K_0`9?RUL:&0M&@``````````2"+L(`$```!5!P`"9&ER
+M_P4`4.A!!P!1Z0/I`P<`5(%1`0```!F!+6QH9"T;``````````!((NP@`0``
+M`%4(``)D:7(R_P4`4.U!!P!1Z0/I`P<`5(%1`0```!YQ+6QH9"TG````````
+M``%((^P@`05F:6QE,0``510``F1I<C+_<WEM;&EN:S%\+B[_!0!0[:$'`%'I
+M`^D#!P!4`J,"````'G(M;&AD+2<``````````4@C["`!!69I;&4R``!5%``"
+M9&ER,O]S>6UL:6YK,GPN+O\%`%#MH0<`4>D#Z0,'`%0"HP(````>!BUL:#4M
+M-0```#P`````2"+L(`$%9FEL93&DYU4%`%"D@0<`4>D#Z0,'`%2!40$`````
+M&$)N:<7C^@'36AWF10PL!:@?(Z$`CYY1##MUIK<Y!2OU'G@M;&@U+34```!.
+M`````$@B["`!!69I;&4RU155!0!0MH$'`%'I`^D#!P!4@5$!`````!A";FG'
+M8_H!TYH<YD4,+`6HWPNA`(\>40P[=::W.04K_0`U`"UL:&0M``````````"!
+M40$`(`(``%4%```%W@,``0<``F1I<O\%`%#H00<`4>D#Z0,``#8`+6QH9"T`
+M`````````(%1`0`@`@``504```B9`P`!"``"9&ER,O\%`%#M00<`4>D#Z0,`
+M`$<`+6QH9"T```````````*C`@`@`@``504``+2I"``!9FEL93$4``)D:7(R
+M_W-Y;6QI;FLQ?"XN_P4`4.VA!P!1Z0/I`P``1P`M;&AD+0```````````J,"
+M`"`"``!5!0``A^T(``%F:6QE,A0``F1I<C+_<WEM;&EN:S)\+B[_!0!0[:$'
+M`%'I`^D#```S`"UL:#4M(@```#P```"!40$`(`*DYU4%``#]`0@``69I;&4Q
+M!0!0I($'`%'I`^D#````&$)N:<7C^@'36AWF10PL!:@?(Z$`CYY1##MUIK<Y
+M!2OU,P`M;&@U+2(```!.````@5$!`"`"U155!0``+\8(``%F:6QE,@4`4+:!
+M!P!1Z0/I`P```!A";FG'8_H!TYH<YD4,+`6HWPNA`(\>40P[=::W.04K_0`$
+M`"UL:&0M``````````"!40$`(`,``$U\````"0```$:D`P``!0````$)````
+M`F1I<O\'````0!``&0```/_M00`````````````,%?Y,1!K^3!T```!!S-]1
+MM/Z5RP&`UD``J+*=`0!Z#]`!ELL!"``````NKP<`````!``M;&AD+0``````
+M````@5$!`"`#``!-?0````D```!&I`,```4````!"@````)D:7(R_P<```!`
+M$``9````_^U!`````````````"$:_DQ$&OY,'0```$%*@6Z[`9;+`8#60`"H
+MLIT!`'H/T`&6RP$(`````'T7!P`````$`"UL:#4M)````#P```"!40$`(`.D
+MYTUQ````"0```$:D`P``"@````%F:6QE,1D```#_I($`````````````QQ3^
+M3",:_DP=````031"HHK^E<L!@-9``*BRG0'^<J2\`9;+`0@`````"O$'````
+M```90FV1J+1V@'IK0ZGID/-H#J@6.H0"'V^-&353:F^XA-UZ@`0`+6QH-2TD
+M````3@```(%1`0`@`]4537$````)````1J0#```*`````69I;&4R&0```/^D
+M@0`````````````A&OY,(QK^3!T```!!_D5SNP&6RP&`UD``J+*=`5C5IKP!
+MELL!"`````!!W@<``````!E";9&H[':`>G-#B>F0\V@.J,8:A`(>;XT9-5-J
+M;[B$W7Z``#4`+6QH9"T``````````(%1`0`@`@``504```7>`P`!!P`"9&ER
+M_P4`4.A!!P!1Z0/I`P``-@`M;&AD+0``````````@5$!`"`"``!5!0``")D#
+M``$(``)D:7(R_P4`4.U!!P!1Z0/I`P``1P`M;&AD+0```````````J,"`"`"
+M``!5!0``M*D(``%F:6QE,10``F1I<C+_<WEM;&EN:S%\+B[_!0!0[:$'`%'I
+M`^D#``!'`"UL:&0M```````````"HP(`(`(``%4%``"'[0@``69I;&4R%``"
+M9&ER,O]S>6UL:6YK,GPN+O\%`%#MH0<`4>D#Z0,``#,`+6QH,"T\````/```
+M`(%1`0`@`J3G504``+DI"``!9FEL93$%`%"D@0<`4>D#Z0,``"`@("`@("`@
+M("`@("`@("`@("`@("`@("`@9FEL92`Q(&-O;G1E;G1S"FAE;&QO"FAE;&QO
+M"FAE;&QO"C,`+6QH,"U.````3@```(%1`0`@`M45504``+T9"``!9FEL93(%
+M`%"V@0<`4>D#Z0,``"`@("`@("`@("`@("`@("`@("`@("`@("`@9FEL92`R
+M(&-O;G1E;G1S"FAE;&QO"FAE;&QO"FAE;&QO"FAE;&QO"FAE;&QO"FAE;&QO
+M"@`U`"UL:&0M``````````"!40$`(`(``%4%```%W@,``0<``F1I<O\%`%#H
+M00<`4>D#Z0,``#8`+6QH9"T``````````(%1`0`@`@``504```B9`P`!"``"
+M9&ER,O\%`%#M00<`4>D#Z0,``$<`+6QH9"T```````````*C`@`@`@``504`
+M`+2I"``!9FEL93$4``)D:7(R_W-Y;6QI;FLQ?"XN_P4`4.VA!P!1Z0/I`P``
+M1P`M;&AD+0```````````J,"`"`"``!5!0``A^T(``%F:6QE,A0``F1I<C+_
+M<WEM;&EN:S)\+B[_!0!0[:$'`%'I`^D#```S`"UL:#8M(P```#P```"!40$`
+M(`*DYU4%``"-)0@``69I;&4Q!0!0I($'`%'I`^D#````&$)N:<7C^@'36AWF
+M10PL!:@?(Y"`1\\HAAVZTUN<@I7Z@#,`+6QH-BTC````3@```(%1`0`@`M45
+M504``%_B"``!9FEL93(%`%"V@0<`4>D#Z0,````80FYIQV/Z`=.:'.9%#"P%
+MJ-\+D(!'CRB&';K36YR"E?Z``#4`+6QH9"T``````````(%1`0`@`@``504`
+M``7>`P`!!P`"9&ER_P4`4.A!!P!1Z0/I`P``-@`M;&AD+0``````````@5$!
+M`"`"``!5!0``")D#``$(``)D:7(R_P4`4.U!!P!1Z0/I`P``1P`M;&AD+0``
+M`````````J,"`"`"``!5!0``M*D(``%F:6QE,10``F1I<C+_<WEM;&EN:S%\
+M+B[_!0!0[:$'`%'I`^D#``!'`"UL:&0M```````````"HP(`(`(``%4%``"'
+M[0@``69I;&4R%``"9&ER,O]S>6UL:6YK,GPN+O\%`%#MH0<`4>D#Z0,``#,`
+M+6QH-RTC````/````(%1`0`@`J3G504``!R)"``!9FEL93$%`%"D@0<`4>D#
+MZ0,````80FYIQ>/Z`=-:'>9%#"P%J!\CD(!'SRB&';K36YR"E?J`,P`M;&@W
+M+2,```!.````@5$!`"`"U155!0``SDX(``%F:6QE,@4`4+:!!P!1Z0/I`P``
+M`!A";FG'8_H!TYH<YD4,+`6HWPN0@$>/*(8=NM-;G(*5_H``-0`M;&@U+7<"
+M``#I!```8TS92R`"A8]5!0``,U4*``%)3E-404Q,!0!0I($'`%'I`^D#```"
+M;6MWC;;L<+KP!X0A;L!(V7I7`;#X&HI"W#8JFWT;ZQ-<\ESDLQ#>-O+FY91=
+MO@?+_S`"5M)[O.0A:>.4!00LS*%P7';GB,4>A'$"F#^+R@^R`@O=,!"!6/E;
+M@7$7?<N!=P!@B9=U=?7T57F=\!M.X:EK];G>$0Q.:!]HEZ;H%P$)\YH.,]H<
+MSS">!YK?+!!K2A@49H^$/:V[763N1\MH/BL5.ZW(C#.91O8+[SA`^5.JW+%1
+M8M?RGW.!?JJ[3CO*_.0MWQ?PZ\.EK<[_-[`V(C=0!VYS0\2_0M7UO5XH%Q2&
+MU#D0S`Y`:^J7(IJ.;O-8]U(K12IBB*#MJB,?]`H;MV`PR<ME@2HO25Z^P\J+
+M[.KU"+U\EP\1@>5#!U11D+Z"_/*YZ,+'=:7.V19(T.PKU#F\H#JCE=A1KGAI
+MZ*WYH=XQJG@YWDJ!R&E3>IWFDBLSH&=H+AD]3FI98==M/;;@-O#MU2?_ZT'9
+MV>Z&KV9B?6C-AC$X[O^PPZ739;23V`H2@2<P^'7*K?(\7:Y+-"U'*^OXT210
+M`,J%*>9(T9[(@N(DJ+A)3`]%Z8U.^3!F0_G-7YFUYB_%6DWMSZ8'\Z-^CRC1
+MH&D_JI,G4GHR^-@OLUOARV,U\QZW#0"C'B4CC38&H`^:^P?1]-H-JR#M(/D2
+M8!^*:N4V2[WVAX>.FHUKX^J._S0Y0#HR+(:&[Z!L:@[`_?MMONN/E&!ONW*5
+M:W>6%#O/."+<UV+IL]EE(\I%10*4EDUVA,X-@P&O=1NL/YJC#M%73!Z,'K&P
+MTU(FF>LEL>1QNH*]<Y*']3@<*G>(C_?QV"GX[4L33S$^9)HI6_.39R>_YC5`
+!````
+`
+end
diff --git a/libarchive/test/test_gnutar_filename_encoding.c b/libarchive/test/test_gnutar_filename_encoding.c
new file mode 100644
index 000000000000..b22ea407374a
--- /dev/null
+++ b/libarchive/test/test_gnutar_filename_encoding.c
@@ -0,0 +1,414 @@
+/*-
+ * Copyright (c) 2011 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+#include <locale.h>
+
+static void
+test_gnutar_filename_encoding_UTF8_CP866(void)
+{
+ struct archive *a;
+ struct archive_entry *entry;
+ char buff[4096];
+ size_t used;
+
+ if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
+ skipping("en_US.UTF-8 locale not available on this system.");
+ return;
+ }
+
+ /*
+ * Verify that UTF-8 filenames are correctly translated into CP866
+ * and stored with hdrcharset=CP866 option.
+ */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_gnutar(a));
+ if (archive_write_set_options(a, "hdrcharset=CP866") != ARCHIVE_OK) {
+ skipping("This system cannot convert character-set"
+ " from UTF-8 to CP866.");
+ archive_write_free(a);
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set a UTF-8 filename. */
+ archive_entry_set_pathname(entry, "\xD0\xBF\xD1\x80\xD0\xB8");
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* Above three characters in UTF-8 should translate to the following
+ * three characters in CP866. */
+ assertEqualMem(buff, "\xAF\xE0\xA8", 3);
+}
+
+static void
+test_gnutar_filename_encoding_KOI8R_UTF8(void)
+{
+ struct archive *a;
+ struct archive_entry *entry;
+ char buff[4096];
+ size_t used;
+
+ if (NULL == setlocale(LC_ALL, "ru_RU.KOI8-R")) {
+ skipping("KOI8-R locale not available on this system.");
+ return;
+ }
+
+ /*
+ * Verify that KOI8-R filenames are correctly translated into UTF-8
+ * and stored with hdrcharset=UTF-8 option.
+ */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_gnutar(a));
+ if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) {
+ skipping("This system cannot convert character-set"
+ " from KOI8-R to UTF-8.");
+ archive_write_free(a);
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set a KOI8-R filename. */
+ archive_entry_set_pathname(entry, "\xD0\xD2\xC9");
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* Above three characters in KOI8-R should translate to the following
+ * three characters (two bytes each) in UTF-8. */
+ assertEqualMem(buff, "\xD0\xBF\xD1\x80\xD0\xB8", 6);
+}
+
+static void
+test_gnutar_filename_encoding_KOI8R_CP866(void)
+{
+ struct archive *a;
+ struct archive_entry *entry;
+ char buff[4096];
+ size_t used;
+
+ if (NULL == setlocale(LC_ALL, "ru_RU.KOI8-R")) {
+ skipping("KOI8-R locale not available on this system.");
+ return;
+ }
+
+ /*
+ * Verify that KOI8-R filenames are correctly translated into CP866
+ * and stored with hdrcharset=CP866 option.
+ */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_gnutar(a));
+ if (archive_write_set_options(a, "hdrcharset=CP866") != ARCHIVE_OK) {
+ skipping("This system cannot convert character-set"
+ " from KOI8-R to CP866.");
+ archive_write_free(a);
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set a KOI8-R filename. */
+ archive_entry_set_pathname(entry, "\xD0\xD2\xC9");
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* Above three characters in KOI8-R should translate to the following
+ * three characters in CP866. */
+ assertEqualMem(buff, "\xAF\xE0\xA8", 3);
+}
+
+static void
+test_gnutar_filename_encoding_CP1251_UTF8(void)
+{
+ struct archive *a;
+ struct archive_entry *entry;
+ char buff[4096];
+ size_t used;
+
+ if (NULL == setlocale(LC_ALL, "Russian_Russia") &&
+ NULL == setlocale(LC_ALL, "ru_RU.CP1251")) {
+ skipping("KOI8-R locale not available on this system.");
+ return;
+ }
+
+ /*
+ * Verify that CP1251 filenames are correctly translated into UTF-8
+ * and stored with hdrcharset=UTF-8 option.
+ */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_gnutar(a));
+ if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) {
+ skipping("This system cannot convert character-set"
+ " from KOI8-R to UTF-8.");
+ archive_write_free(a);
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set a KOI8-R filename. */
+ archive_entry_set_pathname(entry, "\xEF\xF0\xE8");
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* Above three characters in CP1251 should translate to the following
+ * three characters (two bytes each) in UTF-8. */
+ assertEqualMem(buff, "\xD0\xBF\xD1\x80\xD0\xB8", 6);
+}
+
+/*
+ * Do not translate CP1251 into CP866 if non Windows platform.
+ */
+static void
+test_gnutar_filename_encoding_ru_RU_CP1251(void)
+{
+ struct archive *a;
+ struct archive_entry *entry;
+ char buff[4096];
+ size_t used;
+
+ if (NULL == setlocale(LC_ALL, "ru_RU.CP1251")) {
+ skipping("KOI8-R locale not available on this system.");
+ return;
+ }
+
+ /*
+ * Verify that CP1251 filenames are not translated into any
+ * other character-set, in particular, CP866.
+ */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_gnutar(a));
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set a KOI8-R filename. */
+ archive_entry_set_pathname(entry, "\xEF\xF0\xE8");
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* Above three characters in CP1251 should not translate to
+ * any other character-set. */
+ assertEqualMem(buff, "\xEF\xF0\xE8", 3);
+}
+
+/*
+ * Other archiver applications on Windows translate CP1251 filenames
+ * into CP866 filenames and store it in the gnutar file.
+ * Test above behavior works well.
+ */
+static void
+test_gnutar_filename_encoding_Russian_Russia(void)
+{
+ struct archive *a;
+ struct archive_entry *entry;
+ char buff[4096];
+ size_t used;
+
+ if (NULL == setlocale(LC_ALL, "Russian_Russia")) {
+ skipping("Russian_Russia locale not available on this system.");
+ return;
+ }
+
+ /*
+ * Verify that Russian_Russia(CP1251) filenames are correctly translated
+ * to CP866.
+ */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_gnutar(a));
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set a CP1251 filename. */
+ archive_entry_set_pathname(entry, "\xEF\xF0\xE8");
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* Above three characters in CP1251 should translate to the following
+ * three characters in CP866. */
+ assertEqualMem(buff, "\xAF\xE0\xA8", 3);
+}
+
+static void
+test_gnutar_filename_encoding_EUCJP_UTF8(void)
+{
+ struct archive *a;
+ struct archive_entry *entry;
+ char buff[4096];
+ size_t used;
+
+ if (NULL == setlocale(LC_ALL, "ja_JP.eucJP")) {
+ skipping("eucJP locale not available on this system.");
+ return;
+ }
+
+ /*
+ * Verify that EUC-JP filenames are correctly translated to UTF-8.
+ */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_gnutar(a));
+ if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) {
+ skipping("This system cannot convert character-set"
+ " from eucJP to UTF-8.");
+ archive_write_free(a);
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set an EUC-JP filename. */
+ archive_entry_set_pathname(entry, "\xC9\xBD.txt");
+ /* Check the Unicode version. */
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* Check UTF-8 version. */
+ assertEqualMem(buff, "\xE8\xA1\xA8.txt", 7);
+}
+
+static void
+test_gnutar_filename_encoding_EUCJP_CP932(void)
+{
+ struct archive *a;
+ struct archive_entry *entry;
+ char buff[4096];
+ size_t used;
+
+ if (NULL == setlocale(LC_ALL, "ja_JP.eucJP")) {
+ skipping("eucJP locale not available on this system.");
+ return;
+ }
+
+ /*
+ * Verify that EUC-JP filenames are correctly translated to CP932.
+ */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_gnutar(a));
+ if (archive_write_set_options(a, "hdrcharset=CP932") != ARCHIVE_OK) {
+ skipping("This system cannot convert character-set"
+ " from eucJP to CP932.");
+ archive_write_free(a);
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set an EUC-JP filename. */
+ archive_entry_set_pathname(entry, "\xC9\xBD.txt");
+ /* Check the Unicode version. */
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* Check CP932 version. */
+ assertEqualMem(buff, "\x95\x5C.txt", 6);
+}
+
+static void
+test_gnutar_filename_encoding_CP932_UTF8(void)
+{
+ struct archive *a;
+ struct archive_entry *entry;
+ char buff[4096];
+ size_t used;
+
+ if (NULL == setlocale(LC_ALL, "Japanese_Japan") &&
+ NULL == setlocale(LC_ALL, "ja_JP.SJIS")) {
+ skipping("CP932/SJIS locale not available on this system.");
+ return;
+ }
+
+ /*
+ * Verify that CP932/SJIS filenames are correctly translated to UTF-8.
+ */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_gnutar(a));
+ if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) {
+ skipping("This system cannot convert character-set"
+ " from CP932/SJIS to UTF-8.");
+ archive_write_free(a);
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set an CP932/SJIS filename. */
+ archive_entry_set_pathname(entry, "\x95\x5C.txt");
+ /* Check the Unicode version. */
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* Check UTF-8 version. */
+ assertEqualMem(buff, "\xE8\xA1\xA8.txt", 7);
+}
+
+DEFINE_TEST(test_gnutar_filename_encoding)
+{
+ test_gnutar_filename_encoding_UTF8_CP866();
+ test_gnutar_filename_encoding_KOI8R_UTF8();
+ test_gnutar_filename_encoding_KOI8R_CP866();
+ test_gnutar_filename_encoding_CP1251_UTF8();
+ test_gnutar_filename_encoding_ru_RU_CP1251();
+ test_gnutar_filename_encoding_Russian_Russia();
+ test_gnutar_filename_encoding_EUCJP_UTF8();
+ test_gnutar_filename_encoding_EUCJP_CP932();
+ test_gnutar_filename_encoding_CP932_UTF8();
+}
diff --git a/libarchive/test/test_open_failure.c b/libarchive/test/test_open_failure.c
index 0a7632a8ad69..06a3a2c1fa35 100644
--- a/libarchive/test/test_open_failure.c
+++ b/libarchive/test/test_open_failure.c
@@ -42,6 +42,8 @@ static ssize_t
my_read(struct archive *a, void *_private, const void **buff)
{
struct my_data *private = (struct my_data *)_private;
+ (void)a; /* UNUSED */
+ (void)buff; /* UNUSED */
assertEqualInt(MAGIC, private->magic);
++private->read_called;
return (private->read_return);
@@ -51,6 +53,9 @@ static ssize_t
my_write(struct archive *a, void *_private, const void *buff, size_t s)
{
struct my_data *private = (struct my_data *)_private;
+ (void)a; /* UNUSED */
+ (void)buff; /* UNUSED */
+ (void)s; /* UNUSED */
assertEqualInt(MAGIC, private->magic);
++private->write_called;
return (private->write_return);
@@ -60,6 +65,7 @@ static int
my_open(struct archive *a, void *_private)
{
struct my_data *private = (struct my_data *)_private;
+ (void)a; /* UNUSED */
assertEqualInt(MAGIC, private->magic);
++private->open_called;
return (private->open_return);
@@ -69,6 +75,7 @@ static int
my_close(struct archive *a, void *_private)
{
struct my_data *private = (struct my_data *)_private;
+ (void)a; /* UNUSED */
assertEqualInt(MAGIC, private->magic);
++private->close_called;
return (private->close_return);
@@ -132,7 +139,7 @@ DEFINE_TEST(test_open_failure)
a = archive_read_new();
assert(a != NULL);
assertEqualInt(ARCHIVE_OK,
- archive_read_support_compression_compress(a));
+ archive_read_support_filter_compress(a));
assertEqualInt(ARCHIVE_OK, archive_read_support_format_tar(a));
assertEqualInt(ARCHIVE_FATAL,
archive_read_open(a, &private, my_open, my_read, my_close));
@@ -153,8 +160,24 @@ DEFINE_TEST(test_open_failure)
archive_write_open(a, &private, my_open, my_write, my_close));
assertEqualInt(1, private.open_called);
assertEqualInt(0, private.write_called);
- // Broken in 2.8, fixed in 3.0
- //assertEqualInt(1, private.close_called);
+ assertEqualInt(1, private.close_called);
+ assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
+ assertEqualInt(1, private.open_called);
+ assertEqualInt(0, private.write_called);
+ assertEqualInt(1, private.close_called);
+
+ memset(&private, 0, sizeof(private));
+ private.magic = MAGIC;
+ private.open_return = ARCHIVE_FATAL;
+ a = archive_write_new();
+ assert(a != NULL);
+ archive_write_add_filter_compress(a);
+ archive_write_set_format_ustar(a);
+ assertEqualInt(ARCHIVE_FATAL,
+ archive_write_open(a, &private, my_open, my_write, my_close));
+ assertEqualInt(1, private.open_called);
+ assertEqualInt(0, private.write_called);
+ assertEqualInt(1, private.close_called);
assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
assertEqualInt(1, private.open_called);
assertEqualInt(0, private.write_called);
@@ -165,14 +188,12 @@ DEFINE_TEST(test_open_failure)
private.open_return = ARCHIVE_FATAL;
a = archive_write_new();
assert(a != NULL);
- archive_write_set_compression_compress(a);
archive_write_set_format_zip(a);
assertEqualInt(ARCHIVE_FATAL,
archive_write_open(a, &private, my_open, my_write, my_close));
assertEqualInt(1, private.open_called);
assertEqualInt(0, private.write_called);
- // Broken in 2.8, fixed in 3.0
- //assertEqualInt(1, private.close_called);
+ assertEqualInt(1, private.close_called);
assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
assertEqualInt(1, private.open_called);
assertEqualInt(0, private.write_called);
@@ -183,13 +204,12 @@ DEFINE_TEST(test_open_failure)
private.open_return = ARCHIVE_FATAL;
a = archive_write_new();
assert(a != NULL);
- archive_write_set_compression_gzip(a);
+ archive_write_add_filter_gzip(a);
assertEqualInt(ARCHIVE_FATAL,
archive_write_open(a, &private, my_open, my_write, my_close));
assertEqualInt(1, private.open_called);
assertEqualInt(0, private.write_called);
- // Broken in 2.8, fixed in 3.0
- //assertEqualInt(1, private.close_called);
+ assertEqualInt(1, private.close_called);
assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
assertEqualInt(1, private.open_called);
assertEqualInt(0, private.write_called);
diff --git a/libarchive/test/test_open_fd.c b/libarchive/test/test_open_fd.c
index 5e118ad8f43b..52b34bd125f7 100644
--- a/libarchive/test/test_open_fd.c
+++ b/libarchive/test/test_open_fd.c
@@ -79,7 +79,7 @@ DEFINE_TEST(test_open_fd)
/* Close out the archive. */
assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
- assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/*
* Now, read the data back.
@@ -87,7 +87,7 @@ DEFINE_TEST(test_open_fd)
assert(lseek(fd, 0, SEEK_SET) == 0);
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
- assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_fd(a, fd, 512));
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
@@ -110,7 +110,7 @@ DEFINE_TEST(test_open_fd)
/* Verify the end of the archive. */
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
close(fd);
@@ -119,10 +119,10 @@ DEFINE_TEST(test_open_fd)
*/
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
- assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
/* FD 100 shouldn't be open. */
assertEqualIntA(a, ARCHIVE_FATAL,
archive_read_open_fd(a, 100, 512));
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_open_file.c b/libarchive/test/test_open_file.c
index 871249d87292..4308f024344b 100644
--- a/libarchive/test/test_open_file.c
+++ b/libarchive/test/test_open_file.c
@@ -67,7 +67,7 @@ DEFINE_TEST(test_open_file)
/* Close out the archive. */
assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
- assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
fclose(f);
/*
@@ -79,7 +79,7 @@ DEFINE_TEST(test_open_file)
return;
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
- assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_FILE(a, f));
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
@@ -102,7 +102,7 @@ DEFINE_TEST(test_open_file)
/* Verify the end of the archive. */
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
fclose(f);
}
diff --git a/libarchive/test/test_open_filename.c b/libarchive/test/test_open_filename.c
index 07224cde135d..15646b86162b 100644
--- a/libarchive/test/test_open_filename.c
+++ b/libarchive/test/test_open_filename.c
@@ -25,7 +25,8 @@
#include "test.h"
__FBSDID("$FreeBSD: head/lib/libarchive/test/test_open_filename.c 191183 2009-04-17 01:06:31Z kientzle $");
-DEFINE_TEST(test_open_filename)
+static void
+test_open_filename_mbs(void)
{
char buff[64];
struct archive_entry *ae;
@@ -62,14 +63,14 @@ DEFINE_TEST(test_open_filename)
/* Close out the archive. */
assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
- assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/*
* Now, read the data back.
*/
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
- assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_open_filename(a, "test.tar", 512));
@@ -93,17 +94,107 @@ DEFINE_TEST(test_open_filename)
/* Verify the end of the archive. */
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
/*
* Verify some of the error handling.
*/
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
- assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_FATAL,
archive_read_open_filename(a, "nonexistent.tar", 512));
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+}
+
+static void
+test_open_filename_wcs(void)
+{
+ char buff[64];
+ struct archive_entry *ae;
+ struct archive *a;
+
+ /* Write an archive through this FILE *. */
+ assert((a = archive_write_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_none(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_open_filename_w(a, L"test.tar"));
+
+ /*
+ * Write a file to it.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_mtime(ae, 1, 0);
+ archive_entry_copy_pathname_w(ae, L"file");
+ archive_entry_set_mode(ae, S_IFREG | 0755);
+ archive_entry_set_size(ae, 8);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9));
+ /*
+ * Write a second file to it.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_copy_pathname_w(ae, L"file2");
+ archive_entry_set_mode(ae, S_IFREG | 0755);
+ archive_entry_set_size(ae, 819200);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+
+ /* Close out the archive. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /*
+ * Now, read the data back.
+ */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename_w(a, L"test.tar", 512));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(1, archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_mtime_nsec(ae));
+ assertEqualInt(0, archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_ctime(ae));
+ assertEqualWString(L"file", archive_entry_pathname_w(ae));
+ assert((S_IFREG | 0755) == archive_entry_mode(ae));
+ assertEqualInt(8, archive_entry_size(ae));
+ assertEqualIntA(a, 8, archive_read_data(a, buff, 10));
+ assertEqualMem(buff, "12345678", 8);
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualWString(L"file2", archive_entry_pathname_w(ae));
+ assert((S_IFREG | 0755) == archive_entry_mode(ae));
+ assertEqualInt(819200, archive_entry_size(ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a));
+
+ /* Verify the end of the archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+ /*
+ * Verify some of the error handling.
+ */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_FATAL,
+ archive_read_open_filename_w(a, L"nonexistent.tar", 512));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+}
+
+DEFINE_TEST(test_open_filename)
+{
+ test_open_filename_mbs();
+ test_open_filename_wcs();
}
diff --git a/libarchive/test/test_pax_filename_encoding.c b/libarchive/test/test_pax_filename_encoding.c
index 5f1ac935c1ec..3a28e2f7dda2 100644
--- a/libarchive/test/test_pax_filename_encoding.c
+++ b/libarchive/test/test_pax_filename_encoding.c
@@ -58,7 +58,7 @@ test_pax_filename_encoding_1(void)
extract_reference_file(testname);
a = archive_read_new();
assertEqualInt(ARCHIVE_OK, archive_read_support_format_tar(a));
- assertEqualInt(ARCHIVE_OK, archive_read_support_compression_all(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_support_filter_all(a));
assertEqualInt(ARCHIVE_OK,
archive_read_open_filename(a, testname, 10240));
/*
@@ -77,7 +77,7 @@ test_pax_filename_encoding_1(void)
" characters in it without generating a warning");
assertEqualInt(ARCHIVE_OK, archive_read_next_header(a, &entry));
assertEqualString(filename, archive_entry_pathname(entry));
- archive_read_finish(a);
+ archive_read_free(a);
}
/*
@@ -104,13 +104,12 @@ test_pax_filename_encoding_2(void)
/*
* We need a starting locale which has invalid sequences.
- * de_DE.UTF-8 seems to be commonly supported.
+ * en_US.UTF-8 seems to be commonly supported.
*/
/* If it doesn't exist, just warn and return. */
- if (LOCALE_UTF8 == NULL
- || NULL == setlocale(LC_ALL, LOCALE_UTF8)) {
+ if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
skipping("invalid encoding tests require a suitable locale;"
- " %s not available on this system", LOCALE_UTF8);
+ " en_US.UTF-8 not available on this system");
return;
}
@@ -151,8 +150,8 @@ test_pax_filename_encoding_2(void)
assertEqualInt(ARCHIVE_WARN, archive_write_header(a, entry));
archive_entry_free(entry);
- assertEqualInt(0, archive_write_close(a));
- assertEqualInt(0, archive_write_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/*
* Now read the entries back.
@@ -177,10 +176,12 @@ test_pax_filename_encoding_2(void)
assertEqualInt(0, archive_read_next_header(a, &entry));
assertEqualString(longname, archive_entry_pathname(entry));
- assertEqualInt(0, archive_read_close(a));
- assertEqualInt(0, archive_read_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
+#if 0 /* Disable this until Tim check out it. */
+
/*
* Create an entry starting from a wide-character Unicode pathname,
* read it back into "C" locale, which doesn't support the name.
@@ -277,8 +278,8 @@ test_pax_filename_encoding_3(void)
assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
archive_entry_free(entry);
- assertEqualInt(0, archive_write_close(a));
- assertEqualInt(0, archive_write_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/*
* Now read the entries back.
@@ -321,13 +322,280 @@ test_pax_filename_encoding_3(void)
assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &entry));
- assertEqualInt(0, archive_read_close(a));
- assertEqualInt(0, archive_read_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+#else
+static void
+test_pax_filename_encoding_3(void)
+{
}
+#endif
+
+/*
+ * Verify that KOI8-R filenames are correctly translated to Unicode and UTF-8.
+ */
+static void
+test_pax_filename_encoding_KOI8R(void)
+{
+ struct archive *a;
+ struct archive_entry *entry;
+ char buff[4096];
+ size_t used;
+
+ if (NULL == setlocale(LC_ALL, "ru_RU.KOI8-R")) {
+ skipping("KOI8-R locale not available on this system.");
+ return;
+ }
+
+ /* Check if the paltform completely supports the string conversion. */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_pax(a));
+ if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) {
+ skipping("This system cannot convert character-set"
+ " from KOI8-R to UTF-8.");
+ archive_write_free(a);
+ return;
+ }
+ archive_write_free(a);
+
+ /* Re-create a write archive object since filenames should be written
+ * in UTF-8 by default. */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_pax(a));
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ archive_entry_set_pathname(entry, "\xD0\xD2\xC9");
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* Above three characters in KOI8-R should translate to the following
+ * three characters (two bytes each) in UTF-8. */
+ assertEqualMem(buff + 512, "15 path=\xD0\xBF\xD1\x80\xD0\xB8\x0A", 15);
+}
+
+/*
+ * Verify that CP1251 filenames are correctly translated to Unicode and UTF-8.
+ */
+static void
+test_pax_filename_encoding_CP1251(void)
+{
+ struct archive *a;
+ struct archive_entry *entry;
+ char buff[4096];
+ size_t used;
+
+ if (NULL == setlocale(LC_ALL, "Russian_Russia") &&
+ NULL == setlocale(LC_ALL, "ru_RU.CP1251")) {
+ skipping("KOI8-R locale not available on this system.");
+ return;
+ }
+
+ /* Check if the paltform completely supports the string conversion. */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_pax(a));
+ if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) {
+ skipping("This system cannot convert character-set"
+ " from KOI8-R to UTF-8.");
+ archive_write_free(a);
+ return;
+ }
+ archive_write_free(a);
+
+ /* Re-create a write archive object since filenames should be written
+ * in UTF-8 by default. */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_pax(a));
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ archive_entry_set_pathname(entry, "\xef\xf0\xe8");
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* Above three characters in KOI8-R should translate to the following
+ * three characters (two bytes each) in UTF-8. */
+ assertEqualMem(buff + 512, "15 path=\xD0\xBF\xD1\x80\xD0\xB8\x0A", 15);
+}
+
+/*
+ * Verify that EUC-JP filenames are correctly translated to Unicode and UTF-8.
+ */
+static void
+test_pax_filename_encoding_EUCJP(void)
+{
+ struct archive *a;
+ struct archive_entry *entry;
+ char buff[4096];
+ size_t used;
+
+ if (NULL == setlocale(LC_ALL, "ja_JP.eucJP")) {
+ skipping("eucJP locale not available on this system.");
+ return;
+ }
+
+ /* Check if the paltform completely supports the string conversion. */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_pax(a));
+ if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) {
+ skipping("This system cannot convert character-set"
+ " from eucJP to UTF-8.");
+ archive_write_free(a);
+ return;
+ }
+ archive_write_free(a);
+
+ /* Re-create a write archive object since filenames should be written
+ * in UTF-8 by default. */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_pax(a));
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ archive_entry_set_pathname(entry, "\xC9\xBD.txt");
+ /* Check the Unicode version. */
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* Check UTF-8 version. */
+ assertEqualMem(buff + 512, "16 path=\xE8\xA1\xA8.txt\x0A", 16);
+
+}
+
+/*
+ * Verify that CP932/SJIS filenames are correctly translated to Unicode and UTF-8.
+ */
+static void
+test_pax_filename_encoding_CP932(void)
+{
+ struct archive *a;
+ struct archive_entry *entry;
+ char buff[4096];
+ size_t used;
+
+ if (NULL == setlocale(LC_ALL, "Japanese_Japan") &&
+ NULL == setlocale(LC_ALL, "ja_JP.SJIS")) {
+ skipping("eucJP locale not available on this system.");
+ return;
+ }
+
+ /* Check if the paltform completely supports the string conversion. */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_pax(a));
+ if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) {
+ skipping("This system cannot convert character-set"
+ " from CP932/SJIS to UTF-8.");
+ archive_write_free(a);
+ return;
+ }
+ archive_write_free(a);
+
+ /* Re-create a write archive object since filenames should be written
+ * in UTF-8 by default. */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_pax(a));
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ archive_entry_set_pathname(entry, "\x95\x5C.txt");
+ /* Check the Unicode version. */
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* Check UTF-8 version. */
+ assertEqualMem(buff + 512, "16 path=\xE8\xA1\xA8.txt\x0A", 16);
+
+}
+
+/*
+ * Verify that KOI8-R filenames are not translated to Unicode and UTF-8
+ * when using hdrcharset=BINARY option.
+ */
+static void
+test_pax_filename_encoding_KOI8R_BINARY(void)
+{
+ struct archive *a;
+ struct archive_entry *entry;
+ char buff[4096];
+ size_t used;
+
+ if (NULL == setlocale(LC_ALL, "ru_RU.KOI8-R")) {
+ skipping("KOI8-R locale not available on this system.");
+ return;
+ }
+
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_pax(a));
+ /* BINARY mode should be accepted. */
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_set_options(a, "hdrcharset=BINARY"));
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ archive_entry_set_pathname(entry, "\xD0\xD2\xC9");
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* "hdrcharset=BINARY" pax attribute should be written. */
+ assertEqualMem(buff + 512, "21 hdrcharset=BINARY\x0A", 21);
+ /* Above three characters in KOI8-R should not translate to any
+ * character-set. */
+ assertEqualMem(buff + 512+21, "12 path=\xD0\xD2\xC9\x0A", 12);
+}
+
+/*
+ * Pax format writer only accepts both BINARY and UTF-8.
+ * If other character-set name is specified, you will get ARCHIVE_FAILED.
+ */
+static void
+test_pax_filename_encoding_KOI8R_CP1251(void)
+{
+ struct archive *a;
+
+ if (NULL == setlocale(LC_ALL, "ru_RU.KOI8-R")) {
+ skipping("KOI8-R locale not available on this system.");
+ return;
+ }
+
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_pax(a));
+ /* pax format writer only accepts both BINARY and UTF-8. */
+ assertEqualInt(ARCHIVE_FAILED,
+ archive_write_set_options(a, "hdrcharset=CP1251"));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+}
+
DEFINE_TEST(test_pax_filename_encoding)
{
test_pax_filename_encoding_1();
test_pax_filename_encoding_2();
test_pax_filename_encoding_3();
+ test_pax_filename_encoding_KOI8R();
+ test_pax_filename_encoding_CP1251();
+ test_pax_filename_encoding_EUCJP();
+ test_pax_filename_encoding_CP932();
+ test_pax_filename_encoding_KOI8R_BINARY();
+ test_pax_filename_encoding_KOI8R_CP1251();
}
diff --git a/libarchive/test/test_read_compress_program.c b/libarchive/test/test_read_compress_program.c
index 4e6c610de253..751abd54fc91 100644
--- a/libarchive/test/test_read_compress_program.c
+++ b/libarchive/test/test_read_compress_program.c
@@ -43,9 +43,9 @@ DEFINE_TEST(test_read_compress_program)
* program is requested.
*/
assert((a = archive_read_new()) != NULL);
- r = archive_read_support_compression_program(a, "nonexistent");
+ r = archive_read_support_filter_program(a, "nonexistent");
if (r == ARCHIVE_FATAL) {
- skipping("archive_read_support_compression_program() "
+ skipping("archive_read_support_filter_program() "
"unsupported on this platform");
return;
}
@@ -55,7 +55,7 @@ DEFINE_TEST(test_read_compress_program)
assertEqualIntA(a, ARCHIVE_FATAL,
archive_read_open_memory(a, archive, sizeof(archive)));
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
/*
* If we have "gzip -d", try using that.
@@ -66,9 +66,9 @@ DEFINE_TEST(test_read_compress_program)
}
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK,
- archive_read_support_compression_none(a));
+ archive_read_support_filter_none(a));
assertEqualIntA(a, ARCHIVE_OK,
- archive_read_support_compression_program(a, "gunzip"));
+ archive_read_support_filter_program(a, "gunzip"));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK,
@@ -78,7 +78,7 @@ DEFINE_TEST(test_read_compress_program)
assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_PROGRAM);
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR);
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_read_data_large.c b/libarchive/test/test_read_data_large.c
index fe9120b59541..963ee95ef66f 100644
--- a/libarchive/test/test_read_data_large.c
+++ b/libarchive/test/test_read_data_large.c
@@ -72,34 +72,26 @@ DEFINE_TEST(test_read_data_large)
assertA((int)sizeof(buff2) == archive_write_data(a, buff2, sizeof(buff2)));
/* Close out the archive. */
- assertA(0 == archive_write_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_write_finish(a);
-#else
- assertA(0 == archive_write_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/* Check that archive_read_data can handle 10*10^6 at a pop. */
assert((a = archive_read_new()) != NULL);
assertA(0 == archive_read_support_format_all(a));
- assertA(0 == archive_read_support_compression_all(a));
+ assertA(0 == archive_read_support_filter_all(a));
assertA(0 == archive_read_open_memory(a, buff1, sizeof(buff1)));
assertA(0 == archive_read_next_header(a, &ae));
failure("Wrote 10MB, but didn't read the same amount");
assertEqualIntA(a, sizeof(buff2),archive_read_data(a, buff3, sizeof(buff3)));
failure("Read expected 10MB, but data read didn't match what was written");
- assert(0 == memcmp(buff2, buff3, sizeof(buff3)));
- assert(0 == archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assert(0 == archive_read_finish(a));
-#endif
+ assertEqualMem(buff2, buff3, sizeof(buff3));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
/* Check archive_read_data_into_fd */
assert((a = archive_read_new()) != NULL);
assertA(0 == archive_read_support_format_all(a));
- assertA(0 == archive_read_support_compression_all(a));
+ assertA(0 == archive_read_support_filter_all(a));
assertA(0 == archive_read_open_memory(a, buff1, sizeof(buff1)));
assertA(0 == archive_read_next_header(a, &ae));
#if defined(__BORLANDC__)
@@ -109,17 +101,13 @@ DEFINE_TEST(test_read_data_large)
#endif
assert(tmpfilefd != 0);
assertEqualIntA(a, 0, archive_read_data_into_fd(a, tmpfilefd));
- assert(0 == archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assert(0 == archive_read_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
close(tmpfilefd);
f = fopen(tmpfilename, "rb");
assert(f != NULL);
assertEqualInt(sizeof(buff3), fread(buff3, 1, sizeof(buff3), f));
fclose(f);
- assert(0 == memcmp(buff2, buff3, sizeof(buff3)));
+ assertEqualMem(buff2, buff3, sizeof(buff3));
}
diff --git a/libarchive/test/test_read_disk.c b/libarchive/test/test_read_disk.c
index d52659bb73b0..b69e55cfa292 100644
--- a/libarchive/test/test_read_disk.c
+++ b/libarchive/test/test_read_disk.c
@@ -34,7 +34,7 @@ gname_cleanup(void *d)
}
static const char *
-gname_lookup(void *d, gid_t g)
+gname_lookup(void *d, int64_t g)
{
int *mp = d;
assertEqualInt(*mp, 0x13579);
@@ -52,7 +52,7 @@ uname_cleanup(void *d)
}
static const char *
-uname_lookup(void *d, uid_t u)
+uname_lookup(void *d, int64_t u)
{
int *mp = d;
assertEqualInt(*mp, 0x1234);
@@ -164,7 +164,7 @@ DEFINE_TEST(test_read_disk)
&umagic, &uname_lookup, &uname_cleanup));
/* Destroy the archive. */
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
/* Verify our cleanup functions got called. */
assertEqualInt(gmagic, 0x2468);
diff --git a/libarchive/test/test_read_disk_directory_traversals.c b/libarchive/test/test_read_disk_directory_traversals.c
new file mode 100644
index 000000000000..6741ee1b48be
--- /dev/null
+++ b/libarchive/test/test_read_disk_directory_traversals.c
@@ -0,0 +1,1060 @@
+/*-
+ * Copyright (c) 2010 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+#include <limits.h>
+#if defined(_WIN32) && !defined(__CYGWIN__)
+# if !defined(__BORLANDC__)
+# define getcwd _getcwd
+# endif
+#endif
+
+/*
+ * Test if the current filesytem is mounted with noatime option.
+ */
+static int
+atimeIsUpdated(void)
+{
+ const char *fn = "fs_noatime";
+ struct stat st;
+
+ if (!assertMakeFile(fn, 0666, "a"))
+ return (0);
+ if (!assertUtimes(fn, 1, 0, 1, 0))
+ return (0);
+ /* Test the file contents in order to update its atime. */
+ if (!assertTextFileContents("a", fn))
+ return (0);
+ if (stat(fn, &st) != 0)
+ return (0);
+ /* Is atime updated? */
+ if (st.st_atime > 1)
+ return (1);
+ return (0);
+}
+
+static void
+test_basic(void)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+ const void *p;
+ char *initial_cwd, *cwd;
+ size_t size;
+ int64_t offset;
+ int file_count;
+
+ assertMakeDir("dir1", 0755);
+ assertMakeFile("dir1/file1", 0644, "0123456789");
+ assertMakeFile("dir1/file2", 0644, "hello world");
+ assertMakeDir("dir1/sub1", 0755);
+ assertMakeFile("dir1/sub1/file1", 0644, "0123456789");
+ assertMakeDir("dir1/sub2", 0755);
+ assertMakeFile("dir1/sub2/file1", 0644, "0123456789");
+ assertMakeFile("dir1/sub2/file2", 0644, "0123456789");
+ assertMakeDir("dir1/sub2/sub1", 0755);
+ assertMakeDir("dir1/sub2/sub2", 0755);
+ assertMakeDir("dir1/sub2/sub3", 0755);
+ assertMakeFile("dir1/sub2/sub3/file", 0644, "xyz");
+ file_count = 12;
+
+ assert((ae = archive_entry_new()) != NULL);
+ assert((a = archive_read_disk_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "dir1"));
+
+ while (file_count--) {
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
+ if (strcmp(archive_entry_pathname(ae), "dir1") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "dir1/file1") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 10);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 10);
+ assertEqualInt((int)offset, 0);
+ assertEqualMem(p, "0123456789", 10);
+ assertEqualInt(ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ assertEqualInt((int)offset, 10);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "dir1/file2") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 11);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 11);
+ assertEqualInt((int)offset, 0);
+ assertEqualMem(p, "hello world", 11);
+ assertEqualInt(ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ assertEqualInt((int)offset, 11);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "dir1/sub1") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "dir1/sub1/file1") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 10);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 10);
+ assertEqualInt((int)offset, 0);
+ assertEqualMem(p, "0123456789", 10);
+ assertEqualInt(ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ assertEqualInt((int)offset, 10);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "dir1/sub2") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "dir1/sub2/file1") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 10);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 10);
+ assertEqualInt((int)offset, 0);
+ assertEqualMem(p, "0123456789", 10);
+ assertEqualInt(ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ assertEqualInt((int)offset, 10);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "dir1/sub2/file2") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 10);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 10);
+ assertEqualInt((int)offset, 0);
+ assertEqualMem(p, "0123456789", 10);
+ assertEqualInt(ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ assertEqualInt((int)offset, 10);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "dir1/sub2/sub1") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "dir1/sub2/sub2") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "dir1/sub2/sub3") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "dir1/sub2/sub3/file") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 3);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 3);
+ assertEqualInt((int)offset, 0);
+ assertEqualMem(p, "xyz", 3);
+ assertEqualInt(ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ assertEqualInt((int)offset, 3);
+ }
+ if (archive_entry_filetype(ae) == AE_IFDIR) {
+ /* Descend into the current object */
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_disk_descend(a));
+ }
+ }
+ /* There is no entry. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
+
+ /* Close the disk object. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+
+ /*
+ * Test that call archive_read_disk_open_w, wchar_t version.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open_w(a, L"dir1"));
+
+ file_count = 12;
+ while (file_count--) {
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
+ if (wcscmp(archive_entry_pathname_w(ae), L"dir1") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+ } else if (wcscmp(archive_entry_pathname_w(ae),
+ L"dir1/file1") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 10);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 10);
+ assertEqualInt((int)offset, 0);
+ assertEqualMem(p, "0123456789", 10);
+ assertEqualInt(ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ assertEqualInt((int)offset, 10);
+ } else if (wcscmp(archive_entry_pathname_w(ae),
+ L"dir1/file2") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 11);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 11);
+ assertEqualInt((int)offset, 0);
+ assertEqualMem(p, "hello world", 11);
+ assertEqualInt(ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ assertEqualInt((int)offset, 11);
+ } else if (wcscmp(archive_entry_pathname_w(ae),
+ L"dir1/sub1") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+ } else if (wcscmp(archive_entry_pathname_w(ae),
+ L"dir1/sub1/file1") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 10);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 10);
+ assertEqualInt((int)offset, 0);
+ assertEqualMem(p, "0123456789", 10);
+ assertEqualInt(ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ assertEqualInt((int)offset, 10);
+ } else if (wcscmp(archive_entry_pathname_w(ae),
+ L"dir1/sub2") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+ } else if (wcscmp(archive_entry_pathname_w(ae),
+ L"dir1/sub2/file1") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 10);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 10);
+ assertEqualInt((int)offset, 0);
+ assertEqualMem(p, "0123456789", 10);
+ assertEqualInt(ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ assertEqualInt((int)offset, 10);
+ } else if (wcscmp(archive_entry_pathname_w(ae),
+ L"dir1/sub2/file2") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 10);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 10);
+ assertEqualInt((int)offset, 0);
+ assertEqualMem(p, "0123456789", 10);
+ assertEqualInt(ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ assertEqualInt((int)offset, 10);
+ } else if (wcscmp(archive_entry_pathname_w(ae),
+ L"dir1/sub2/sub1") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+ } else if (wcscmp(archive_entry_pathname_w(ae),
+ L"dir1/sub2/sub2") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+ } else if (wcscmp(archive_entry_pathname_w(ae),
+ L"dir1/sub2/sub3") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+ } else if (wcscmp(archive_entry_pathname_w(ae),
+ L"dir1/sub2/sub3/file") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 3);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 3);
+ assertEqualInt((int)offset, 0);
+ assertEqualMem(p, "xyz", 3);
+ assertEqualInt(ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ assertEqualInt((int)offset, 3);
+ }
+ if (archive_entry_filetype(ae) == AE_IFDIR) {
+ /* Descend into the current object */
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_disk_descend(a));
+ }
+ }
+ /* There is no entry. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
+
+ /* Close the disk object. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+
+ /*
+ * Test that call archive_read_disk_open with a regular file.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "dir1/file1"));
+
+ /* dir1/file1 */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
+ assertEqualString(archive_entry_pathname(ae), "dir1/file1");
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 10);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 10);
+ assertEqualInt((int)offset, 0);
+ assertEqualMem(p, "0123456789", 10);
+
+ /* There is no entry. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
+
+ /* Close the disk object. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ /*
+ * Test for wildcard '*' or '?'
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "dir1/*1"));
+
+ /* dir1/file1 */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
+ assertEqualString(archive_entry_pathname(ae), "dir1/file1");
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 10);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 10);
+ assertEqualInt((int)offset, 0);
+ assertEqualMem(p, "0123456789", 10);
+
+ /* dir1/sub1 */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
+ assertEqualString(archive_entry_pathname(ae), "dir1/sub1");
+ assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+
+ /* Descend into the current object */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_descend(a));
+
+ /* dir1/sub1/file1 */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
+ assertEqualString(archive_entry_pathname(ae), "dir1/sub1/file1");
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 10);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 10);
+ assertEqualInt((int)offset, 0);
+ assertEqualMem(p, "0123456789", 10);
+
+ /* There is no entry. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
+
+ /* Close the disk object. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+#endif
+
+ /*
+ * We should be on the initial directory where we performed
+ * archive_read_disk_new() after we perfome archive_read_free()
+ * even if we broke off the directory traversals.
+ */
+
+ /* Save current working directory. */
+#ifdef PATH_MAX
+ initial_cwd = getcwd(NULL, PATH_MAX);/* Solaris getcwd needs the size. */
+#else
+ initial_cwd = getcwd(NULL, 0);
+#endif
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "dir1"));
+
+ /* Step in a deep directory. */
+ file_count = 12;
+ while (file_count--) {
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_next_header2(a, ae));
+ if (strcmp(archive_entry_pathname(ae),
+ "dir1/sub1/file1") == 0)
+ /*
+ * We are on an another directory at this time.
+ */
+ break;
+ if (archive_entry_filetype(ae) == AE_IFDIR) {
+ /* Descend into the current object */
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_disk_descend(a));
+ }
+ }
+ /* Destroy the disk object. */
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+ /* We should be on the initial working directory. */
+ failure(
+ "Current working directory does not return to the initial"
+ "directory");
+#ifdef PATH_MAX
+ cwd = getcwd(NULL, PATH_MAX);/* Solaris getcwd needs the size. */
+#else
+ cwd = getcwd(NULL, 0);
+#endif
+ assertEqualString(initial_cwd, cwd);
+ free(initial_cwd);
+ free(cwd);
+
+ archive_entry_free(ae);
+}
+
+static void
+test_symlink_hybrid(void)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+ const void *p;
+ size_t size;
+ int64_t offset;
+ int file_count;
+
+ if (!canSymlink()) {
+ skipping("Can't test symlinks on this filesystem");
+ return;
+ }
+
+ /*
+ * Create a sample archive.
+ */
+ assertMakeDir("h", 0755);
+ assertChdir("h");
+ assertMakeDir("d1", 0755);
+ assertMakeSymlink("ld1", "d1");
+ assertMakeFile("d1/file1", 0644, "d1/file1");
+ assertMakeFile("d1/file2", 0644, "d1/file2");
+ assertMakeSymlink("d1/link1", "file1");
+ assertMakeSymlink("d1/linkX", "fileX");
+ assertMakeSymlink("link2", "d1/file2");
+ assertMakeSymlink("linkY", "d1/fileY");
+ assertChdir("..");
+
+ assert((ae = archive_entry_new()) != NULL);
+ assert((a = archive_read_disk_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_disk_set_symlink_hybrid(a));
+
+ /*
+ * Specified file is a symbolic link file.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "h/ld1"));
+ file_count = 5;
+
+ while (file_count--) {
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
+ if (strcmp(archive_entry_pathname(ae), "h/ld1") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "h/ld1/file1") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 8);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 8);
+ assertEqualInt((int)offset, 0);
+ assertEqualMem(p, "d1/file1", 8);
+ assertEqualInt(ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ assertEqualInt((int)offset, 8);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "h/ld1/file2") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 8);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 8);
+ assertEqualInt((int)offset, 0);
+ assertEqualMem(p, "d1/file2", 8);
+ assertEqualInt(ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ assertEqualInt((int)offset, 8);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "h/ld1/link1") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "h/ld1/linkX") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
+ }
+ if (archive_entry_filetype(ae) == AE_IFDIR) {
+ /* Descend into the current object */
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_disk_descend(a));
+ }
+ }
+ /* There is no entry. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
+ /* Close the disk object. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+
+ /*
+ * Specified file is a directory and it has symbolic files.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "h"));
+ file_count = 9;
+
+ while (file_count--) {
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
+ if (strcmp(archive_entry_pathname(ae), "h") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+ } else if (strcmp(archive_entry_pathname(ae), "h/d1") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "h/d1/file1") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 8);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 8);
+ assertEqualInt((int)offset, 0);
+ assertEqualMem(p, "d1/file1", 8);
+ assertEqualInt(ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ assertEqualInt((int)offset, 8);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "h/d1/file2") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 8);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 8);
+ assertEqualInt((int)offset, 0);
+ assertEqualMem(p, "d1/file2", 8);
+ assertEqualInt(ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ assertEqualInt((int)offset, 8);
+ } else if (strcmp(archive_entry_pathname(ae), "h/ld1") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "h/d1/link1") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "h/d1/linkX") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "h/link2") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "h/linkY") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
+ }
+ if (archive_entry_filetype(ae) == AE_IFDIR) {
+ /* Descend into the current object */
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_disk_descend(a));
+ }
+ }
+ /* There is no entry. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
+ /* Close the disk object. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ /* Destroy the disk object. */
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+ archive_entry_free(ae);
+}
+
+static void
+test_symlink_logical(void)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+ const void *p;
+ size_t size;
+ int64_t offset;
+ int file_count;
+
+ if (!canSymlink()) {
+ skipping("Can't test symlinks on this filesystem");
+ return;
+ }
+
+ /*
+ * Create a sample archive.
+ */
+ assertMakeDir("l", 0755);
+ assertChdir("l");
+ assertMakeDir("d1", 0755);
+ assertMakeSymlink("ld1", "d1");
+ assertMakeFile("d1/file1", 0644, "d1/file1");
+ assertMakeFile("d1/file2", 0644, "d1/file2");
+ assertMakeSymlink("d1/link1", "file1");
+ assertMakeSymlink("d1/linkX", "fileX");
+ assertMakeSymlink("link2", "d1/file2");
+ assertMakeSymlink("linkY", "d1/fileY");
+ assertChdir("..");
+
+ assert((ae = archive_entry_new()) != NULL);
+ assert((a = archive_read_disk_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_disk_set_symlink_logical(a));
+
+ /*
+ * Specified file is a symbolic link file.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "l/ld1"));
+ file_count = 5;
+
+ while (file_count--) {
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
+ if (strcmp(archive_entry_pathname(ae), "l/ld1") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "l/ld1/file1") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 8);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 8);
+ assertEqualInt((int)offset, 0);
+ assertEqualMem(p, "d1/file1", 8);
+ assertEqualInt(ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ assertEqualInt((int)offset, 8);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "l/ld1/file2") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 8);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 8);
+ assertEqualInt((int)offset, 0);
+ assertEqualMem(p, "d1/file2", 8);
+ assertEqualInt(ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ assertEqualInt((int)offset, 8);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "l/ld1/link1") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 8);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 8);
+ assertEqualInt((int)offset, 0);
+ assertEqualMem(p, "d1/file1", 8);
+ assertEqualInt(ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ assertEqualInt((int)offset, 8);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "l/ld1/linkX") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
+ }
+ if (archive_entry_filetype(ae) == AE_IFDIR) {
+ /* Descend into the current object */
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_disk_descend(a));
+ }
+ }
+ /* There is no entry. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
+ /* Close the disk object. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+
+ /*
+ * Specified file is a directory and it has symbolic files.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "l"));
+ file_count = 13;
+
+ while (file_count--) {
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
+ if (strcmp(archive_entry_pathname(ae), "l") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+ } else if (strcmp(archive_entry_pathname(ae), "l/d1") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "l/d1/file1") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 8);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 8);
+ assertEqualInt((int)offset, 0);
+ assertEqualMem(p, "d1/file1", 8);
+ assertEqualInt(ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ assertEqualInt((int)offset, 8);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "l/d1/file2") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 8);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 8);
+ assertEqualInt((int)offset, 0);
+ assertEqualMem(p, "d1/file2", 8);
+ assertEqualInt(ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ assertEqualInt((int)offset, 8);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "l/d1/link1") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 8);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 8);
+ assertEqualInt((int)offset, 0);
+ assertEqualMem(p, "d1/file1", 8);
+ assertEqualInt(ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ assertEqualInt((int)offset, 8);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "l/d1/linkX") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
+ } else if (strcmp(archive_entry_pathname(ae), "l/ld1") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "l/ld1/file1") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 8);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 8);
+ assertEqualInt((int)offset, 0);
+ assertEqualMem(p, "d1/file1", 8);
+ assertEqualInt(ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ assertEqualInt((int)offset, 8);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "l/ld1/file2") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 8);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 8);
+ assertEqualInt((int)offset, 0);
+ assertEqualMem(p, "d1/file2", 8);
+ assertEqualInt(ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ assertEqualInt((int)offset, 8);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "l/ld1/link1") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 8);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 8);
+ assertEqualInt((int)offset, 0);
+ assertEqualMem(p, "d1/file1", 8);
+ assertEqualInt(ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ assertEqualInt((int)offset, 8);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "l/ld1/linkX") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "l/link2") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 8);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 8);
+ assertEqualInt((int)offset, 0);
+ assertEqualMem(p, "d1/file2", 8);
+ assertEqualInt(ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ assertEqualInt((int)offset, 8);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "l/linkY") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
+ }
+ if (archive_entry_filetype(ae) == AE_IFDIR) {
+ /* Descend into the current object */
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_disk_descend(a));
+ }
+ }
+ /* There is no entry. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
+ /* Close the disk object. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ /* Destroy the disk object. */
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+ archive_entry_free(ae);
+}
+
+static void
+test_symlink_logical_loop(void)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+ const void *p;
+ size_t size;
+ int64_t offset;
+ int file_count;
+
+ if (!canSymlink()) {
+ skipping("Can't test symlinks on this filesystem");
+ return;
+ }
+
+ /*
+ * Create a sample archive.
+ */
+ assertMakeDir("l2", 0755);
+ assertChdir("l2");
+ assertMakeDir("d1", 0755);
+ assertMakeDir("d1/d2", 0755);
+ assertMakeDir("d1/d2/d3", 0755);
+ assertMakeDir("d2", 0755);
+ assertMakeFile("d2/file1", 0644, "d2/file1");
+ assertMakeSymlink("d1/d2/ld1", "../../d1");
+ assertMakeSymlink("d1/d2/ld2", "../../d2");
+ assertChdir("..");
+
+ assert((ae = archive_entry_new()) != NULL);
+ assert((a = archive_read_disk_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_disk_set_symlink_logical(a));
+
+ /*
+ * Specified file is a symbolic link file.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "l2/d1"));
+ file_count = 6;
+
+ while (file_count--) {
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
+ if (strcmp(archive_entry_pathname(ae), "l2/d1") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+ } else if (strcmp(archive_entry_pathname(ae), "l2/d1/d2") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+ } else if (strcmp(archive_entry_pathname(ae), "l2/d1/d2/d3") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+ } else if (strcmp(archive_entry_pathname(ae), "l2/d1/d2/ld1") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
+ } else if (strcmp(archive_entry_pathname(ae), "l2/d1/d2/ld2") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+ } else if (strcmp(archive_entry_pathname(ae),
+ "l2/d1/d2/ld2/file1") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 8);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 8);
+ assertEqualInt((int)offset, 0);
+ assertEqualMem(p, "d2/file1", 8);
+ assertEqualInt(ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ assertEqualInt((int)offset, 8);
+ }
+ if (archive_entry_filetype(ae) == AE_IFDIR) {
+ /* Descend into the current object */
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_disk_descend(a));
+ }
+ }
+ /* There is no entry. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
+ /* Destroy the disk object. */
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+ archive_entry_free(ae);
+}
+
+static void
+test_restore_atime(void)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+ const void *p;
+ size_t size;
+ int64_t offset;
+ int file_count;
+
+ if (!atimeIsUpdated()) {
+ skipping("Can't test restoring atime on this filesystem");
+ return;
+ }
+
+ assertMakeDir("at", 0755);
+ assertMakeFile("at/f1", 0644, "0123456789");
+ assertMakeFile("at/f2", 0644, "hello world");
+ assertMakeFile("at/fe", 0644, NULL);
+ assertUtimes("at/f1", 886600, 0, 886600, 0);
+ assertUtimes("at/f2", 886611, 0, 886611, 0);
+ assertUtimes("at/fe", 886611, 0, 886611, 0);
+ assertUtimes("at", 886622, 0, 886622, 0);
+ file_count = 4;
+
+ assert((ae = archive_entry_new()) != NULL);
+ assert((a = archive_read_disk_new()) != NULL);
+
+ /*
+ * Test1: Traversals without archive_read_disk_set_atime_restored().
+ */
+ failure("Directory traversals should work as well");
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "at"));
+ while (file_count--) {
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
+ if (strcmp(archive_entry_pathname(ae), "at") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+ } else if (strcmp(archive_entry_pathname(ae), "at/f1") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 10);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 10);
+ assertEqualInt((int)offset, 0);
+ assertEqualMem(p, "0123456789", 10);
+ assertEqualInt(ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ assertEqualInt((int)offset, 10);
+ } else if (strcmp(archive_entry_pathname(ae), "at/f2") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 11);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 11);
+ assertEqualInt((int)offset, 0);
+ assertEqualMem(p, "hello world", 11);
+ assertEqualInt(ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ assertEqualInt((int)offset, 11);
+ } else if (strcmp(archive_entry_pathname(ae), "at/fe") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 0);
+ }
+ if (archive_entry_filetype(ae) == AE_IFDIR) {
+ /* Descend into the current object */
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_disk_descend(a));
+ }
+ }
+ /* There is no entry. */
+ failure("There must be no entry");
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
+
+ failure("Atime must not be restored");
+ assertFileAtimeRecent("at");
+ assertFileAtimeRecent("at/f1");
+ assertFileAtimeRecent("at/f2");
+ failure("The atime of a empty file must not be changed");
+ assertFileAtime("at/fe", 886611, 0);
+
+ /* Close the disk object. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+
+ /*
+ * Test2: Traversals with archive_read_disk_set_atime_restored().
+ */
+ assertUtimes("at/f1", 886600, 0, 886600, 0);
+ assertUtimes("at/f2", 886611, 0, 886611, 0);
+ assertUtimes("at/fe", 886611, 0, 886611, 0);
+ assertUtimes("at", 886622, 0, 886622, 0);
+ file_count = 4;
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_atime_restored(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "at"));
+
+ failure("Directory traversals should work as well");
+ while (file_count--) {
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
+ if (strcmp(archive_entry_pathname(ae), "at") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+ } else if (strcmp(archive_entry_pathname(ae), "at/f1") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 10);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 10);
+ assertEqualInt((int)offset, 0);
+ assertEqualMem(p, "0123456789", 10);
+ assertEqualInt(ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ assertEqualInt((int)offset, 10);
+ } else if (strcmp(archive_entry_pathname(ae), "at/f2") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 11);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 11);
+ assertEqualInt((int)offset, 0);
+ assertEqualMem(p, "hello world", 11);
+ assertEqualInt(ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ assertEqualInt((int)offset, 11);
+ } else if (strcmp(archive_entry_pathname(ae), "at/fe") == 0) {
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualInt(archive_entry_size(ae), 0);
+ }
+ if (archive_entry_filetype(ae) == AE_IFDIR) {
+ /* Descend into the current object */
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_disk_descend(a));
+ }
+ }
+ /* There is no entry. */
+ failure("There must be no entry");
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
+
+ failure("Atime must be restored");
+ assertFileAtime("at", 886622, 0);
+ assertFileAtime("at/f1", 886600, 0);
+ assertFileAtime("at/f2", 886611, 0);
+ failure("The atime of a empty file must not be changed");
+ assertFileAtime("at/fe", 886611, 0);
+
+ /* Destroy the disk object. */
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+ archive_entry_free(ae);
+}
+
+DEFINE_TEST(test_read_disk_directory_traversals)
+{
+ /* Basic test. */
+ test_basic();
+ /* Test hybird mode; follow symlink initially, then not. */
+ test_symlink_hybrid();
+ /* Test logcal mode; follow all symlinks. */
+ test_symlink_logical();
+ /* Test logcal mode; prevent loop in symlinks. */
+ test_symlink_logical_loop();
+ /* Test to restore atime. */
+ test_restore_atime();
+}
diff --git a/libarchive/test/test_read_disk_entry_from_file.c b/libarchive/test/test_read_disk_entry_from_file.c
index 6e34abe441df..7a41034ac37e 100644
--- a/libarchive/test/test_read_disk_entry_from_file.c
+++ b/libarchive/test/test_read_disk_entry_from_file.c
@@ -26,7 +26,7 @@
__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_disk_entry_from_file.c 201247 2009-12-30 05:59:21Z kientzle $");
static const char *
-gname_lookup(void *d, gid_t g)
+gname_lookup(void *d, int64_t g)
{
(void)d; /* UNUSED */
(void)g; /* UNUSED */
@@ -34,7 +34,7 @@ gname_lookup(void *d, gid_t g)
}
static const char *
-uname_lookup(void *d, uid_t u)
+uname_lookup(void *d, int64_t u)
{
(void)d; /* UNUSED */
(void)u; /* UNUSED */
@@ -66,7 +66,7 @@ DEFINE_TEST(test_read_disk_entry_from_file)
entry = archive_entry_new();
assert(entry != NULL);
archive_entry_copy_pathname(entry, "foo");
- assertEqualInt(ARCHIVE_OK,
+ assertEqualIntA(a, ARCHIVE_OK,
archive_read_disk_entry_from_file(a, entry, -1, NULL));
/* Verify the information we got back. */
@@ -76,5 +76,5 @@ DEFINE_TEST(test_read_disk_entry_from_file)
/* Destroy the archive. */
archive_entry_free(entry);
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_read_extract.c b/libarchive/test/test_read_extract.c
index 5696e0d356f6..d7de26b6ee61 100644
--- a/libarchive/test/test_read_extract.c
+++ b/libarchive/test/test_read_extract.c
@@ -111,13 +111,13 @@ DEFINE_TEST(test_read_extract)
archive_entry_free(ae);
}
/* Close out the archive. */
- assertA(0 == archive_write_close(a));
- assertA(0 == archive_write_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/* Extract the entries to disk. */
assert((a = archive_read_new()) != NULL);
assertA(0 == archive_read_support_format_all(a));
- assertA(0 == archive_read_support_compression_all(a));
+ assertA(0 == archive_read_support_filter_all(a));
assertA(0 == archive_read_open_memory(a, buff, BUFF_SIZE));
/* Restore first entry with _EXTRACT_PERM. */
failure("Error reading first entry", i);
@@ -132,8 +132,8 @@ DEFINE_TEST(test_read_extract)
assertA(0 == archive_read_extract(a, ae, 0));
}
assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
- assert(0 == archive_read_close(a));
- assert(0 == archive_read_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
/* Test the entries on disk. */
/* This first entry was extracted with ARCHIVE_EXTRACT_PERM,
diff --git a/libarchive/test/test_read_file_nonexistent.c b/libarchive/test/test_read_file_nonexistent.c
index 9494dbab6f4f..acb72a1e32cc 100644
--- a/libarchive/test/test_read_file_nonexistent.c
+++ b/libarchive/test/test_read_file_nonexistent.c
@@ -31,7 +31,7 @@ DEFINE_TEST(test_read_file_nonexistent)
assertEqualInt(ARCHIVE_OK, archive_read_support_format_all(a));
assertEqualInt(ARCHIVE_FATAL,
archive_read_open_filename(a, "notexistent.tar", 512));
- archive_read_finish(a);
+ archive_read_free(a);
}
diff --git a/libarchive/test/test_read_format_7zip.c b/libarchive/test/test_read_format_7zip.c
new file mode 100644
index 000000000000..a4cc555d06b7
--- /dev/null
+++ b/libarchive/test/test_read_format_7zip.c
@@ -0,0 +1,703 @@
+/*-
+ * Copyright (c) 2011 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD");
+
+/*
+ * Extract a non-encorded file.
+ * The header of the 7z archive files is not encdoed.
+ */
+static void
+test_copy()
+{
+ const char *refname = "test_read_format_7zip_copy.7z";
+ struct archive_entry *ae;
+ struct archive *a;
+ char buff[128];
+
+ extract_reference_file(refname);
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file1. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0777), archive_entry_mode(ae));
+ assertEqualString("file1", archive_entry_pathname(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(60, archive_entry_size(ae));
+ assertEqualInt(60, archive_read_data(a, buff, sizeof(buff)));
+ assertEqualMem(buff, " ", 4);
+
+ assertEqualInt(1, archive_file_count(a));
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+/*
+ * An archive file has no entry.
+ */
+static void
+test_empty_archive()
+{
+ const char *refname = "test_read_format_7zip_empty_archive.7z";
+ struct archive_entry *ae;
+ struct archive *a;
+
+ extract_reference_file(refname);
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ assertEqualInt(0, archive_file_count(a));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+/*
+ * An archive file has one empty file. It means there is no content
+ * in the archive file except for a header.
+ */
+static void
+test_empty_file()
+{
+ const char *refname = "test_read_format_7zip_empty_file.7z";
+ struct archive_entry *ae;
+ struct archive *a;
+
+ extract_reference_file(refname);
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular empty. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
+ assertEqualString("empty", archive_entry_pathname(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+
+ assertEqualInt(1, archive_file_count(a));
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+/*
+ * Extract an encoded file.
+ * The header of the 7z archive files is not encdoed.
+ */
+static void
+test_plain_header(const char *refname)
+{
+ struct archive_entry *ae;
+ struct archive *a;
+ char buff[128];
+
+ extract_reference_file(refname);
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file1. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
+ assertEqualString("file1", archive_entry_pathname(ae));
+ assertEqualInt(1322058763, archive_entry_mtime(ae));
+ assertEqualInt(2844, archive_entry_size(ae));
+ assertEqualInt(sizeof(buff), archive_read_data(a, buff, sizeof(buff)));
+ assertEqualMem(buff, "The libarchive distribution ", 28);
+
+ assertEqualInt(1, archive_file_count(a));
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+/*
+ * Extract multi files.
+ * The header of the 7z archive files is encdoed with LZMA.
+ */
+static void
+test_extract_all_files(const char *refname)
+{
+ struct archive_entry *ae;
+ struct archive *a;
+ char buff[128];
+
+ extract_reference_file(refname);
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file1. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
+ assertEqualString("dir1/file1", archive_entry_pathname(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(13, archive_entry_size(ae));
+ assertEqualInt(13, archive_read_data(a, buff, sizeof(buff)));
+ assertEqualMem(buff, "aaaaaaaaaaaa\n", 13);
+
+ /* Verify regular file2. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
+ assertEqualString("file2", archive_entry_pathname(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(26, archive_entry_size(ae));
+ assertEqualInt(26, archive_read_data(a, buff, sizeof(buff)));
+ assertEqualMem(buff, "aaaaaaaaaaaa\nbbbbbbbbbbbb\n", 26);
+
+ /* Verify regular file3. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
+ assertEqualString("file3", archive_entry_pathname(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(39, archive_entry_size(ae));
+ assertEqualInt(39, archive_read_data(a, buff, sizeof(buff)));
+ assertEqualMem(buff, "aaaaaaaaaaaa\nbbbbbbbbbbbb\ncccccccccccc\n", 39);
+
+ /* Verify regular file4. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
+ assertEqualString("file4", archive_entry_pathname(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(52, archive_entry_size(ae));
+ assertEqualInt(52, archive_read_data(a, buff, sizeof(buff)));
+ assertEqualMem(buff,
+ "aaaaaaaaaaaa\nbbbbbbbbbbbb\ncccccccccccc\ndddddddddddd\n", 52);
+
+ /* Verify directory dir1. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFDIR | 0755), archive_entry_mode(ae));
+ assertEqualString("dir1/", archive_entry_pathname(ae));
+ assertEqualInt(2764801, archive_entry_mtime(ae));
+
+ assertEqualInt(5, archive_file_count(a));
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+/*
+ * Extract last file.
+ * The header of the 7z archive files is encdoed with LZMA.
+ */
+static void
+test_extract_last_file(const char *refname)
+{
+ struct archive_entry *ae;
+ struct archive *a;
+ char buff[128];
+
+ extract_reference_file(refname);
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file1. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
+ assertEqualString("dir1/file1", archive_entry_pathname(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(13, archive_entry_size(ae));
+
+ /* Verify regular file2. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
+ assertEqualString("file2", archive_entry_pathname(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(26, archive_entry_size(ae));
+
+ /* Verify regular file3. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
+ assertEqualString("file3", archive_entry_pathname(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(39, archive_entry_size(ae));
+
+ /* Verify regular file4. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
+ assertEqualString("file4", archive_entry_pathname(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(52, archive_entry_size(ae));
+ assertEqualInt(52, archive_read_data(a, buff, sizeof(buff)));
+ assertEqualMem(buff,
+ "aaaaaaaaaaaa\nbbbbbbbbbbbb\ncccccccccccc\ndddddddddddd\n", 52);
+
+ /* Verify directory dir1. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFDIR | 0755), archive_entry_mode(ae));
+ assertEqualString("dir1/", archive_entry_pathname(ae));
+ assertEqualInt(2764801, archive_entry_mtime(ae));
+
+ assertEqualInt(5, archive_file_count(a));
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+/*
+ * Extract a mixed archive file which has both LZMA and LZMA2 encoded files.
+ * LZMA: file1, file2, file3, file4
+ * LZMA2: zfile1, zfile2, zfile3, zfile4
+ */
+static void
+test_extract_all_files2(const char *refname)
+{
+ struct archive_entry *ae;
+ struct archive *a;
+ char buff[128];
+
+ extract_reference_file(refname);
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file1. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
+ assertEqualString("dir1/file1", archive_entry_pathname(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(13, archive_entry_size(ae));
+ assertEqualInt(13, archive_read_data(a, buff, sizeof(buff)));
+ assertEqualMem(buff, "aaaaaaaaaaaa\n", 13);
+
+ /* Verify regular file2. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
+ assertEqualString("file2", archive_entry_pathname(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(26, archive_entry_size(ae));
+ assertEqualInt(26, archive_read_data(a, buff, sizeof(buff)));
+ assertEqualMem(buff, "aaaaaaaaaaaa\nbbbbbbbbbbbb\n", 26);
+
+ /* Verify regular file3. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
+ assertEqualString("file3", archive_entry_pathname(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(39, archive_entry_size(ae));
+ assertEqualInt(39, archive_read_data(a, buff, sizeof(buff)));
+ assertEqualMem(buff, "aaaaaaaaaaaa\nbbbbbbbbbbbb\ncccccccccccc\n", 39);
+
+ /* Verify regular file4. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
+ assertEqualString("file4", archive_entry_pathname(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(52, archive_entry_size(ae));
+ assertEqualInt(52, archive_read_data(a, buff, sizeof(buff)));
+ assertEqualMem(buff,
+ "aaaaaaaaaaaa\nbbbbbbbbbbbb\ncccccccccccc\ndddddddddddd\n", 52);
+
+ /* Verify regular zfile1. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
+ assertEqualString("dir1/zfile1", archive_entry_pathname(ae));
+ assertEqualInt(5184001, archive_entry_mtime(ae));
+ assertEqualInt(13, archive_entry_size(ae));
+ assertEqualInt(13, archive_read_data(a, buff, sizeof(buff)));
+ assertEqualMem(buff, "aaaaaaaaaaaa\n", 13);
+
+ /* Verify regular zfile2. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
+ assertEqualString("zfile2", archive_entry_pathname(ae));
+ assertEqualInt(5184001, archive_entry_mtime(ae));
+ assertEqualInt(26, archive_entry_size(ae));
+ assertEqualInt(26, archive_read_data(a, buff, sizeof(buff)));
+ assertEqualMem(buff, "aaaaaaaaaaaa\nbbbbbbbbbbbb\n", 26);
+
+ /* Verify regular zfile3. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
+ assertEqualString("zfile3", archive_entry_pathname(ae));
+ assertEqualInt(5184001, archive_entry_mtime(ae));
+ assertEqualInt(39, archive_entry_size(ae));
+ assertEqualInt(39, archive_read_data(a, buff, sizeof(buff)));
+ assertEqualMem(buff, "aaaaaaaaaaaa\nbbbbbbbbbbbb\ncccccccccccc\n", 39);
+
+ /* Verify regular zfile4. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
+ assertEqualString("zfile4", archive_entry_pathname(ae));
+ assertEqualInt(5184001, archive_entry_mtime(ae));
+ assertEqualInt(52, archive_entry_size(ae));
+ assertEqualInt(52, archive_read_data(a, buff, sizeof(buff)));
+ assertEqualMem(buff,
+ "aaaaaaaaaaaa\nbbbbbbbbbbbb\ncccccccccccc\ndddddddddddd\n", 52);
+
+ /* Verify directory dir1. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFDIR | 0755), archive_entry_mode(ae));
+ assertEqualString("dir1/", archive_entry_pathname(ae));
+ assertEqualInt(2764801, archive_entry_mtime(ae));
+
+ assertEqualInt(9, archive_file_count(a));
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+/*
+ * Extract a file compressed with DELTA + LZMA[12].
+ */
+static void
+test_delta_lzma(const char *refname)
+{
+ struct archive_entry *ae;
+ struct archive *a;
+ size_t remaining;
+ ssize_t bytes;
+ char buff[1024];
+
+ extract_reference_file(refname);
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file1. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
+ assertEqualString("file1", archive_entry_pathname(ae));
+ assertEqualInt(172802, archive_entry_mtime(ae));
+ assertEqualInt(27627, archive_entry_size(ae));
+ remaining = (size_t)archive_entry_size(ae);
+ while (remaining) {
+ if (remaining < sizeof(buff))
+ assertEqualInt(remaining,
+ bytes = archive_read_data(a, buff, sizeof(buff)));
+ else
+ assertEqualInt(sizeof(buff),
+ bytes = archive_read_data(a, buff, sizeof(buff)));
+ if (bytes > 0)
+ remaining -= bytes;
+ else
+ break;
+ }
+ assertEqualInt(0, remaining);
+
+ assertEqualInt(1, archive_file_count(a));
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+/*
+ * Extract a file compressed with BCJ + LZMA2.
+ */
+static void
+test_bcj(const char *refname)
+{
+ struct archive_entry *ae;
+ struct archive *a;
+ size_t remaining;
+ ssize_t bytes;
+ char buff[1024];
+
+ extract_reference_file(refname);
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular x86exe. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0555), archive_entry_mode(ae));
+ assertEqualString("x86exe", archive_entry_pathname(ae));
+ assertEqualInt(172802, archive_entry_mtime(ae));
+ assertEqualInt(27328, archive_entry_size(ae));
+ remaining = (size_t)archive_entry_size(ae);
+ while (remaining) {
+ if (remaining < sizeof(buff))
+ assertEqualInt(remaining,
+ bytes = archive_read_data(a, buff, sizeof(buff)));
+ else
+ assertEqualInt(sizeof(buff),
+ bytes = archive_read_data(a, buff, sizeof(buff)));
+ if (bytes > 0)
+ remaining -= bytes;
+ else
+ break;
+ }
+ assertEqualInt(0, remaining);
+
+ assertEqualInt(1, archive_file_count(a));
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+/*
+ * Extract a file compressed with PPMd.
+ */
+static void
+test_ppmd()
+{
+ const char *refname = "test_read_format_7zip_ppmd.7z";
+ struct archive_entry *ae;
+ struct archive *a;
+ size_t remaining;
+ ssize_t bytes;
+ char buff[1024];
+
+ extract_reference_file(refname);
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file1. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0777), archive_entry_mode(ae));
+ assertEqualString("ppmd_test.txt", archive_entry_pathname(ae));
+ assertEqualInt(1322464589, archive_entry_mtime(ae));
+ assertEqualInt(102400, archive_entry_size(ae));
+ remaining = (size_t)archive_entry_size(ae);
+ while (remaining) {
+ if (remaining < sizeof(buff))
+ assertEqualInt(remaining,
+ bytes = archive_read_data(a, buff, sizeof(buff)));
+ else
+ assertEqualInt(sizeof(buff),
+ bytes = archive_read_data(a, buff, sizeof(buff)));
+ if (bytes > 0)
+ remaining -= bytes;
+ else
+ break;
+ }
+ assertEqualInt(0, remaining);
+
+ assertEqualInt(1, archive_file_count(a));
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_symname()
+{
+ const char *refname = "test_read_format_7zip_symbolic_name.7z";
+ struct archive_entry *ae;
+ struct archive *a;
+ char buff[128];
+
+ extract_reference_file(refname);
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file1. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
+ assertEqualString("file1", archive_entry_pathname(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(32, archive_entry_size(ae));
+ assertEqualInt(32, archive_read_data(a, buff, sizeof(buff)));
+ assertEqualMem(buff, "hellohellohello\nhellohellohello\n", 32);
+
+ /* Verify symbolic-linke symlinkfile. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFLNK | 0755), archive_entry_mode(ae));
+ assertEqualString("symlinkfile", archive_entry_pathname(ae));
+ assertEqualString("file1", archive_entry_symlink(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+
+ assertEqualInt(2, archive_file_count(a));
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+
+DEFINE_TEST(test_read_format_7zip)
+{
+ struct archive *a;
+
+ test_copy();
+ test_empty_archive();
+ test_empty_file();
+ test_ppmd();
+ test_bcj("test_read_format_7zip_bcj_copy.7z");
+ test_bcj("test_read_format_7zip_bcj2_copy_1.7z");
+ test_bcj("test_read_format_7zip_bcj2_copy_2.7z");
+
+ assert((a = archive_read_new()) != NULL);
+
+ /* Extracting with libbzip2 */
+ if (ARCHIVE_OK != archive_read_support_filter_bzip2(a)) {
+ skipping("7zip:bzip2 decoding is not supported on this platform");
+ } else {
+ test_plain_header("test_read_format_7zip_bzip2.7z");
+ test_bcj("test_read_format_7zip_bcj_bzip2.7z");
+ test_bcj("test_read_format_7zip_bcj2_bzip2.7z");
+ }
+
+ /* Extracting with libz */
+ if (ARCHIVE_OK != archive_read_support_filter_gzip(a)) {
+ skipping("7zip:deflate decoding is not supported on this platform");
+ } else {
+ test_plain_header("test_read_format_7zip_deflate.7z");
+ test_bcj("test_read_format_7zip_bcj_deflate.7z");
+ test_bcj("test_read_format_7zip_bcj2_deflate.7z");
+ }
+
+ /* Extracting with liblzma */
+ if (ARCHIVE_OK != archive_read_support_filter_xz(a)) {
+ skipping("7zip:lzma decoding is not supported on this platform");
+ } else {
+ test_symname();
+ test_plain_header("test_read_format_7zip_lzma1.7z");
+ test_plain_header("test_read_format_7zip_lzma2.7z");
+ test_extract_all_files("test_read_format_7zip_copy_2.7z");
+ test_extract_all_files("test_read_format_7zip_lzma1_2.7z");
+ test_extract_last_file("test_read_format_7zip_copy_2.7z");
+ test_extract_last_file("test_read_format_7zip_lzma1_2.7z");
+ test_extract_all_files2("test_read_format_7zip_lzma1_lzma2.7z");
+ test_bcj("test_read_format_7zip_bcj_lzma1.7z");
+ test_bcj("test_read_format_7zip_bcj_lzma2.7z");
+ test_bcj("test_read_format_7zip_bcj2_copy_lzma.7z");
+ test_bcj("test_read_format_7zip_bcj2_lzma1_1.7z");
+ test_bcj("test_read_format_7zip_bcj2_lzma1_2.7z");
+ test_bcj("test_read_format_7zip_bcj2_lzma2_1.7z");
+ test_bcj("test_read_format_7zip_bcj2_lzma2_2.7z");
+ test_delta_lzma("test_read_format_7zip_delta_lzma1.7z");
+ test_delta_lzma("test_read_format_7zip_delta_lzma2.7z");
+ }
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
diff --git a/libarchive/test/test_read_format_7zip_bcj2_bzip2.7z.uu b/libarchive/test/test_read_format_7zip_bcj2_bzip2.7z.uu
new file mode 100644
index 000000000000..274668fdf5e6
--- /dev/null
+++ b/libarchive/test/test_read_format_7zip_bcj2_bzip2.7z.uu
@@ -0,0 +1,319 @@
+begin 644 test_read_format_7zip_bcj2_bzip2.7z
+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
+MD@'6)-C52;$@8C(&M?E>WQK.ZZ<^=S)-B'(9PQ8#&?+L(4E85@L4BLPU3%*"
+M=?^5@P'_XWE+QZ&)$!BFO2F$J&!,+Y.PRX8QF6*4+1#%,1)'&'!(5JB1B8/=
+M62%5(R,RAG&,"N,3`B3%**.*%%#Q@,@]M%\7>T89S1,.3A=5C0<Q^-<-U4;*
+M5LSFHYR+,S!DRS)XC44^1^[[WR*&GNQ=R13A0D(QD_.L```58```6%```!20
+M```3Z```$^@```_D```HH```$U@``!&(```0B```2?```!*H```2J```%!@`
+M`!08```3:```%"@``!0H```4*```$[@``!%X```2*```$[@``!*8```16```
+M%"@``!.X```0"```$[@``!#8```4&```$1@``!*H```3>```$2@``!'(```4
+M&```$.@``!*X```1R```$-@``!*H```4&```$V@``!)(```3N```$J@``!08
+M```2J```%!@``!*H```4&```$K@``!*H```4&```$X@``!.(```3V```$R@`
+M`!)X```98```$N@``#?````0&```$G@``!E@```1V```$N@``!)H```1>```
+M$B@``!(H```WP```$!@``!#(```32```$X@``!.(```3J```$Y@``!"(```1
+M2```$@@``$FP```0B```$#@``!"(```3F```$(@``!+(```2V```$M@``!"(
+M```RT```)@```"8````36```$S@``!"(```3"```$\@``!18```46```%%@`
+M`!18```46```$#@``!18```2.```$C@``!(X```Q\```$M@``!0(```0F```
+M$&@``!08```2*```$B@``!"X```2.```$+@``!(X```2.```-#```#0P```T
+M,```-#```#0P```T,```-#```#0P```T,```-#```#0P```1N```$6@``!#X
+M```0>```$$@``!+X```3V```$,@``!-(```0R```$T@``!#(```32```$T@`
+M`!-(```32```$,@``!#(```0R```$,@``!-(```U$```-\```#A@```WP```
+M,?```%;````2B```$H@``#N````0R```$T@``#N````0R```$T@``!#(```3
+M2```$H@``!&8```2N```$H@``!08```[@```$,@``!#(```32```$T@``!(8
+M```2J```$:@``!0X```1.```$_@``!*(```0J```$H@``#9@```WP```,?``
+M`!*(```2J```$H@``#9@```U$```$H@``!*(``!6P```$H@``!*(```0R```
+M.&```!*H```42```$H@``#?````2J```$H@``#9@```V8```$J@``!*H```2
+M:```$7@``!`H```32```$_@``!*X```2:```$K@``!&H```2:```$K@``!/8
+M```3&```$U@``!)8```06```$0@``!)8```3V```$E@``!!8```0R```$T@`
+M`!)8```1"```$,@``!#(```1"```$T@``!-(```0R```$T@``!/8```26```
+M$%@``!#(```32```$0@``!)8```2B```$0@``!#(```32```$]@``!)8```0
+M6```$,@``!#(```0R```$,@``!#(```32```$T@``!-(```32```%!@``!-(
+M```1"```$E@``!'H```1"```$,@``!#(```32```$T@``!/8```5,```#_@`
+M``_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```
+M#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/
+M^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X
+M```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@`
+M``_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```
+M#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/
+M^```#_@``!'X```5D```$?@``!9````1^```%M```!'X```78```$?@``!?P
+M```1^```$?@``!B@```A1```(5L``"#]```=7@``'6H``!YQ```>4```'5``
+M`!U0```>B@``'S$``!^B```EJ0``'LT``![-```?!0``&H$``"$;```CMP``
+M)?0``!JD```=5P``&J0``!JD```<````'/$``!S^```<_@``)>```"7@```<
+M5P``'%<``"2R```@R0``''```!QP```@/P``'^D``!XR```=N0``'C(``!FR
+M```EJ0``)<<``"6]```DU```)1H``!HQ```=ZP``(#4``"2-```C00``(Y@`
+M`")U```A\@``(:,``"B"```G=P``*`@``"=H```GP```)X```"A&```GV```
+M*"P``"A9```F@```)H```":2```H;@``)H```":````F@```)Q```"<0```F
+M<@``)H```"9R```F^0``)H```":^```F^0``*8L``#$P```OOP``+#H``#"!
+M```K[0``+`<``#`3```P5```,#P``"_H```P8P``*QP``"L2```K'```*?\`
+M`"HF```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC```I8P``
+M*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC```I
+M8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC
+M```I8P``*6,``"EC```IVP``*=L``"G;```KHP``,6T``"NM```K0@``,4P`
+M`"NM```KP```*ZT``"NM```KP```,<L``"HF```J)@``*B8``"HP```I7@``
+M*ZT``"NM```KK0``*ZT``"NM```KK0``,/@``#0D```ST0``-!P``#,I```S
+M(P``,RD``#+D```TX```-$P``#7S```UN```-<L``#9````V'@``-;0``#6T
+M```W10``-R```#>Z```VF```-I@``#:8```V@0``-I@``#:8```VF```-I@`
+M`%$0``!+(```3H```#ES```Y)@``.?D``#I*```[4@``.:@``#HJ```YQ```
+M.+(``#KB```ZP@``.OX``#IF```[-@``.J(``#L:```Y%0``.9<``#GH```Y
+M8@``.-H``#R(```[LP``.ZH``$`\``!`*@``/^L``#_K```_N@``/X0``#]R
+M```_A```/X0``#YT```^K0``/DT``#XT```^-```/+```#UP``!!5```09(`
+M`$"@``!!$```11P``$4<``!$]P``1J@``$95``!#5```0U0``$-4``!(>P``
+M1_4``$@U``!)!@``21H``$CC``!(Q0``1C```$8(``!%<```17```$>P``!%
+MWP``1^4``$?3``!%]```1O```$<```!&T```2,X``$(```!)I0``0?4``$>`
+M``!$4P``1((``$2"``!#M```0Z<``$(N``!"(```1/<``$2U``!(1P``2(X`
+M`$3)``!%N```1$8``$1U``!$=0``0L$``$-4``!#`P``1S```$-4``!"@```
+M1,D``$-,``!$]P``0U0``$-4``!#`P``0P,``$@U``!(-0``0U0``$K]``!-
+MI0``3.0``$UO``!-1```3*,``$R!``!-\0``3=\``$MH``!,`0``3`H``$U5
+M``!-_@``2V@``$W%``!.'```2V@``$O)``!,T@``3CH``$Y4``!.<@``31,`
+M`$QP``!,70``3,@``$S2``!-"0``31,``$V>``!-E```39X``%"%``!0:0``
+M4`(``$_4``!.R```4+,``%"A``!.R```3S<``$]```!0P```4-\``$[(``!/
+MR0``3[8``%!6``!030``4%8``%44``!2L@``56D``%3?``!4WP``5-\``%5&
+M``!60```5B@``%44``!5=@``45@``%4T``!3J```5(```%/A``!48```5!``
+M`%2@``!40```5,```%*'``!2T```4OX``%,V``!3;@``4Y8``%,@``!3*0``
+M4N<``%+Q``!36```4V$``%.-``!3E@``5:```%+$``!2E```5KH``%()``!2
+M$@``4;T``%%8``!4^0``5F0``%9^``!6G```4H<``%*'``!2;@``5>P``%7B
+M``!5[```5A,``%8<``!7H@``5\```%<&``!7!@``5T```%=``'__[(*_<*GB
+MTO8J#[&TS@MGB4R]0=<':N.(W\G9G;.:/7*.,11&`00&``0)JKB$;(>X)P`'
+M"P$``@,$`@(4`P,!&P0!`0```@,$#,"<7L#`:@`("@$]?9*5```%`1$/`'@`
+B.``V`&4`>`!E````%`H!```M0RMQLYT!%08!`"$`````````
+`
+end
diff --git a/libarchive/test/test_read_format_7zip_bcj2_copy_1.7z.uu b/libarchive/test/test_read_format_7zip_bcj2_copy_1.7z.uu
new file mode 100644
index 000000000000..ad8cc4dee7dc
--- /dev/null
+++ b/libarchive/test/test_read_format_7zip_bcj2_copy_1.7z.uu
@@ -0,0 +1,614 @@
+begin 644 test_read_format_7zip_bcj2_copy_1.7z
+M-WJ\KR<<``.C9M/"YVH```````!=`````````"._PGQ_14Q&`0$!"0``````
+M`````@`#``$```!PE`0(-````+!F````````-``@``<`*``:`!D`!@```#0`
+M```T@`0(-(`$".````#@````!0````0````#````%`$``!2!!`@4@00(%0``
+M`!4````$`````0````$``````````(`$"`"`!`@T70``-%T```4`````$```
+M`0````!@````X`0(`.`$")@"``!,!```!@`````0```"````B&```(C@!`B(
+MX`0(V````-@````&````!`````0````L`0``+($$""R!!`@8````&`````0`
+M```$````4.5T9!A=```8W00(&-T$"!P````<````!`````0````O;&EB97AE
+M8R]L9"UE;&8N<V\N,0`````(````!`````$```!&<F5E0E-$`,<^#`!#````
+M60```$````!5````&``````````]````5``````````\````.@```%(```!&
+M````%P````````!!````-P```$0```!.`````````"T````6````&0````4`
+M``!-````5P```$@`````````'@```"X````G````20``````````````-```
+M`%8```!8````*``````````*````"0````````````````````T````^````
+M-@```%,````,````(````!4````R````(0```"L`````````40```"\```!*
+M````4```````````````0@````````!,````0P````````!/````-0``````
+M```````````````````````````````````````````````````!````````
+M`````````````````````````````P``````````````#@``````````````
+M````````````````!@`````````+`````````!L`````````````````````
+M````'0```````````````````!(`````````'````!H```````````````(`
+M```3```````````````E````#P```!$````0````!P```"(````4````````
+M`````````````````"8````P````(P```````````````````"0````X````
+M`````#L````S```````````````?````*0```"H`````````.0````0```!+
+M````,0```$4`````````/P```$<```````````````@`````````+```````
+M``````````````````"6`0```````*,````2`````P,```````#"````$@``
+M`,$!````````-````!(```#&`@```````#,````2````J`(```````!#````
+M$@```$L!````````2````!(```"N`@`````````````2````E0(```````"A
+M````$@````0!````````;@$``!(````.````B.`$"``````1`/'_R0$`````
+M````````$@```!<`````````/04``!(```!M`````````-0#```2````E@(`
+M``````"A````$@```$("````````6@```!(````U`0```````"H````2````
+M`@,```````":````$@````4"````````E````!(```"B`0```````"T````2
+M````V0(````````S````$@```-@`````````[0```!(```#R````H.($""``
+M```1`!<`N```````````````$@```/,"````````[0```!(```"D`@``````
+M`.<!```2````Q@````````!/````$@```'("````````!0```!(````@`@``
+M`````-D+```2````S@$`````````````$@```"<```#DCP0(`````!(`"@!=
+M`@```````"P!```2````N0$``.3C!`@$````$0`7``L!````````/0```!(`
+M``#J`````````#X````2````[`(````````9````$@```!$"````````(0(`
+M`!(```!)`@``P.($"`0````1`!<`5@(```````!E`@``$@```.L!````X`0(
+M!````!$`$`"^`````````.8"```2````L@`````````M````$@```',`````
+M````]`,``!(```!H`0``Q.($"`0````1`!<`.P(````````T````$@```&<"
+M````````0````!(```#V`0```````!8````2````"`,````````Z`0``$@``
+M`,(!````````.0```!(```#+`@```````.T````2````(0,``)CB!`@`````
+M$`#Q_\\`````````00$``!(````5`P```````$$````2````DP```,CB!`@$
+M````$0`7`'D`````````#@8``!(```#^`0```````'@````2````FP(`````
+M```B!0``$@```"T```!\V`0(`````!(`#0#8`0```````)<"```2````&0(`
+M``````"8````$@```*@```#,X@0(!````!$`%P"M`@```````,L````2````
+M*`(``-#B!`@$````$0`7`&\!````````>@(``!(```"]`@```````,\!```2
+M````?`(```````#.````$@```(8"````````0P```!(```!:`0```````&<&
+M```2````>`$````````J````$@```&X"````````/@```!(````:`P``F.($
+M"``````0`/'_80$```````!5````$@```#,```!TX00(`````!$`\?\M`P``
+M3.0$"``````0`/'_BP(```````!B`P``$@```"L!``#4X@0(!````!$`%P`/
+M`0```````)L(```2````Y`$``-CB!`@$````$0`7`%,!`````````````!(`
+M``"%`0```````!H````2````A`(````````K````$@```+0"````````*0``
+M`!(````4`0`````````````2````Y0(```````"+````$@```*$`````````
+M8````!(```!)```````````````@````&P$```````!]````$@```$(!````
+M`````````!(```"!`````````!0!```2`````&QI8G5T:6PN<V\N.`!?1%E.
+M04U)0P!H=6UA;FEZ95]N=6UB97(`7VEN:70`7V9I;FD`7T=,3T)!3%]/1D93
+M151?5$%"3$5?`%]*=E]296=I<W1E<D-L87-S97,`;&EB;F-U<G-E<RYS;RXX
+M`'1G;W1O`'1P=71S`'1G971E;G0`=&=E='-T<@!L:6)C+G-O+C<`7U]M8E]S
+M8E]L:6UI=`!S=')C<'D`7U]S=&1O=71P`'=A<FYX`&EO8W1L`'-T<FUO9&4`
+M<W1R97)R;W(`<VYP<FEN=&8`86-L7VES7W1R:79I86Q?;G``9G1S7W-E=`!?
+M7W-T86-K7V-H:U]G=6%R9`!G971E;G8`;6%C7V9R964`9V5T<&ED`&%C;%]G
+M971?;&EN:U]N<`!?7W-T9&5R<G``;6%C7V=E=%]L:6YK`')E861L:6YK`&UB
+M<G1O=V,`9V5T=6ED`&UA;&QO8P!I<V%T='D`;W!T87)G`&9T<U]O<&5N`&UA
+M8U]G971?9FEL90!?7W-T86-K7V-H:U]F86EL`&9F;&%G<W1O<W1R`&UA8U]P
+M<F5P87)E7V9I;&5?;&%B96P`96YV:7)O;@!F<')I;G1F`&MI;&P`;'!A=&AC
+M;VYF`&YL7VQA;F=I;F9O`&]P=&EN9`!?7W!R;V=N86UE`%]?97)R;W(`<VEG
+M;F%L`%]?7W)U;F5T>7!E`'-T<F-O;&P`<V5T96YV`')E86QL;V,`7T-U<G)E
+M;G12=6YE3&]C86QE`'-S8V%N9@!S=')D=7``7U]I<W1H<F5A9&5D`&=E=&]P
+M=`!L;V-A;'1I;64`;65M<V5T`&5R<@!?:6YI=%]T;',`7U]S=V)U9@!A=&5X
+M:70`<V5T;&]C86QE`&9P=71C`&9T<U]R96%D`'-T<F9T:6UE`&9W<FET90!A
+M8VQ?9G)E90!G971B<VEZ90!A=&]I`'5S97)?9G)O;5]U:60`;6%C7W1O7W1E
+M>'0`<W1R;&5N`'-T<F-H<@!G<F]U<%]F<F]M7V=I9`!F<'5T<P!F='-?8VAI
+M;&1R96X`=V%R;@!?961A=&$`7U]B<W-?<W1A<G0`7V5N9`!&0E-$7S$N,0!&
+M0E-$7S$N,`````(``@`"``(``@`"``(``@`"``$``@```````@`"``(``@`"
+M``(``@`#``(``@`"``(``@`"``(``P`!``(``0`"``,``@`"``(``@`!``(`
+M`@````(``@`"``(``P`"``(``0`"``(``@````(``P`!``(``@`"``(``@`#
+M``(``@`"``(``@`"``$``@`!``$``@`"``(``@`"``(``@`"``(``@`"````
+M`@`"```````!``(`B0```!``````````L2AZ!P```P`R`P``$````+`H>@<`
+M``(`.P,```````"@X@0(!18``,#B!`@%)0``Q.($"`4K``#(X@0(!34``,SB
+M!`@%/```T.($"`4^``#4X@0(!4L``-CB!`@%30``@.$$"`<!``"$X00(!P(`
+M`(CA!`@'`P``C.$$"`<$``"0X00(!P4``)3A!`@'!@``F.$$"`<'``"<X00(
+M!P@``*#A!`@'"0``I.$$"`<+``"HX00(!PP``*SA!`@'#0``L.$$"`<.``"T
+MX00(!P\``+CA!`@'$```O.$$"`<1``#`X00(!Q(``,3A!`@'$P``R.$$"`<4
+M``#,X00(!Q4``-#A!`@'%P``U.$$"`<8``#8X00(!QD``-SA!`@'&@``X.$$
+M"`<;``#DX00(!QP``.CA!`@''0``[.$$"`<?``#PX00(!R$``/3A!`@'(@``
+M^.$$"`<C``#\X00(!R0```#B!`@')@``!.($"`<H```(X@0(!RD```SB!`@'
+M*@``$.($"`<L```4X@0(!RT``!CB!`@'+@``'.($"`<O```@X@0(!S```"3B
+M!`@',0``*.($"`<S```LX@0(!S0``##B!`@'-@``-.($"`<W```XX@0(!S@`
+M`#SB!`@'.@``0.($"`<[``!$X@0(!ST``$CB!`@'/P``3.($"`=```!0X@0(
+M!T$``%3B!`@'0@``6.($"`=#``!<X@0(!T0``&#B!`@'10``9.($"`='``!H
+MX@0(!TH``&SB!`@'3```<.($"`=.``!TX@0(!T\``'CB!`@'4```?.($"`=1
+M``"`X@0(!U(``(3B!`@'4P``B.($"`=4``",X@0(!U8``)#B!`@'5P``E.($
+M"`=8``"#[`SHZ(/$#,,```#_-7CA!`C_)7SA!`@`````_R6`X00(:`````#I
+M_R6$X00(:`@```#I_R6(X00(:!````#I_R6,X00(:!@```#I_R60X00(:"``
+M``#I_R64X00(:"@```#I_R68X00(:#````#I_R6<X00(:#@```#I_R6@X00(
+M:$````#I_R6DX00(:$@```#I_R6HX00(:%````#I_R6LX00(:%@```#I_R6P
+MX00(:&````#I_R6TX00(:&@```#I_R6XX00(:'````#I_R6\X00(:'@```#I
+M_R7`X00(:(````#I_R7$X00(:(@```#I_R7(X00(:)````#I_R7,X00(:)@`
+M``#I_R70X00(:*````#I_R74X00(:*@```#I_R78X00(:+````#I_R7<X00(
+M:+@```#I_R7@X00(:,````#I_R7DX00(:,@```#I_R7HX00(:-````#I_R7L
+MX00(:-@```#I_R7PX00(:.````#I_R7TX00(:.@```#I_R7XX00(:/````#I
+M_R7\X00(:/@```#I_R4`X@0(:``!``#I_R4$X@0(:`@!``#I_R4(X@0(:!`!
+M``#I_R4,X@0(:!@!``#I_R40X@0(:"`!``#I_R44X@0(:"@!``#I_R48X@0(
+M:#`!``#I_R4<X@0(:#@!``#I_R4@X@0(:$`!``#I_R4DX@0(:$@!``#I_R4H
+MX@0(:%`!``#I_R4LX@0(:%@!``#I_R4PX@0(:&`!``#I_R4TX@0(:&@!``#I
+M_R4XX@0(:'`!``#I_R4\X@0(:'@!``#I_R5`X@0(:(`!``#I_R5$X@0(:(@!
+M``#I_R5(X@0(:)`!``#I_R5,X@0(:)@!``#I_R50X@0(:*`!``#I_R54X@0(
+M:*@!``#I_R58X@0(:+`!``#I_R5<X@0(:+@!``#I_R5@X@0(:,`!``#I_R5D
+MX@0(:,@!``#I_R5HX@0(:-`!``#I_R5LX@0(:-@!``#I_R5PX@0(:.`!``#I
+M_R5TX@0(:.@!``#I_R5XX@0(:/`!``#I_R5\X@0(:/@!``#I_R6`X@0(:``"
+M``#I_R6$X@0(:`@"``#I_R6(X@0(:!`"``#I_R6,X@0(:!@"``#I_R60X@0(
+M:"`"``#I_R64X@0(:"@"``#I```````````Q[56)Y8/D\(U%"(/L!%#_=012
+MZ,R0D)"0D)"058GE5U93@^P,BW4,BUT0A?:-?+,$B3WDXP0(?C6+`X7`="^C
+M`.`$"`^V$(32=".#P`'K"@^V$(/``832=!2`^B]U\:,`X`0(#[80@\`!A-)U
+M[+B(X`0(A<!T-(M%"(D$).C'!"1\V`0(Z.B)?"0(B5PD!(DT).B)!"3HZ.O0
+MD)"0D)"0D)"0D%6)Y8/L"(`]W.($"`!T#.L<@\`$HPC@!`C_TJ$(X`0(BQ"%
+MTG7KQ@7<X@0(`<G#D%6)Y8/L"*%PX00(A<!T$K@`````A<!T"<<$)'#A!`C_
+MT,G#D)"0D)"0D)"0D)"0D%6)Y8/L#(D<)(ET)`2)?"0(BW4,BWT(BT9,BU@T
+MBT@PBT=,BU`TBT`P.=-]%+C_____BQPDBW0D!(M\)`B)[%W#?@VX`0```.OH
+MC;8`````.<%W[SG3?A^+1E")10R+1U")10B+'"2+="0$BWPD"(GL7>E\M#G!
+M<]N-=@#KJXVT)@````"-O"<`````58GEBU4,BT4(B54(B44,7>F-="8`C;PG
+M`````%6)Y8/L"(D<)(ET)`2+=0B+70R+5DR+2TR+0B@Y02A^$+@!````BQPD
+MBW0D!(GL7<-\#XM"+#E!+'_FD(UT)@!]![C_____Z]V+0U")10R+1E")10B+
+M'"2+="0$B>Q=Z8VV`````(V_`````%6)Y8M5#(M%"(E5"(E%#%WIC70F`(V\
+M)P````!5B>6#[`B)'"2)="0$BW4(BUT,BU9,BTM,BT)0.4%0?A"X`0```(L<
+M)(MT)`2)[%W#?`^+0E0Y051_YI"-="8`?0>X_____^O=BT-0B44,BT90B44(
+MBQPDBW0D!(GL7>F-M@````"-OP````!5B>6+50R+10B)50B)10Q=Z8UT)@"-
+MO"<`````58GE@^P(B1PDB70D!(MU"(M=#(M63(M+3(M"&#E!&'X0N`$```"+
+M'"2+="0$B>Q=PWP/BT(<.4$<?^:0C70F`'T'N/_____KW8M#4(E%#(M&4(E%
+M"(L<)(MT)`2)[%WIC;8`````C;\`````58GEBU4,BT4(B54(B44,7>F-="8`
+MC;PG`````%6)Y8/L"(D<)(ET)`2+=0B+70R+5DR+2TR+0B`Y02!^$+@!````
+MBQPDBW0D!(GL7<-\#XM")#E!)'_FD(UT)@!]![C_____Z]V+0U")10R+1E")
+M10B+'"2+="0$B>Q=Z8VV`````(V_`````%6)Y8M5#(M%"(E5"(E%#%WIC70F
+M`(V\)P````!5B>6+10B+50R+0%")10R+0E")10A=Z9"-="8`58GEBT4,BT!0
+MB44,BT4(BT!0B44(7>F0D)"0D%6)Y8/L"(D<)(ET)`2+10B+30R+`(M00(/Z
+M!W1SBQF+2T"#^0=T:8/Z"G1,@_D*=$<YRG0KBW`\A?9U)(LU[.($"(7V=1J#
+MZ@&^`0```'1"@^D!OO____]T.(VV`````(E=#(E%"(L-Y.($"(L<)(MT)`2)
+M[%W_X8E=#(E%"(L<)(MT)`2)[%WIC78`,?:)\(L<)(MT)`2)[%W#D%6)Y5=6
+M4X'L+`4``(F%&/O__Z&@X@0(B47L,<"A0.0$"(F5%/O__XF-$/O__\>%E/O_
+M_P````"%P'4-H43D!`B%P`^$QX5`^___`0```,<$)-S8!`CHQX6(^___````
+M`,>%C/O__P````#'A:#[__\`````QX6<^___`````,>%F/O__P````"%P(G#
+MQX6H^___`````,>%K/O__P````#'A;#[__\`````QX6T^___`````,>%I/O_
+M_P````!T"8`X``^%B[T4^___A?\/A(N%$/O__XN]%/O__\>%+/O__P````#'
+MA3#[__\`````@^`"QX4\^___`````,>%3/O__P````")A0S[___I@_@*#X2+
+MM1C[__^%]@^$BT=0@#@N#X2+1RP[A:S[__]V!HF%K/O__XL5).0$"(72=0J+
+M->SC!`B%]G0=B40D!(M'4(D$).@[A:S[__]V!HF%K/O__XN=0/O__X7;#X2+
+M5TR)T(M(/(N%M/O__XF5*/O__XM2.(G&P?X?.?%\#'\$.<)V!HF5M/O__XN5
+M*/O__XM"!#N%L/O__W8&B86P^___BXTH^___#[=!"CN%J/O__W8&B86H^___
+MBXTH^___BU$T.Y6,^___BT$P?!9_"#N%B/O__W8,B86(^___B96,^___BX4H
+M^___BPU$Y`0(BT`X`84L^___A<D/A(L5`.,$"(72#X2+E2C[__^-==*-7=^+
+M0@S'1"0(]]@$",=$)`0-````B30DB40D#.B+C2C[__^+01#'1"0(]]@$",=$
+M)`0-````B1PDB40D#.B)M43[__^)G4C[__^+A43[__^)!"3H.X68^___B84X
+M^___=@:)A9C[__^+E4C[__^)%"3H.X6<^___B<-V!HF%G/O__Z$\Y`0(QX4T
+M^___`````(7`#X6A".0$"#'2QX64^___`````(7`#X6+M3C[__^+C33[__\!
+MWHU$,1@!T(D$).B%P(G##X2+E43[__^-0!")`XD$)(E4)`3HBXTX^___BY5(
+M^___C409$8E#!(E4)`2)!"3HBXTH^___#[=!""4`\```/0`@```/A#T`8```
+M#X2A/.0$"(7`#X6+#0CD!`B%R71`BY4T^___@\(!@ST\Y`0(`1G`]]`APHN%
+ME/O__XT4%HU4$Q*)4PR)1"0$B10DZ(N%E/O__XD$).B)7Q20C70F`(.%//O_
+M_P&+?PB%_W1-BT=`@_@'#X6+1R")!"3HB40D"(M'4,<$)/#8!`B)1"0$Z,='
+M#`$```#'1Q``````BW\(QP4@XP0(`0```(7_=;.+E3S[__^%T@^$BX44^___
+MBY4\^___B858^___BX6L^___B95@^___B85D^___BX5`^___A<`/A8V%6/O_
+M_XD$)/\5X.($"*%$Y`0(QP4DXP0(`0```(7`="6+O13[__^%_W0;BYT4^___
+MC78`BT,4B00DZ(M;"(7;=>Z+5>PS%:#B!`@/A8'$+`4``%M>7UW#C70F`(L-
+M\.($"(7)#X7'1PP!````QT<0`````.F#Z`$/A8L=[.($"(7;#X7KU(N5*/O_
+M_\=$)`0`````BT(,B00DZ(N-*/O__\=$)`0`````B85$^___BT$0B00DZ(F%
+M2/O__^F#O3#[__\.#X>+E2C[__^+0A0PY#T``0``H3SD!`@9R8/A^8/!#X7`
+MB8TP^___#X2+E4S[__^-1#,2B4,(B00DB50D!.B+C4S[__^)#"3HZ8N-*/O_
+M_XM!1(D$).B%P(F%3/O__P^$@#@`=2*)!"3HQP0D^M@$".B%P(F%3/O__P^$
+MBX5,^___B00DZ#N%H/O__XF%-/O__P^&B86@^___Z8V5D/O__XD4).B#P`$/
+MA(M'/(7`#X6+1U"-M;G[___'1"0(]-@$",=$)`0!!```B30DB40D#.B+A0S[
+M__^%P'1SBX60^___B30DB40D!.B#P`%T<XV%E/O__XE$)`2+A9#[__^)!"3H
+M@\`!=%:+A9#[__^)!"3HBX64^___A<!T<XN%E/O__XD$).@[A:3[__^)P@^&
+MB86D^___Z8N%D/O__XDT)(E$)`3H@\`!=8V+1U")1"0(BT<$BT`<QP0D"-D$
+M"(E$)`3HBX60^___B00DZ(N%E/O__X7`=8W'!"3ZV`0(Z(F%E/O__^F+1U"-
+MM;G[__^)1"00BT<$BT`8QT0D"!;9!`C'1"0$`00``(DT)(E$)`SHZ<>%+/O_
+M_P````#'A3S[__\`````QX4P^___`````*%$Y`0(A<!U#:'XXP0(A<`/A(N%
+M&/O__X7`#X7I,<"#/?CC!`@`#Y7`B85`^___Z8D$).B-1``"B00DZ(7`B84<
+M^___#X0/M@,\.@^$BXT<^___B`&+C1S[__^+A1S[__^#P0'&0`$`#[9#`83`
+M=#V)VNL4B`&#P0'&00$`#[9"`H/"`83`="6`.CIUYSPZ=>/&`3`/MD(!B$$!
+M@\$"QD$!``^V0@*#P@&$P'7;@'G_.@^$C86D^___BY4<^___B40D*(V%K/O_
+M_XE$)"2-A8C[__^)1"0@C86@^___B40D'(V%G/O__XE$)!B-A9C[__^)1"04
+MC86H^___B40D$(V%M/O__XE$)`R-A;#[__^)1"0(QT0D!)39!`B)%"3HQP48
+MY`0(`0```(/X"`^&B[6P^___,<"%]G0@N0$```"X"@```/?A@^X!B<%U\L>%
+ML/O__P````"-0/^+O;3[__^)A;#[__\QP(7_?C6)_KD!````,=MKTPJX"@``
+M`(F5!/O___?AB=.)P0.=!/O__X/N`77AQX6T^___`````(U`_XNUJ/O__XF%
+MM/O__S'`A?9T(+D!````N`H```#WX8/N`8G!=?+'A:C[__\`````C4#_BXV,
+M^___BY6(^___B86H^___@_D`B94@^___B8TD^___#XZ+C2#[__^^`0```#'_
+MBYTD^___:\<*B84$^___N`H```#WYHG7B<8#O03[__^#P?^#T_^)V@G*==J)
+M\(GZ@\#_QX6(^___`````(/2_\>%C/O__P````"+C1S[__^)A8C[__^)E8S[
+M__^)#"3HZ8N-+/O__XU=NHN%M/O__\=$)`@<V00(QT0D!!@```")C5S[__^)
+M1"0,B1PDZ(D<).C'1"0('-D$",=$)`08````B1PDB85H^___BX6@^___B85L
+M^___BX6D^___B85P^___BX6<^___B85T^___BX6P^___B40D#.B)'"3HQT0D
+M"!S9!`C'1"0$&````(D<)(F%>/O__XN%J/O__XE$)`SHB1PDZ(F%?/O__Z'\
+MXP0(A<!T6,>%@/O__P4```"+A3#[__\[A8#[__]V!HF%@/O__XN%F/O__XF%
+MA/O__^F+1U")1"0(BT<$BT`<QP0D"-D$"(E$)`3HZ?\DA?#9!`B+E8S[__^+
+MA8C[___'1"0((-D$",=$)`08````B50D$(E$)`R)'"3HB1PDZ(F%@/O__^E\
+M"H/Z`)`/AS'`,=+IQX6P^___`````,>%M/O__P````#'A:C[__\`````QX68
+M^___`````,>%G/O__P````#'A:#[__\`````QX6(^___`````,>%C/O__P``
+M``#'A:S[__\`````@ST<Y`0(`<>%I/O__P`````9P/?0(048Y`0(Z<=$)`3I
+MV`0(QP0D`0```.AFQP$P`.F+E1S[__^)T8/!`F;'`C`ZQD("`.G'1"0$_-@$
+M",<$)`$```#HZ(VT)@````!5B>575E.#[!R#/?SB!`@!B47LB4WH&<`EP)@$
+M"(E$)`B)3"0$B10DZ(7`B<</A,=$)`0`````B00DZ(7`=`R+3>B)PC'`Z*'L
+MX@0(A<`/A8LU!.,$"(7V#X3'1?``````C;0F`````(D\).B%P(G##X2+0T"#
+M^`(/A(GV#X^#Z`%UU8M+/(7)=`R+0U"`."X/A*$DXP0(A<`/A*'`X@0(A<`/
+MA8L5S.($"(M""(/H`87`B4((#XB+`L8`"H/``8D"BT,<B00DZ,<$)$K9!`CH
+MBT7PB3PDB40D!.B+3>B)PHG&B=CHH03C!`B%P`^%A?8/A(E<)`3'1"0(!```
+M`(D\).B)/"3HA<")PP^%Z(L`A<`/A8/$'%M>7UW#D(/X!'0)@_@'#X6+0R")
+M!"3HB40D"(M#',<$)/#8!`B)1"0$Z,<%(.,$"`$```#ID(M#4,<$)"W9!`B)
+M1"0$Z.F#?>P!#XZ+0QR)!"3HQP0D2MD$".C'!23C!`@!````Z8L=".0$"(7;
+M#X7V1>@(QT7P``$```^%Z:',X@0(QP0D"@```(E$)`3HZ8L5\.($"(72#X3I
+MB50D!,<$)`H```#HZ<=$)`1,V00(QP0D`0```.C'1"0$)-D$",<$)`$```#H
+MC78`C;PG`````(U,)`2#Y/#_<?Q5B>575E-1@>PX!@``BQFAH.($"(E%[#'`
+MC87L_?__BWD$B87D^?__QT0D!,S;!`C'!"0`````Z,<$)`$```#HA<`/A,<%
+M#.`$"%````#'!"15V00(Z(7`=`F`.``/A8V%W/G__XE$)`C'1"0$:'0(0,<$
+M)`$```#H@\`!=!0/MX7>^?__9H7`=`@/M\"C#.`$",<%#.0$"`$```"^$```
+M`,=$)`C(V00(B7PD!(D<).B#^/]T/X/H,8/X1W8PZ.O8QP4,XP0(`0```,<$
+M)%79!`CHA<!TN8D$).BC#.`$".NJ_R2%%-H$"*'8X@0(*<.)A<CY__^A\.($
+M"(F=S/G__X7`#X3'!"1=V00(Z(7`=#O'!"0!````Z(7`#X3'!"1UV00(Z(E$
+M)`2-A>SY__^)!"3H@^@!#X2+%1SD!`B%TG1&QP48Y`0(`0```,=$)`1@L@0(
+MQP0D`@```.C'1"0$8+($",<$)`,```#HQP0DB=D$".B)!"3HH4#D!`B%P'5!
+MH43D!`B%P'4XH?CC!`B%P'4OH13C!`B%P'4FH1CC!`B%P'4=H3#D!`B%P'44
+MBQT<Y`0(A=MU"H/."(VT)@````"+#?CB!`B%R74?BQ5$Y`0(A=)U%:'LX@0(
+MA<!U#*$PY`0(A<!U`X/.`:$<XP0(A<!T!H'.@````*%$Y`0(A<`/A*'HX@0(
+MA<`/A,<%$.0$"`(```"+'0CC!`B%VW1CBPT4XP0(A<D/A8L5&.,$"(72#X2A
+M#.,$",<%Y.($"""6!`B%P'5AH43D!`B%P`^$BX7,^?__QP7@X@0(P,$$"(7`
+M=52)\;H0X`0(N`$```#HZU>A%.,$"(7`#X6A&.,$"(7`#X3'!>3B!`B0E00(
+MH0SC!`B%P'2?QP7@X@0(L+P$"(N%S/G__X7`=*R+A<CY__^)\8T4AXN%S/G_
+M_^BA(.,$"(D$).BA^.,$"(7`#X2AZ.($"(7`#X6-A>CY___'1"0$$.0$"(D$
+M).B+%1#D!`B)T,'X'\'H%P'0P?@)HQ#D!`CIQP0D9MD$".B%P`^%Z8/.(,<%
+M\.($"`$```#IQP4,Y`0(`````,<%).0$"`$```#'!>SC!`@`````Z:'$X@0(
+MH_3C!`CIQP4,XP0(`````,<%1.0$"`````#'!33D!`@`````Z<<%&.,$"`$`
+M``#'!13C!`@`````Z<<%!.,$"`$```#I@^;\@\X0QP7XX@0(`0```.F#YN^#
+MS@+'!?CB!`@`````Z<<%].($"`$```#I@\X!QP7XX@0(`````.G'1"0(`0``
+M`,=$)`3,VP0(QP0D7=D$".CIQP4PY`0(`0```,<%%.0$"`````#IQP4,XP0(
+M`0```,<%1.0$"`````#'!1#C!`@`````Z<<%-.0$"`$```#'!43D!`@`````
+MQP4,XP0(`````.G'!0SD!`@`````QP4DY`0(`````,<%[.,$"`````#IQP4$
+MY`0(`0```,<%Z.,$"`````#'!3CD!`@`````Z<<%%.,$"`$```#'!1CC!`@`
+M````Z<<%^.,$"`$```#IQP4(XP0(`0```.G'!0SD!`@!````QP4DY`0(````
+M`,<%[.,$"`````#IQP44Y`0(`0```,<%,.0$"`$```#IQP4\Y`0(`0```.G'
+M!0#C!`@!````Z<<%$.,$"`$```#'!0SC!`@`````QP5$Y`0(`````.G'!43D
+M!`@!````QP4,XP0(`````,<%$.,$"`````#IQP7\XP0(`````,<%Z.($"`$`
+M``#IQP5`Y`0(`0```.G'!?SC!`@!````Z<<%_.($"`$```#IQP7LX@0(`0``
+M`,<%!.,$"`````#IQP7HXP0(`0```,<%!.0$"`````#'!3CD!`@`````Z<<%
+M#.0$"`````#'!23D!`@`````QP7LXP0(`0```.G'!0CD!`@!````Z<<%'.,$
+M"`$```#IQP4XY`0(`0```,<%!.0$"`````#'!>CC!`@`````Z<<%(.0$"`$`
+M``#IZ(7`#X6A].($"(7`#X7'!?#B!`@!````Z8L=&.,$"(7;#X6+#03D!`B%
+MR0^$QP7DX@0(8)<$".FA&.,$"(7`#X6A!.0$"(7`#X3'!>3B!`C0EP0(Z:$0
+MXP0(A<!T+<<%X.($"(#`!`CIQP7DX@0(@)@$".G'!>3B!`B@F`0(Z<<%X.($
+M"$"]!`CIC9WD^?__B5PD!,<$)'K9!`CHB5PD!,<$)'W9!`BC\.,$".B)7"0$
+MQP0D@-D$"*,LY`0(Z(E<)`3'!"2#V00(HTCD!`CHB5PD!,<$)(;9!`BC*.0$
+M".B%P*,`Y`0(#X2A\.,$"(7`#X2+'2SD!`B%VP^$BPT`Y`0(A<D/A,<%'.0$
+M"`$```#IB00DZ,<%#.0$"`$```"C#.`$".FA..0$"(7`=4FAZ.,$"(7`=$_'
+M!>3B!`BPE@0(Z8L5..0$"(72=1BAZ.,$"(7`=#S'!>3B!`A`E@0(Z<<%Y.($
+M"-"6!`CIQP7DX@0(0)<$".G'!>3B!`A@F`0(Z<<%Y.($"/"7!`CIB5PD!,<$
+M).W8!`CHHP#D!`CID)"0D)"0D)"0D)!5B>6#[!B%P'0]H0#D!`C'1"0(H+($
+M",=$)`0!````B00DZ+B@L@0(B40D"*%(Y`0(QT0D!`$```")!"3HR<.A`.0$
+M",=$)`@`N`0(QT0D!`$```")!"3HN`"X!`CKP9"-="8`58GE4X/L%(M="(G8
+MZ(D<),=$)`0`````Z.B)7"0$B00DZ(/$%%M=PY"-M"8`````58GE@^PHBT4(
+MQT0D"`$```#'!"0!````B$7_C47_B40D!.@QP,G#D(UT)@!5B>575E.#["R+
+M10B%P`^$BT4(,?^)!"3HBQ5@W`0(9L=%V@``QT7<`````(E5X(E%U.L\C70F
+M``^^PH/H,&:#?=H`B0,/A&;'1=H!`(/&`8/#!(/^`G5%@\<!@T7<#(-%X`*#
+M_PL/A(M%W,>`:.,$"`````"-!#\Y1=1W.8M5X`^V`HA%\@^V0@&(1?.-!'\Q
+M]HT<A6#C!`@/ME0N\HU"T#P'=HN-0I\\!W<D#[["@^AAB0/KDXM5"`^V!'J(
+M1?(/MD1Z`8A%\^O#C;8`````C4*_/`=W*P^^PH/H08D#BT7<QX!HXP0(`0``
+M`.G'!"3LVP0(Z.D/MLH[#<CB!`A]#*'0X@0(BXR(-`0``(/Y>'03#[["B40D
+M!,<$)#3<!`CHQP/_____Z8/$+%M>7UW#QT4(S-L$".E5B>564XG#C31`@^P0
+MBQ2U:.,$"(72#X6+!+5@XP0(@_C_=#B)1"0(H?#C!`C'1"0$`````(D$).B%
+MP'0;QT0D"`"X!`C'1"0$`0```(D$).B-=@"-!%N+!(5DXP0(@_C_=#6)1"0(
+MH2SD!`C'1"0$`````(D$).B%P'08QT0D"`"X!`C'1"0$`0```(D$).B#Q!!;
+M7EW#D(UT)@"A*.0$",=$)`@`N`0(QT0D!`$```")!"3HZ8VT)@````"-O"<`
+M````#[?`B<)5@>(`\```B>6#[`B!^@!````/A'Y1@?H`H```#X2!^@#```!T
+M8H'Z`&````^$,=*H271?]L0(#X7VQ`0/A+@(````C70F`.BZ`0```.LXC70F
+M`('Z`!```'18@?H`(```B?9UO;@&````Z+H!````R8G0P[@"````Z+H!````
+MR8G0P[@!````Z+H!````R8G0P[@%````Z+H!````R8G0PXGVN`,```#HN@$`
+M``#)B=##J`)T./;$`G01N`D```#HN@$```#KI[@*````Z+H!````ZY:X!```
+M`.BZ`0```.N%,<#HN@$```#IN`<```#HN@$```"0Z8UT)@"-O"<`````58GE
+M4X/L=(E%F*&@X@0(B47X,<"A+.`$"(7`#XBA1.,$"(7`=':+'?3C!`B%VP^$
+MC468B00DZ(E<)`B-7:C'1"0$4````(D<)(E$)`SHH<SB!`B)'"2)1"0$Z*',
+MX@0(QP0D(````(E$)`3HBT7X,P6@X@0(#X6#Q'1;7<.-M"8`````QP0D````
+M`.B+'?3C!`B%VZ-$XP0(#X60H2#D!`B%P'0[H2S@!`B[--L$"(7`#X6[0-L$
+M".G'!"0Y````Z(`X9`^4P`^VP*,LX`0(Z8M-F(L51.,$"(V!`/'O`#G0?B:-
+M@@#Q[P`YP7T<H2S@!`B[3-L$"(7`#X6[5=L$".F+#2S@!`B[7ML$"(7)#X6[
+M:-L$".GHD(L5).0$"%6)Y8M%"(72=0J+#>SC!`B%R70)B44(7>F+%0SD!`B%
+MTG0)B44(7>F)10A=Z9!5B>6#[`BAP.($"(M-"(7`=2"+%<SB!`B+0@B#Z`&%
+MP(E""'@BBP*("(/``8D"R3'`PZ',X@0(B0PDB40D!.@QP,G#.T(8?`:`^0J0
+M==.)5"0$B0PDZ.O.58GE@^P(BPT4Y`0(A<ET$"4`\```/0!```!T=,DQP,.)
+MPH'B`/```('Z`*````^$#X>!^@`0```/A('Z`$```(UT)@!T/JA)=,:AP.($
+M"(7`#X6+%<SB!`B+0@B#Z`&%P(E""`^(BP+&`"J#P`&)`K@!````R<.0C70F
+M`(L5P.($"(72#X6+%<SB!`B+0@B#Z`&%P(E""`^(BP+&`"^#P`&)`K@!````
+MR<.!^@#````/A('Z`.````^%H<#B!`B%P`^%BQ7,X@0(BT((@^@!A<")0@@/
+MB(L"Q@`E@\`!B0*X`0```,G#H<#B!`B%P`^%BQ7,X@0(BT((@^@!A<")0@@/
+MB(L"Q@!`@\`!B0*X`0```,G#H<SB!`C'!"0O````B40D!.BX`0```,G#H<#B
+M!`B%P`^%BQ7,X@0(BT((@^@!A<")0@@/B(L"Q@`]@\`!B0*X`0```,G#H<#B
+M!`B%P`^%BQ7,X@0(BT((@^@!A<")0@AX;8L"Q@!\@\`!B0*X`0```,G#.T(8
+M#XV)5"0$QP0D+P```.BX`0```,G#H<SB!`C'!"0J````B40D!.BX`0```,G#
+M.T(8#XV)5"0$QP0D0````.BX`0```,G#.T(8?8Z)5"0$QP0D?````.BX`0``
+M`,G#.T(8#XV)5"0$QP0D/0```.BX`0```,G#.T(8#XV)5"0$QP0D)0```.BX
+M`0```,G#H<SB!`C'!"0E````B40D!.BX`0```,G#H<SB!`C'!"1`````B40D
+M!.BX`0```,G#H<SB!`C'!"1\````B40D!.BX`0```,G#H<SB!`C'!"0]````
+MB40D!.BX`0```,G#.T(8#XV)5"0$QP0D*@```.BX`0```,G#C;0F`````(V\
+M)P````!5B>6#[#B)7?2)PXE]_(G/B77XBW!,H4#D!`C'1>P`````A<`/A:'X
+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
+M1E"-C<O[__^)1"00BT8$BT`8QT0D"!;9!`C'1"0$`00``(D,)(E$)`SHZ8L5
+M).`$"(72#X3IZ(L`B00DZ(V5R_O__XE4)`C'1"0$P-L$"(E$)`RAU.($"(D$
+M).CIQD76*^F)5"0$QP0D"@```.CIB1PDC9W+^___Z(E<)`3'!"3TV`0(Z.E]
+M+9"-M"8`````Z(,X%G0;C8W+^___B4PD!,<$)/38!`CHZ:$DX`0(A<`/A8V=
+MR_O__\=$)`0[````B1PDZ(/X`'X9QP4@X`0(`@```,<%).`$"`$```#I#XWH
+M@S@6#X2-A<O[__^)1"0$QP0D]-@$".CIZ)"0D)"0D%6)Y8/L&*'4X@0(QT0D
+M"$H```#'1"0$`0```,<$)&3<!`B)1"0,Z,<$)`$```#HB?:-O"<`````58GE
+M5U93@>RL````BWT,C95P____BW4(H:#B!`B)1?`QP,=$)`B`````QT0D!```
+M``")%"3HA?_'A6#___\`````=%^-E7#___^-A6S___^)5"0,B7PD"(ET)`2)
+M!"3HA<")PW0Y@_O_=&V#^_X/A(N5;/___X'Z_P```'=*H=#B!`B+1)`TJ0``
+M!`!T*8.%8/___P$!WH7_=:&+5?`S%:#B!`B+A6#___]U9H'$K````%M>7UW#
+MBX5@____C028B85@____Z\V)%"3HZ[6)]HV%</___X/&`8.%8/___P2#[P''
+M1"0(@````,=$)`0`````B00DZ.N6BY5@____C12ZB95@____ZXGHC;8`````
+MC;PG`````%6)Y5=64X'LK````(M%"(L5H.($"(E5\#'2QT0D"(````#'1"0$
+M`````(F%7/___XV%</___XD$).C'A6#___\`````BY5<____C85P____B40D
+M#(V%;/___\=$)`@&````B00DB50D!.B%P(G'#X2#__\/A(/__@^$BYUL____
+M@?O_````#X>AT.($"(M$F#2I```$``^$,?:%_W\WZV:-="8`BQ7,X@0(BX5<
+M____#[8,!HM""(/H`87`B4((#XB+`H@(@\`!B0*#Q@$Y]W0KH<#B!`B%P'3&
+MH<SB!`B+E5S___^)1"0$#[8$%H/&`8D$).@Y]W75BYUL____,<"%VW0H@?O_
+M````#X>AT.($"(M$F#2)PH'B````X`^$B=#!Z!X!O5S___\!A6#____I.T(8
+M#[;9?`F`^PH/A8E4)`2)'"3HZ8L5P.($"(72#X6+%<SB!`B+0@B#Z`&%P(E"
+M"`^(BP+&`#^#P`&)`@&]7/___X.%8/___P'IBQW`X@0(A=L/A8L5S.($"(M"
+M"(/H`87`B4((#XB+`L8`/X/``8D"C95P____@X5<____`8.%8/___P''1"0(
+M@````,=$)`0`````B10DZ.F)'"3HC70F`.FAS.($",<$)#\```")1"0$Z.F+
+M#<#B!`B%R0^%BQ7,X@0(BT((@^@!A<")0@@/B(L"Q@`_@\`!B0*#A6#___\!
+MBU7P,Q6@X@0(BX5@____#X6!Q*P```!;7E]=PZ',X@0(QP0D/P```(E$)`3H
+MZ24```0`@_@!&<"#R`'IB1PDZ.D[0A@/C8E4)`3'!"0_````Z.D[0A@/C8E4
+M)`3'!"0_````Z.FAS.($",<$)#\```")1"0$Z.D[0A@/C8E4)`3'!"0_````
+MZ.GHB?:-O"<`````58GE5U93@>RL````BT4(BQ6@X@0(B57P,=+'1"0(@```
+M`,=$)`0`````B85<____C85P____B00DZ,>%8/___P````"+E5S___^-A7#_
+M__^)1"0,C85L____QT0D"`8```")!"2)5"0$Z(7`B<8/A(/^_@^$@_[_#X0Q
+MVX7V?S/K78L5S.($"(N%7/___P^V#`.+0@B#Z`&%P(E""`^(BP*("(/``8D"
+M@\,!.=YT+(L]P.($"(7_=,6AS.($"(N57/___XE$)`0/M@03@\,!B00DZ#G>
+M==2+G6S___\!M5S___^!^_\```!W<*'0X@0(BT28-*D```0`#X0QP(7;="B!
+M^_\````/AZ'0X@0(BT28-(G"@>(```#@#X2)T,'H'@&%8/___^D[0A@/MOE\
+M"HGX/`H/A8E4)`2)/"3HZ8D<).B0ZXZ-A7#____'1"0(@````,=$)`0`````
+MB00DZ*'`X@0(A<`/A8L5S.($"(N%7/___P^V"(M""(/H`87`B4((#XB+`H@(
+M@\`!B0*#A5S___\!@X5@____`>F+E5S____'!"3TV`0(B50D!.@!A6#___^+
+M5?`S%:#B!`B+A6#___]U:X'$K````%M>7UW#)0``!`"#^`$9P(/(`>F)'"3H
+MZ:',X@0(BY5<____B40D!`^V`HD$).CI.T(8#[;9?`F`^PH/A8E4)`2)'"3H
+MZ>B-=@"-O"<`````58GE5U93@>RL````BT4(BQ6@X@0(B57P,=+'1"0(@```
+M`,=$)`0`````B858____C85P____B00DZ,>%8/___P````"+E5C___^-A7#_
+M__^)1"0,C85L____QT0D"`8```")!"2)5"0$Z(7`B85<____#X2+A5S___^#
+MP`*#^`$/AHN=;/___X'[_P````^'H=#B!`B+1)@TJ0``!``/A(/[(@^$@_M<
+M#X2+O5S___^%_WYO,=OK-8L5S.($"(N%6/___P^V#`.+0@B#Z`&%P(E""`^(
+MBP*("(/``8D"@\,!.YU<____=#"+-<#B!`B%]G3!H<SB!`B+E5C___^)1"0$
+M#[8$$X/#`8D$).@[G5S___]UT(N=;/___S'`A=MT*('[_P````^'H=#B!`B+
+M1)@TB<*!X@```.`/A(G0P>@>`85@____@[U<_____@^$@[U<_____P^$BY5<
+M____`958____Z8.]7/____\/A;\!````,?;ID(UT)@"+%<SB!`B+0@B#Z`&%
+MP(E""`^(BP+&`%R#P`&)`J'`X@0(A<`/A8L5S.($"(G8P.@&#[;`C4@PBT((
+M@^@!A<")0@@/B(L"B`B#P`&)`J'`X@0(A<`/A8L5S.($"(G8P.@#@^`'C4@P
+MBT((@^@!A<")0@@/B(L"B`B#P`&)`J'`X@0(A<`/A8L5S.($"(G8@^`'C4@P
+MBT((@^@!A<")0@@/B(L"B`B#P`&)`H/&`8.%8/___P0Y_@^-H<#B!`B+E5C_
+M__^%P`^V'!8/A*',X@0(QP0D7````(E$)`3HH<#B!`B%P`^$H<SB!`B)1"0$
+MB=C`Z`8/ML"#P#")!"3HH<#B!`B%P`^$C;8`````H<SB!`B)1"0$B=C`Z`.#
+MX`>#P#")!"3HH<#B!`B%P`^$C;0F`````*',X@0(B40D!(G8@^`'@\`PB00D
+MZ.F)]CM"&'P)@/D*#X6)5"0$B0PDZ.F0.T(8#XV)5"0$QP0D7````.CIB?8[
+M0AA\"8#Y"@^%B50D!(D,).CID#M"&'P)@/D*#X6)5"0$B0PDZ.F+#>SC!`B%
+MR700A=MX#('[_P````^.B[U<____A?\/CX.]7/____X/A8M5\#,5H.($"(N%
+M8/___P^%@<2L````6UY?7<.+A5C___^)!"3HB<?KN3M"&`^V\7P*B?`\"@^%
+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
+M+V-R=&XN4RQV(#$N-BXR,BXQ(#(P,#DO,#@O,#,@,#@Z,3,Z,#8@:V5N<VUI
+M=&@@17AP("0````!&P,[%`,```(```!8M___,`,``*CY__],`P``````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M``````````````````````````````````````````````#,VP0(`````&SA
+M!`A0````&.`$"``````N````_____P(```#_______________\4````````
+M``%Z4@`!?`@!&PP$!(@!```8````'````""T__\9`````$,.!$*%`@T%````
+M'````#@```!4]O__AP$```!!#@B%`D(-!46&!(<#`````````0````$````!
+M````70````$```")````#````.2/!`@-````?-@$"`0```!$@00(!0```$R)
+M!`@&````O(,$"`H```!$`P``"P```!`````5``````````,```!TX00(`@``
+M`#`"```4````$0```!<```"TC00($0```'2-!`@2````0````!,````(````
+M_O__;T2-!`C___]O`0```/#__V^0C`0(````````````````````````````
+M````````````````````````````````````_____P````#_____````````
+M``"(X`0(```````````.D`0('I`$""Z0!`@^D`0(3I`$"%Z0!`AND`0(?I`$
+M"(Z0!`B>D`0(KI`$"+Z0!`C.D`0(WI`$".Z0!`C^D`0(#I$$"!Z1!`@ND00(
+M/I$$"$Z1!`A>D00(;I$$"'Z1!`B.D00(GI$$"*Z1!`B^D00(SI$$"-Z1!`CN
+MD00(_I$$"`Z2!`@>D@0(+I($"#Z2!`A.D@0(7I($"&Z2!`A^D@0(CI($")Z2
+M!`BND@0(OI($",Z2!`C>D@0([I($"/Z2!`@.DP0('I,$""Z3!`@^DP0(3I,$
+M"%Z3!`ANDP0(?I,$"(Z3!`B>DP0(KI,$"+Z3!`C.DP0(WI,$".Z3!`C^DP0(
+M#I0$"!Z4!`@NE`0(/I0$"$Z4!`A>E`0(````````````)$9R965"4T0Z('-R
+M8R]L:6(O8W-U+VDS.#8M96QF+V-R=#%?<RY3+'8@,2XQ+C(N-"`R,#$Q+S`Q
+M+S$V(#$P.C0Q.C0W(&MI8B!%>'`@)```)$9R965"4T0Z('-R8R]L:6(O8W-U
+M+V-O;6UO;B]C<G1B<F%N9"YC+'8@,2XV+C(N,2`R,#`Y+S`X+S`S(#`X.C$S
+M.C`V(&ME;G-M:71H($5X<"`D`$=#0SH@*$=.52D@-"XR+C(@,C`P-S`X,S$@
+M<')E<F5L96%S92!;1G)E94)31%T``$=#0SH@*$=.52D@-"XR+C(@,C`P-S`X
+M,S$@<')E<F5L96%S92!;1G)E94)31%T``"1&<F5E0E-$.B!S<F,O8FEN+VQS
+M+V-M<"YC+'8@,2XQ."XQ,"XQ(#(P,#DO,#@O,#,@,#@Z,3,Z,#8@:V5N<VUI
+M=&@@17AP("0`1T-#.B`H1TY5*2`T+C(N,B`R,#`W,#@S,2!P<F5R96QE87-E
+M(%M&<F5E0E-$70``)$9R965"4T0Z('-R8R]B:6XO;',O;',N8RQV(#$N.#8N
+M,BXT(#(P,3`O,#(O,C@@,30Z,#0Z,C`@:F@@17AP("0`1T-#.B`H1TY5*2`T
+M+C(N,B`R,#`W,#@S,2!P<F5R96QE87-E(%M&<F5E0E-$70``)$9R965"4T0Z
+M('-R8R]B:6XO;',O<')I;G0N8RQV(#$N-S@N,BXS(#(P,3`O,#(O,C0@,34Z
+M,C<Z,S$@:F@@17AP("0`1T-#.B`H1TY5*2`T+C(N,B`R,#`W,#@S,2!P<F5R
+M96QE87-E(%M&<F5E0E-$70``)$9R965"4T0Z('-R8R]B:6XO;',O=71I;"YC
+M+'8@,2XT,2XR+C$@,C`P.2\P."\P,R`P.#HQ,SHP-B!K96YS;6ET:"!%>'`@
+M)`!'0T,Z("A'3E4I(#0N,BXR(#(P,#<P.#,Q('!R97)E;&5A<V4@6T9R965"
+M4T1=``!'0T,Z("A'3E4I(#0N,BXR(#(P,#<P.#,Q('!R97)E;&5A<V4@6T9R
+M965"4T1=``!'0T,Z("A'3E4I(#0N,BXR(#(P,#<P.#,Q('!R97)E;&5A<V4@
+M6T9R965"4T1=```N<VAS=')T86(`+FEN=&5R<``N;F]T92Y!0DDM=&%G`"YH
+M87-H`"YD>6YS>6T`+F1Y;G-T<@`N9VYU+G9E<G-I;VX`+F=N=2YV97)S:6]N
+M7W(`+G)E;"YD>6X`+G)E;"YP;'0`+FEN:70`+G1E>'0`+F9I;FD`+G)O9&%T
+M80`N96A?9G)A;65?:&1R`"YD871A`"YE:%]F<F%M90`N9'EN86UI8P`N8W1O
+M<G,`+F1T;W)S`"YJ8W(`+F=O=``N8G-S`"YC;VUM96YT````````````````
+M```````````````````````````````````````````+`````0````(````4
+M@00(%`$``!4```````````````$`````````$P````<````"````+($$""P!
+M```8```````````````$`````````"$````%`````@```$2!!`A$`0``>`(`
+M``0`````````!`````0````G````"P````(```"\@P0(O`,``)`%```%````
+M`0````0````0````+P````,````"````3(D$"$P)``!$`P`````````````!
+M`````````#<```#___]O`@```)",!`B0#```L@````0``````````@````(`
+M``!$````_O__;P(```!$C00(1`T``#`````%`````0````0`````````4P``
+M``D````"````=(T$"'0-``!`````!``````````$````"````%P````)````
+M`@```+2-!`BT#0``,`(```0````+````!`````@```!E`````0````8```#D
+MCP0(Y`\``!$```````````````0`````````8`````$````&````^(\$"/@/
+M``!P!``````````````$````!````&L````!````!@```'"4!`AP%```#$0`
+M````````````$`````````!Q`````0````8```!\V`0(?%@```P`````````
+M``````0`````````=P````$````"````B-@$"(A8``".!``````````````$
+M`````````'\````!`````@```!C=!`@870``'```````````````!```````
+M``"-`````0````,`````X`0(`&```#````````````````0`````````DP``
+M``$````"````,.`$"#!@``!8```````````````$`````````)T````&````
+M`P```(C@!`B(8```V`````4`````````!`````@```"F`````0````,```!@
+MX00(8&$```@```````````````0`````````K0````$````#````:.$$"&AA
+M```(```````````````$`````````+0````!`````P```'#A!`AP80``!```
+M````````````!`````````"Y`````0````,```!TX00(=&$``"0!````````
+M``````0````$````O@````@````#````H.($"*!B``"L`0`````````````@
+M`````````,,````!``````````````"@8@``00,``````````````0``````
+M```!`````P``````````````X64``,P```````````````$````````````5
+M8```6%```!20```3Z```$^@```_D```HH```$U@``!&(```0B```2?```!*H
+M```2J```%!@``!08```3:```%"@``!0H```4*```$[@``!%X```2*```$[@`
+M`!*8```16```%"@``!.X```0"```$[@``!#8```4&```$1@``!*H```3>```
+M$2@``!'(```4&```$.@``!*X```1R```$-@``!*H```4&```$V@``!)(```3
+MN```$J@``!08```2J```%!@``!*H```4&```$K@``!*H```4&```$X@``!.(
+M```3V```$R@``!)X```98```$N@``#?````0&```$G@``!E@```1V```$N@`
+M`!)H```1>```$B@``!(H```WP```$!@``!#(```32```$X@``!.(```3J```
+M$Y@``!"(```12```$@@``$FP```0B```$#@``!"(```3F```$(@``!+(```2
+MV```$M@``!"(```RT```)@```"8````36```$S@``!"(```3"```$\@``!18
+M```46```%%@``!18```46```$#@``!18```2.```$C@``!(X```Q\```$M@`
+M`!0(```0F```$&@``!08```2*```$B@``!"X```2.```$+@``!(X```2.```
+M-#```#0P```T,```-#```#0P```T,```-#```#0P```T,```-#```#0P```1
+MN```$6@``!#X```0>```$$@``!+X```3V```$,@``!-(```0R```$T@``!#(
+M```32```$T@``!-(```32```$,@``!#(```0R```$,@``!-(```U$```-\``
+M`#A@```WP```,?```%;````2B```$H@``#N````0R```$T@``#N````0R```
+M$T@``!#(```32```$H@``!&8```2N```$H@``!08```[@```$,@``!#(```3
+M2```$T@``!(8```2J```$:@``!0X```1.```$_@``!*(```0J```$H@``#9@
+M```WP```,?```!*(```2J```$H@``#9@```U$```$H@``!*(``!6P```$H@`
+M`!*(```0R```.&```!*H```42```$H@``#?````2J```$H@``#9@```V8```
+M$J@``!*H```2:```$7@``!`H```32```$_@``!*X```2:```$K@``!&H```2
+M:```$K@``!/8```3&```$U@``!)8```06```$0@``!)8```3V```$E@``!!8
+M```0R```$T@``!)8```1"```$,@``!#(```1"```$T@``!-(```0R```$T@`
+M`!/8```26```$%@``!#(```32```$0@``!)8```2B```$0@``!#(```32```
+M$]@``!)8```06```$,@``!#(```0R```$,@``!#(```32```$T@``!-(```3
+M2```%!@``!-(```1"```$E@``!'H```1"```$,@``!#(```32```$T@``!/8
+M```5,```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@`
+M``_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```
+M#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/
+M^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X
+M```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@`
+M``_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```
+M#_@```_X```/^```#_@``!'X```5D```$?@``!9````1^```%M```!'X```7
+M8```$?@``!?P```1^```$?@``!B@```A1```(5L``"#]```=7@``'6H``!YQ
+M```>4```'5```!U0```>B@``'S$``!^B```EJ0``'LT``![-```?!0``&H$`
+M`"$;```CMP``)?0``!JD```=5P``&J0``!JD```<````'/$``!S^```<_@``
+M)>```"7@```<5P``'%<``"2R```@R0``''```!QP```@/P``'^D``!XR```=
+MN0``'C(``!FR```EJ0``)<<``"6]```DU```)1H``!HQ```=ZP``(#4``"2-
+M```C00``(Y@``")U```A\@``(:,``"B"```G=P``*`@``"=H```GP```)X``
+M`"A&```GV```*"P``"A9```F@```)H```":2```H;@``)H```":````F@```
+M)Q```"<0```F<@``)H```"9R```F^0``)H```":^```F^0``*8L``#$P```O
+MOP``+#H``#"!```K[0``+`<``#`3```P5```,#P``"_H```P8P``*QP``"L2
+M```K'```*?\``"HF```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,`
+M`"EC```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC```I8P``
+M*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC```I
+M8P``*6,``"EC```I8P``*6,``"EC```IVP``*=L``"G;```KHP``,6T``"NM
+M```K0@``,4P``"NM```KP```*ZT``"NM```KP```,<L``"HF```J)@``*B8`
+M`"HP```I7@``*ZT``"NM```KK0``*ZT``"NM```KK0``,/@``#0D```ST0``
+M-!P``#,I```S(P``,RD``#+D```TX```-$P``#7S```UN```-<L``#9````V
+M'@``-;0``#6T```W10``-R```#>Z```VF```-I@``#:8```V@0``-I@``#:8
+M```VF```-I@``%$0``!+(```3H```#ES```Y)@``.?D``#I*```[4@``.:@`
+M`#HJ```YQ```.+(``#KB```ZP@``.OX``#IF```[-@``.J(``#L:```Y%0``
+M.9<``#GH```Y8@``.-H``#R(```[LP``.ZH``$`\``!`*@``/^L``#_K```_
+MN@``/X0``#]R```_A```/X0``#YT```^K0``/DT``#XT```^-```/+```#UP
+M``!!5```09(``$"@``!!$```11P``$4<``!$]P``1J@``$95``!#5```0U0`
+M`$-4``!(>P``1_4``$@U``!)!@``21H``$CC``!(Q0``1C```$8(``!%<```
+M17```$>P``!%WP``1^4``$?3``!%]```1O```$<```!&T```2,X``$(```!)
+MI0``0?4``$>```!$4P``1((``$2"``!#M```0Z<``$(N``!"(```1/<``$2U
+M``!(1P``2(X``$3)``!%N```1$8``$1U``!$=0``0L$``$-4``!#`P``1S``
+M`$-4``!"@```1,D``$-,``!$]P``0U0``$-4``!#`P``0P,``$@U``!(-0``
+M0U0``$K]``!-I0``3.0``$UO``!-1```3*,``$R!``!-\0``3=\``$MH``!,
+M`0``3`H``$U5``!-_@``2V@``$W%``!.'```2V@``$O)``!,T@``3CH``$Y4
+M``!.<@``31,``$QP``!,70``3,@``$S2``!-"0``31,``$V>``!-E```39X`
+M`%"%``!0:0``4`(``$_4``!.R```4+,``%"A``!.R```3S<``$]```!0P```
+M4-\``$[(``!/R0``3[8``%!6``!030``4%8``%44``!2L@``56D``%3?``!4
+MWP``5-\``%5&``!60```5B@``%44``!5=@``45@``%4T``!3J```5(```%/A
+M``!48```5!```%2@``!40```5,```%*'``!2T```4OX``%,V``!3;@``4Y8`
+M`%,@``!3*0``4N<``%+Q``!36```4V$``%.-``!3E@``5:```%+$``!2E```
+M5KH``%()``!2$@``4;T``%%8``!4^0``5F0``%9^``!6G```4H<``%*'``!2
+M;@``5>P``%7B``!5[```5A,``%8<``!7H@``5\```%<&``!7!@``5T```%=`
+M`'__[(*_<*GBTO8J#[&TS@MGB4R]0=<':N.(W\G9G;.:/7*.,11&`00&``0)
+MP)Q>A&R'N"<`!PL!``(!`!0#`P$;!`$!```"`P0,P)Q>P,!J``@*`3U]DI4`
+J``4!$0\`>``X`#8`90!X`&4````4"@$``"U#*W&SG0$5!@$`(0``````
+`
+end
diff --git a/libarchive/test/test_read_format_7zip_bcj2_copy_2.7z.uu b/libarchive/test/test_read_format_7zip_bcj2_copy_2.7z.uu
new file mode 100644
index 000000000000..b3d860e3cadc
--- /dev/null
+++ b/libarchive/test/test_read_format_7zip_bcj2_copy_2.7z.uu
@@ -0,0 +1,615 @@
+begin 644 test_read_format_7zip_bcj2_copy_2.7z
+M-WJ\KR<<``-Y\RJ#YVH```````!K`````````/R]6^=_14Q&`0$!"0``````
+M`````@`#``$```!PE`0(-````+!F````````-``@``<`*``:`!D`!@```#0`
+M```T@`0(-(`$".````#@````!0````0````#````%`$``!2!!`@4@00(%0``
+M`!4````$`````0````$``````````(`$"`"`!`@T70``-%T```4`````$```
+M`0````!@````X`0(`.`$")@"``!,!```!@`````0```"````B&```(C@!`B(
+MX`0(V````-@````&````!`````0````L`0``+($$""R!!`@8````&`````0`
+M```$````4.5T9!A=```8W00(&-T$"!P````<````!`````0````O;&EB97AE
+M8R]L9"UE;&8N<V\N,0`````(````!`````$```!&<F5E0E-$`,<^#`!#````
+M60```$````!5````&``````````]````5``````````\````.@```%(```!&
+M````%P````````!!````-P```$0```!.`````````"T````6````&0````4`
+M``!-````5P```$@`````````'@```"X````G````20``````````````-```
+M`%8```!8````*``````````*````"0````````````````````T````^````
+M-@```%,````,````(````!4````R````(0```"L`````````40```"\```!*
+M````4```````````````0@````````!,````0P````````!/````-0``````
+M```````````````````````````````````````````````````!````````
+M`````````````````````````````P``````````````#@``````````````
+M````````````````!@`````````+`````````!L`````````````````````
+M````'0```````````````````!(`````````'````!H```````````````(`
+M```3```````````````E````#P```!$````0````!P```"(````4````````
+M`````````````````"8````P````(P```````````````````"0````X````
+M`````#L````S```````````````?````*0```"H`````````.0````0```!+
+M````,0```$4`````````/P```$<```````````````@`````````+```````
+M``````````````````"6`0```````*,````2`````P,```````#"````$@``
+M`,$!````````-````!(```#&`@```````#,````2````J`(```````!#````
+M$@```$L!````````2````!(```"N`@`````````````2````E0(```````"A
+M````$@````0!````````;@$``!(````.````B.`$"``````1`/'_R0$`````
+M````````$@```!<`````````/04``!(```!M`````````-0#```2````E@(`
+M``````"A````$@```$("````````6@```!(````U`0```````"H````2````
+M`@,```````":````$@````4"````````E````!(```"B`0```````"T````2
+M````V0(````````S````$@```-@`````````[0```!(```#R````H.($""``
+M```1`!<`N```````````````$@```/,"````````[0```!(```"D`@``````
+M`.<!```2````Q@````````!/````$@```'("````````!0```!(````@`@``
+M`````-D+```2````S@$`````````````$@```"<```#DCP0(`````!(`"@!=
+M`@```````"P!```2````N0$``.3C!`@$````$0`7``L!````````/0```!(`
+M``#J`````````#X````2````[`(````````9````$@```!$"````````(0(`
+M`!(```!)`@``P.($"`0````1`!<`5@(```````!E`@``$@```.L!````X`0(
+M!````!$`$`"^`````````.8"```2````L@`````````M````$@```',`````
+M````]`,``!(```!H`0``Q.($"`0````1`!<`.P(````````T````$@```&<"
+M````````0````!(```#V`0```````!8````2````"`,````````Z`0``$@``
+M`,(!````````.0```!(```#+`@```````.T````2````(0,``)CB!`@`````
+M$`#Q_\\`````````00$``!(````5`P```````$$````2````DP```,CB!`@$
+M````$0`7`'D`````````#@8``!(```#^`0```````'@````2````FP(`````
+M```B!0``$@```"T```!\V`0(`````!(`#0#8`0```````)<"```2````&0(`
+M``````"8````$@```*@```#,X@0(!````!$`%P"M`@```````,L````2````
+M*`(``-#B!`@$````$0`7`&\!````````>@(``!(```"]`@```````,\!```2
+M````?`(```````#.````$@```(8"````````0P```!(```!:`0```````&<&
+M```2````>`$````````J````$@```&X"````````/@```!(````:`P``F.($
+M"``````0`/'_80$```````!5````$@```#,```!TX00(`````!$`\?\M`P``
+M3.0$"``````0`/'_BP(```````!B`P``$@```"L!``#4X@0(!````!$`%P`/
+M`0```````)L(```2````Y`$``-CB!`@$````$0`7`%,!`````````````!(`
+M``"%`0```````!H````2````A`(````````K````$@```+0"````````*0``
+M`!(````4`0`````````````2````Y0(```````"+````$@```*$`````````
+M8````!(```!)```````````````@````&P$```````!]````$@```$(!````
+M`````````!(```"!`````````!0!```2`````&QI8G5T:6PN<V\N.`!?1%E.
+M04U)0P!H=6UA;FEZ95]N=6UB97(`7VEN:70`7V9I;FD`7T=,3T)!3%]/1D93
+M151?5$%"3$5?`%]*=E]296=I<W1E<D-L87-S97,`;&EB;F-U<G-E<RYS;RXX
+M`'1G;W1O`'1P=71S`'1G971E;G0`=&=E='-T<@!L:6)C+G-O+C<`7U]M8E]S
+M8E]L:6UI=`!S=')C<'D`7U]S=&1O=71P`'=A<FYX`&EO8W1L`'-T<FUO9&4`
+M<W1R97)R;W(`<VYP<FEN=&8`86-L7VES7W1R:79I86Q?;G``9G1S7W-E=`!?
+M7W-T86-K7V-H:U]G=6%R9`!G971E;G8`;6%C7V9R964`9V5T<&ED`&%C;%]G
+M971?;&EN:U]N<`!?7W-T9&5R<G``;6%C7V=E=%]L:6YK`')E861L:6YK`&UB
+M<G1O=V,`9V5T=6ED`&UA;&QO8P!I<V%T='D`;W!T87)G`&9T<U]O<&5N`&UA
+M8U]G971?9FEL90!?7W-T86-K7V-H:U]F86EL`&9F;&%G<W1O<W1R`&UA8U]P
+M<F5P87)E7V9I;&5?;&%B96P`96YV:7)O;@!F<')I;G1F`&MI;&P`;'!A=&AC
+M;VYF`&YL7VQA;F=I;F9O`&]P=&EN9`!?7W!R;V=N86UE`%]?97)R;W(`<VEG
+M;F%L`%]?7W)U;F5T>7!E`'-T<F-O;&P`<V5T96YV`')E86QL;V,`7T-U<G)E
+M;G12=6YE3&]C86QE`'-S8V%N9@!S=')D=7``7U]I<W1H<F5A9&5D`&=E=&]P
+M=`!L;V-A;'1I;64`;65M<V5T`&5R<@!?:6YI=%]T;',`7U]S=V)U9@!A=&5X
+M:70`<V5T;&]C86QE`&9P=71C`&9T<U]R96%D`'-T<F9T:6UE`&9W<FET90!A
+M8VQ?9G)E90!G971B<VEZ90!A=&]I`'5S97)?9G)O;5]U:60`;6%C7W1O7W1E
+M>'0`<W1R;&5N`'-T<F-H<@!G<F]U<%]F<F]M7V=I9`!F<'5T<P!F='-?8VAI
+M;&1R96X`=V%R;@!?961A=&$`7U]B<W-?<W1A<G0`7V5N9`!&0E-$7S$N,0!&
+M0E-$7S$N,`````(``@`"``(``@`"``(``@`"``$``@```````@`"``(``@`"
+M``(``@`#``(``@`"``(``@`"``(``P`!``(``0`"``,``@`"``(``@`!``(`
+M`@````(``@`"``(``P`"``(``0`"``(``@````(``P`!``(``@`"``(``@`#
+M``(``@`"``(``@`"``$``@`!``$``@`"``(``@`"``(``@`"``(``@`"````
+M`@`"```````!``(`B0```!``````````L2AZ!P```P`R`P``$````+`H>@<`
+M``(`.P,```````"@X@0(!18``,#B!`@%)0``Q.($"`4K``#(X@0(!34``,SB
+M!`@%/```T.($"`4^``#4X@0(!4L``-CB!`@%30``@.$$"`<!``"$X00(!P(`
+M`(CA!`@'`P``C.$$"`<$``"0X00(!P4``)3A!`@'!@``F.$$"`<'``"<X00(
+M!P@``*#A!`@'"0``I.$$"`<+``"HX00(!PP``*SA!`@'#0``L.$$"`<.``"T
+MX00(!P\``+CA!`@'$```O.$$"`<1``#`X00(!Q(``,3A!`@'$P``R.$$"`<4
+M``#,X00(!Q4``-#A!`@'%P``U.$$"`<8``#8X00(!QD``-SA!`@'&@``X.$$
+M"`<;``#DX00(!QP``.CA!`@''0``[.$$"`<?``#PX00(!R$``/3A!`@'(@``
+M^.$$"`<C``#\X00(!R0```#B!`@')@``!.($"`<H```(X@0(!RD```SB!`@'
+M*@``$.($"`<L```4X@0(!RT``!CB!`@'+@``'.($"`<O```@X@0(!S```"3B
+M!`@',0``*.($"`<S```LX@0(!S0``##B!`@'-@``-.($"`<W```XX@0(!S@`
+M`#SB!`@'.@``0.($"`<[``!$X@0(!ST``$CB!`@'/P``3.($"`=```!0X@0(
+M!T$``%3B!`@'0@``6.($"`=#``!<X@0(!T0``&#B!`@'10``9.($"`='``!H
+MX@0(!TH``&SB!`@'3```<.($"`=.``!TX@0(!T\``'CB!`@'4```?.($"`=1
+M``"`X@0(!U(``(3B!`@'4P``B.($"`=4``",X@0(!U8``)#B!`@'5P``E.($
+M"`=8``"#[`SHZ(/$#,,```#_-7CA!`C_)7SA!`@`````_R6`X00(:`````#I
+M_R6$X00(:`@```#I_R6(X00(:!````#I_R6,X00(:!@```#I_R60X00(:"``
+M``#I_R64X00(:"@```#I_R68X00(:#````#I_R6<X00(:#@```#I_R6@X00(
+M:$````#I_R6DX00(:$@```#I_R6HX00(:%````#I_R6LX00(:%@```#I_R6P
+MX00(:&````#I_R6TX00(:&@```#I_R6XX00(:'````#I_R6\X00(:'@```#I
+M_R7`X00(:(````#I_R7$X00(:(@```#I_R7(X00(:)````#I_R7,X00(:)@`
+M``#I_R70X00(:*````#I_R74X00(:*@```#I_R78X00(:+````#I_R7<X00(
+M:+@```#I_R7@X00(:,````#I_R7DX00(:,@```#I_R7HX00(:-````#I_R7L
+MX00(:-@```#I_R7PX00(:.````#I_R7TX00(:.@```#I_R7XX00(:/````#I
+M_R7\X00(:/@```#I_R4`X@0(:``!``#I_R4$X@0(:`@!``#I_R4(X@0(:!`!
+M``#I_R4,X@0(:!@!``#I_R40X@0(:"`!``#I_R44X@0(:"@!``#I_R48X@0(
+M:#`!``#I_R4<X@0(:#@!``#I_R4@X@0(:$`!``#I_R4DX@0(:$@!``#I_R4H
+MX@0(:%`!``#I_R4LX@0(:%@!``#I_R4PX@0(:&`!``#I_R4TX@0(:&@!``#I
+M_R4XX@0(:'`!``#I_R4\X@0(:'@!``#I_R5`X@0(:(`!``#I_R5$X@0(:(@!
+M``#I_R5(X@0(:)`!``#I_R5,X@0(:)@!``#I_R50X@0(:*`!``#I_R54X@0(
+M:*@!``#I_R58X@0(:+`!``#I_R5<X@0(:+@!``#I_R5@X@0(:,`!``#I_R5D
+MX@0(:,@!``#I_R5HX@0(:-`!``#I_R5LX@0(:-@!``#I_R5PX@0(:.`!``#I
+M_R5TX@0(:.@!``#I_R5XX@0(:/`!``#I_R5\X@0(:/@!``#I_R6`X@0(:``"
+M``#I_R6$X@0(:`@"``#I_R6(X@0(:!`"``#I_R6,X@0(:!@"``#I_R60X@0(
+M:"`"``#I_R64X@0(:"@"``#I```````````Q[56)Y8/D\(U%"(/L!%#_=012
+MZ,R0D)"0D)"058GE5U93@^P,BW4,BUT0A?:-?+,$B3WDXP0(?C6+`X7`="^C
+M`.`$"`^V$(32=".#P`'K"@^V$(/``832=!2`^B]U\:,`X`0(#[80@\`!A-)U
+M[+B(X`0(A<!T-(M%"(D$).C'!"1\V`0(Z.B)?"0(B5PD!(DT).B)!"3HZ.O0
+MD)"0D)"0D)"0D%6)Y8/L"(`]W.($"`!T#.L<@\`$HPC@!`C_TJ$(X`0(BQ"%
+MTG7KQ@7<X@0(`<G#D%6)Y8/L"*%PX00(A<!T$K@`````A<!T"<<$)'#A!`C_
+MT,G#D)"0D)"0D)"0D)"0D%6)Y8/L#(D<)(ET)`2)?"0(BW4,BWT(BT9,BU@T
+MBT@PBT=,BU`TBT`P.=-]%+C_____BQPDBW0D!(M\)`B)[%W#?@VX`0```.OH
+MC;8`````.<%W[SG3?A^+1E")10R+1U")10B+'"2+="0$BWPD"(GL7>E\M#G!
+M<]N-=@#KJXVT)@````"-O"<`````58GEBU4,BT4(B54(B44,7>F-="8`C;PG
+M`````%6)Y8/L"(D<)(ET)`2+=0B+70R+5DR+2TR+0B@Y02A^$+@!````BQPD
+MBW0D!(GL7<-\#XM"+#E!+'_FD(UT)@!]![C_____Z]V+0U")10R+1E")10B+
+M'"2+="0$B>Q=Z8VV`````(V_`````%6)Y8M5#(M%"(E5"(E%#%WIC70F`(V\
+M)P````!5B>6#[`B)'"2)="0$BW4(BUT,BU9,BTM,BT)0.4%0?A"X`0```(L<
+M)(MT)`2)[%W#?`^+0E0Y051_YI"-="8`?0>X_____^O=BT-0B44,BT90B44(
+MBQPDBW0D!(GL7>F-M@````"-OP````!5B>6+50R+10B)50B)10Q=Z8UT)@"-
+MO"<`````58GE@^P(B1PDB70D!(MU"(M=#(M63(M+3(M"&#E!&'X0N`$```"+
+M'"2+="0$B>Q=PWP/BT(<.4$<?^:0C70F`'T'N/_____KW8M#4(E%#(M&4(E%
+M"(L<)(MT)`2)[%WIC;8`````C;\`````58GEBU4,BT4(B54(B44,7>F-="8`
+MC;PG`````%6)Y8/L"(D<)(ET)`2+=0B+70R+5DR+2TR+0B`Y02!^$+@!````
+MBQPDBW0D!(GL7<-\#XM")#E!)'_FD(UT)@!]![C_____Z]V+0U")10R+1E")
+M10B+'"2+="0$B>Q=Z8VV`````(V_`````%6)Y8M5#(M%"(E5"(E%#%WIC70F
+M`(V\)P````!5B>6+10B+50R+0%")10R+0E")10A=Z9"-="8`58GEBT4,BT!0
+MB44,BT4(BT!0B44(7>F0D)"0D%6)Y8/L"(D<)(ET)`2+10B+30R+`(M00(/Z
+M!W1SBQF+2T"#^0=T:8/Z"G1,@_D*=$<YRG0KBW`\A?9U)(LU[.($"(7V=1J#
+MZ@&^`0```'1"@^D!OO____]T.(VV`````(E=#(E%"(L-Y.($"(L<)(MT)`2)
+M[%W_X8E=#(E%"(L<)(MT)`2)[%WIC78`,?:)\(L<)(MT)`2)[%W#D%6)Y5=6
+M4X'L+`4``(F%&/O__Z&@X@0(B47L,<"A0.0$"(F5%/O__XF-$/O__\>%E/O_
+M_P````"%P'4-H43D!`B%P`^$QX5`^___`0```,<$)-S8!`CHQX6(^___````
+M`,>%C/O__P````#'A:#[__\`````QX6<^___`````,>%F/O__P````"%P(G#
+MQX6H^___`````,>%K/O__P````#'A;#[__\`````QX6T^___`````,>%I/O_
+M_P````!T"8`X``^%B[T4^___A?\/A(N%$/O__XN]%/O__\>%+/O__P````#'
+MA3#[__\`````@^`"QX4\^___`````,>%3/O__P````")A0S[___I@_@*#X2+
+MM1C[__^%]@^$BT=0@#@N#X2+1RP[A:S[__]V!HF%K/O__XL5).0$"(72=0J+
+M->SC!`B%]G0=B40D!(M'4(D$).@[A:S[__]V!HF%K/O__XN=0/O__X7;#X2+
+M5TR)T(M(/(N%M/O__XF5*/O__XM2.(G&P?X?.?%\#'\$.<)V!HF5M/O__XN5
+M*/O__XM"!#N%L/O__W8&B86P^___BXTH^___#[=!"CN%J/O__W8&B86H^___
+MBXTH^___BU$T.Y6,^___BT$P?!9_"#N%B/O__W8,B86(^___B96,^___BX4H
+M^___BPU$Y`0(BT`X`84L^___A<D/A(L5`.,$"(72#X2+E2C[__^-==*-7=^+
+M0@S'1"0(]]@$",=$)`0-````B30DB40D#.B+C2C[__^+01#'1"0(]]@$",=$
+M)`0-````B1PDB40D#.B)M43[__^)G4C[__^+A43[__^)!"3H.X68^___B84X
+M^___=@:)A9C[__^+E4C[__^)%"3H.X6<^___B<-V!HF%G/O__Z$\Y`0(QX4T
+M^___`````(7`#X6A".0$"#'2QX64^___`````(7`#X6+M3C[__^+C33[__\!
+MWHU$,1@!T(D$).B%P(G##X2+E43[__^-0!")`XD$)(E4)`3HBXTX^___BY5(
+M^___C409$8E#!(E4)`2)!"3HBXTH^___#[=!""4`\```/0`@```/A#T`8```
+M#X2A/.0$"(7`#X6+#0CD!`B%R71`BY4T^___@\(!@ST\Y`0(`1G`]]`APHN%
+ME/O__XT4%HU4$Q*)4PR)1"0$B10DZ(N%E/O__XD$).B)7Q20C70F`(.%//O_
+M_P&+?PB%_W1-BT=`@_@'#X6+1R")!"3HB40D"(M'4,<$)/#8!`B)1"0$Z,='
+M#`$```#'1Q``````BW\(QP4@XP0(`0```(7_=;.+E3S[__^%T@^$BX44^___
+MBY4\^___B858^___BX6L^___B95@^___B85D^___BX5`^___A<`/A8V%6/O_
+M_XD$)/\5X.($"*%$Y`0(QP4DXP0(`0```(7`="6+O13[__^%_W0;BYT4^___
+MC78`BT,4B00DZ(M;"(7;=>Z+5>PS%:#B!`@/A8'$+`4``%M>7UW#C70F`(L-
+M\.($"(7)#X7'1PP!````QT<0`````.F#Z`$/A8L=[.($"(7;#X7KU(N5*/O_
+M_\=$)`0`````BT(,B00DZ(N-*/O__\=$)`0`````B85$^___BT$0B00DZ(F%
+M2/O__^F#O3#[__\.#X>+E2C[__^+0A0PY#T``0``H3SD!`@9R8/A^8/!#X7`
+MB8TP^___#X2+E4S[__^-1#,2B4,(B00DB50D!.B+C4S[__^)#"3HZ8N-*/O_
+M_XM!1(D$).B%P(F%3/O__P^$@#@`=2*)!"3HQP0D^M@$".B%P(F%3/O__P^$
+MBX5,^___B00DZ#N%H/O__XF%-/O__P^&B86@^___Z8V5D/O__XD4).B#P`$/
+MA(M'/(7`#X6+1U"-M;G[___'1"0(]-@$",=$)`0!!```B30DB40D#.B+A0S[
+M__^%P'1SBX60^___B30DB40D!.B#P`%T<XV%E/O__XE$)`2+A9#[__^)!"3H
+M@\`!=%:+A9#[__^)!"3HBX64^___A<!T<XN%E/O__XD$).@[A:3[__^)P@^&
+MB86D^___Z8N%D/O__XDT)(E$)`3H@\`!=8V+1U")1"0(BT<$BT`<QP0D"-D$
+M"(E$)`3HBX60^___B00DZ(N%E/O__X7`=8W'!"3ZV`0(Z(F%E/O__^F+1U"-
+MM;G[__^)1"00BT<$BT`8QT0D"!;9!`C'1"0$`00``(DT)(E$)`SHZ<>%+/O_
+M_P````#'A3S[__\`````QX4P^___`````*%$Y`0(A<!U#:'XXP0(A<`/A(N%
+M&/O__X7`#X7I,<"#/?CC!`@`#Y7`B85`^___Z8D$).B-1``"B00DZ(7`B84<
+M^___#X0/M@,\.@^$BXT<^___B`&+C1S[__^+A1S[__^#P0'&0`$`#[9#`83`
+M=#V)VNL4B`&#P0'&00$`#[9"`H/"`83`="6`.CIUYSPZ=>/&`3`/MD(!B$$!
+M@\$"QD$!``^V0@*#P@&$P'7;@'G_.@^$C86D^___BY4<^___B40D*(V%K/O_
+M_XE$)"2-A8C[__^)1"0@C86@^___B40D'(V%G/O__XE$)!B-A9C[__^)1"04
+MC86H^___B40D$(V%M/O__XE$)`R-A;#[__^)1"0(QT0D!)39!`B)%"3HQP48
+MY`0(`0```(/X"`^&B[6P^___,<"%]G0@N0$```"X"@```/?A@^X!B<%U\L>%
+ML/O__P````"-0/^+O;3[__^)A;#[__\QP(7_?C6)_KD!````,=MKTPJX"@``
+M`(F5!/O___?AB=.)P0.=!/O__X/N`77AQX6T^___`````(U`_XNUJ/O__XF%
+MM/O__S'`A?9T(+D!````N`H```#WX8/N`8G!=?+'A:C[__\`````C4#_BXV,
+M^___BY6(^___B86H^___@_D`B94@^___B8TD^___#XZ+C2#[__^^`0```#'_
+MBYTD^___:\<*B84$^___N`H```#WYHG7B<8#O03[__^#P?^#T_^)V@G*==J)
+M\(GZ@\#_QX6(^___`````(/2_\>%C/O__P````"+C1S[__^)A8C[__^)E8S[
+M__^)#"3HZ8N-+/O__XU=NHN%M/O__\=$)`@<V00(QT0D!!@```")C5S[__^)
+M1"0,B1PDZ(D<).C'1"0('-D$",=$)`08````B1PDB85H^___BX6@^___B85L
+M^___BX6D^___B85P^___BX6<^___B85T^___BX6P^___B40D#.B)'"3HQT0D
+M"!S9!`C'1"0$&````(D<)(F%>/O__XN%J/O__XE$)`SHB1PDZ(F%?/O__Z'\
+MXP0(A<!T6,>%@/O__P4```"+A3#[__\[A8#[__]V!HF%@/O__XN%F/O__XF%
+MA/O__^F+1U")1"0(BT<$BT`<QP0D"-D$"(E$)`3HZ?\DA?#9!`B+E8S[__^+
+MA8C[___'1"0((-D$",=$)`08````B50D$(E$)`R)'"3HB1PDZ(F%@/O__^E\
+M"H/Z`)`/AS'`,=+IQX6P^___`````,>%M/O__P````#'A:C[__\`````QX68
+M^___`````,>%G/O__P````#'A:#[__\`````QX6(^___`````,>%C/O__P``
+M``#'A:S[__\`````@ST<Y`0(`<>%I/O__P`````9P/?0(048Y`0(Z<=$)`3I
+MV`0(QP0D`0```.AFQP$P`.F+E1S[__^)T8/!`F;'`C`ZQD("`.G'1"0$_-@$
+M",<$)`$```#HZ(VT)@````!5B>575E.#[!R#/?SB!`@!B47LB4WH&<`EP)@$
+M"(E$)`B)3"0$B10DZ(7`B<</A,=$)`0`````B00DZ(7`=`R+3>B)PC'`Z*'L
+MX@0(A<`/A8LU!.,$"(7V#X3'1?``````C;0F`````(D\).B%P(G##X2+0T"#
+M^`(/A(GV#X^#Z`%UU8M+/(7)=`R+0U"`."X/A*$DXP0(A<`/A*'`X@0(A<`/
+MA8L5S.($"(M""(/H`87`B4((#XB+`L8`"H/``8D"BT,<B00DZ,<$)$K9!`CH
+MBT7PB3PDB40D!.B+3>B)PHG&B=CHH03C!`B%P`^%A?8/A(E<)`3'1"0(!```
+M`(D\).B)/"3HA<")PP^%Z(L`A<`/A8/$'%M>7UW#D(/X!'0)@_@'#X6+0R")
+M!"3HB40D"(M#',<$)/#8!`B)1"0$Z,<%(.,$"`$```#ID(M#4,<$)"W9!`B)
+M1"0$Z.F#?>P!#XZ+0QR)!"3HQP0D2MD$".C'!23C!`@!````Z8L=".0$"(7;
+M#X7V1>@(QT7P``$```^%Z:',X@0(QP0D"@```(E$)`3HZ8L5\.($"(72#X3I
+MB50D!,<$)`H```#HZ<=$)`1,V00(QP0D`0```.C'1"0$)-D$",<$)`$```#H
+MC78`C;PG`````(U,)`2#Y/#_<?Q5B>575E-1@>PX!@``BQFAH.($"(E%[#'`
+MC87L_?__BWD$B87D^?__QT0D!,S;!`C'!"0`````Z,<$)`$```#HA<`/A,<%
+M#.`$"%````#'!"15V00(Z(7`=`F`.``/A8V%W/G__XE$)`C'1"0$:'0(0,<$
+M)`$```#H@\`!=!0/MX7>^?__9H7`=`@/M\"C#.`$",<%#.0$"`$```"^$```
+M`,=$)`C(V00(B7PD!(D<).B#^/]T/X/H,8/X1W8PZ.O8QP4,XP0(`0```,<$
+M)%79!`CHA<!TN8D$).BC#.`$".NJ_R2%%-H$"*'8X@0(*<.)A<CY__^A\.($
+M"(F=S/G__X7`#X3'!"1=V00(Z(7`=#O'!"0!````Z(7`#X3'!"1UV00(Z(E$
+M)`2-A>SY__^)!"3H@^@!#X2+%1SD!`B%TG1&QP48Y`0(`0```,=$)`1@L@0(
+MQP0D`@```.C'1"0$8+($",<$)`,```#HQP0DB=D$".B)!"3HH4#D!`B%P'5!
+MH43D!`B%P'4XH?CC!`B%P'4OH13C!`B%P'4FH1CC!`B%P'4=H3#D!`B%P'44
+MBQT<Y`0(A=MU"H/."(VT)@````"+#?CB!`B%R74?BQ5$Y`0(A=)U%:'LX@0(
+MA<!U#*$PY`0(A<!U`X/.`:$<XP0(A<!T!H'.@````*%$Y`0(A<`/A*'HX@0(
+MA<`/A,<%$.0$"`(```"+'0CC!`B%VW1CBPT4XP0(A<D/A8L5&.,$"(72#X2A
+M#.,$",<%Y.($"""6!`B%P'5AH43D!`B%P`^$BX7,^?__QP7@X@0(P,$$"(7`
+M=52)\;H0X`0(N`$```#HZU>A%.,$"(7`#X6A&.,$"(7`#X3'!>3B!`B0E00(
+MH0SC!`B%P'2?QP7@X@0(L+P$"(N%S/G__X7`=*R+A<CY__^)\8T4AXN%S/G_
+M_^BA(.,$"(D$).BA^.,$"(7`#X2AZ.($"(7`#X6-A>CY___'1"0$$.0$"(D$
+M).B+%1#D!`B)T,'X'\'H%P'0P?@)HQ#D!`CIQP0D9MD$".B%P`^%Z8/.(,<%
+M\.($"`$```#IQP4,Y`0(`````,<%).0$"`$```#'!>SC!`@`````Z:'$X@0(
+MH_3C!`CIQP4,XP0(`````,<%1.0$"`````#'!33D!`@`````Z<<%&.,$"`$`
+M``#'!13C!`@`````Z<<%!.,$"`$```#I@^;\@\X0QP7XX@0(`0```.F#YN^#
+MS@+'!?CB!`@`````Z<<%].($"`$```#I@\X!QP7XX@0(`````.G'1"0(`0``
+M`,=$)`3,VP0(QP0D7=D$".CIQP4PY`0(`0```,<%%.0$"`````#IQP4,XP0(
+M`0```,<%1.0$"`````#'!1#C!`@`````Z<<%-.0$"`$```#'!43D!`@`````
+MQP4,XP0(`````.G'!0SD!`@`````QP4DY`0(`````,<%[.,$"`````#IQP4$
+MY`0(`0```,<%Z.,$"`````#'!3CD!`@`````Z<<%%.,$"`$```#'!1CC!`@`
+M````Z<<%^.,$"`$```#IQP4(XP0(`0```.G'!0SD!`@!````QP4DY`0(````
+M`,<%[.,$"`````#IQP44Y`0(`0```,<%,.0$"`$```#IQP4\Y`0(`0```.G'
+M!0#C!`@!````Z<<%$.,$"`$```#'!0SC!`@`````QP5$Y`0(`````.G'!43D
+M!`@!````QP4,XP0(`````,<%$.,$"`````#IQP7\XP0(`````,<%Z.($"`$`
+M``#IQP5`Y`0(`0```.G'!?SC!`@!````Z<<%_.($"`$```#IQP7LX@0(`0``
+M`,<%!.,$"`````#IQP7HXP0(`0```,<%!.0$"`````#'!3CD!`@`````Z<<%
+M#.0$"`````#'!23D!`@`````QP7LXP0(`0```.G'!0CD!`@!````Z<<%'.,$
+M"`$```#IQP4XY`0(`0```,<%!.0$"`````#'!>CC!`@`````Z<<%(.0$"`$`
+M``#IZ(7`#X6A].($"(7`#X7'!?#B!`@!````Z8L=&.,$"(7;#X6+#03D!`B%
+MR0^$QP7DX@0(8)<$".FA&.,$"(7`#X6A!.0$"(7`#X3'!>3B!`C0EP0(Z:$0
+MXP0(A<!T+<<%X.($"(#`!`CIQP7DX@0(@)@$".G'!>3B!`B@F`0(Z<<%X.($
+M"$"]!`CIC9WD^?__B5PD!,<$)'K9!`CHB5PD!,<$)'W9!`BC\.,$".B)7"0$
+MQP0D@-D$"*,LY`0(Z(E<)`3'!"2#V00(HTCD!`CHB5PD!,<$)(;9!`BC*.0$
+M".B%P*,`Y`0(#X2A\.,$"(7`#X2+'2SD!`B%VP^$BPT`Y`0(A<D/A,<%'.0$
+M"`$```#IB00DZ,<%#.0$"`$```"C#.`$".FA..0$"(7`=4FAZ.,$"(7`=$_'
+M!>3B!`BPE@0(Z8L5..0$"(72=1BAZ.,$"(7`=#S'!>3B!`A`E@0(Z<<%Y.($
+M"-"6!`CIQP7DX@0(0)<$".G'!>3B!`A@F`0(Z<<%Y.($"/"7!`CIB5PD!,<$
+M).W8!`CHHP#D!`CID)"0D)"0D)"0D)!5B>6#[!B%P'0]H0#D!`C'1"0(H+($
+M",=$)`0!````B00DZ+B@L@0(B40D"*%(Y`0(QT0D!`$```")!"3HR<.A`.0$
+M",=$)`@`N`0(QT0D!`$```")!"3HN`"X!`CKP9"-="8`58GE4X/L%(M="(G8
+MZ(D<),=$)`0`````Z.B)7"0$B00DZ(/$%%M=PY"-M"8`````58GE@^PHBT4(
+MQT0D"`$```#'!"0!````B$7_C47_B40D!.@QP,G#D(UT)@!5B>575E.#["R+
+M10B%P`^$BT4(,?^)!"3HBQ5@W`0(9L=%V@``QT7<`````(E5X(E%U.L\C70F
+M``^^PH/H,&:#?=H`B0,/A&;'1=H!`(/&`8/#!(/^`G5%@\<!@T7<#(-%X`*#
+M_PL/A(M%W,>`:.,$"`````"-!#\Y1=1W.8M5X`^V`HA%\@^V0@&(1?.-!'\Q
+M]HT<A6#C!`@/ME0N\HU"T#P'=HN-0I\\!W<D#[["@^AAB0/KDXM5"`^V!'J(
+M1?(/MD1Z`8A%\^O#C;8`````C4*_/`=W*P^^PH/H08D#BT7<QX!HXP0(`0``
+M`.G'!"3LVP0(Z.D/MLH[#<CB!`A]#*'0X@0(BXR(-`0``(/Y>'03#[["B40D
+M!,<$)#3<!`CHQP/_____Z8/$+%M>7UW#QT4(S-L$".E5B>564XG#C31`@^P0
+MBQ2U:.,$"(72#X6+!+5@XP0(@_C_=#B)1"0(H?#C!`C'1"0$`````(D$).B%
+MP'0;QT0D"`"X!`C'1"0$`0```(D$).B-=@"-!%N+!(5DXP0(@_C_=#6)1"0(
+MH2SD!`C'1"0$`````(D$).B%P'08QT0D"`"X!`C'1"0$`0```(D$).B#Q!!;
+M7EW#D(UT)@"A*.0$",=$)`@`N`0(QT0D!`$```")!"3HZ8VT)@````"-O"<`
+M````#[?`B<)5@>(`\```B>6#[`B!^@!````/A'Y1@?H`H```#X2!^@#```!T
+M8H'Z`&````^$,=*H271?]L0(#X7VQ`0/A+@(````C70F`.BZ`0```.LXC70F
+M`('Z`!```'18@?H`(```B?9UO;@&````Z+H!````R8G0P[@"````Z+H!````
+MR8G0P[@!````Z+H!````R8G0P[@%````Z+H!````R8G0PXGVN`,```#HN@$`
+M``#)B=##J`)T./;$`G01N`D```#HN@$```#KI[@*````Z+H!````ZY:X!```
+M`.BZ`0```.N%,<#HN@$```#IN`<```#HN@$```"0Z8UT)@"-O"<`````58GE
+M4X/L=(E%F*&@X@0(B47X,<"A+.`$"(7`#XBA1.,$"(7`=':+'?3C!`B%VP^$
+MC468B00DZ(E<)`B-7:C'1"0$4````(D<)(E$)`SHH<SB!`B)'"2)1"0$Z*',
+MX@0(QP0D(````(E$)`3HBT7X,P6@X@0(#X6#Q'1;7<.-M"8`````QP0D````
+M`.B+'?3C!`B%VZ-$XP0(#X60H2#D!`B%P'0[H2S@!`B[--L$"(7`#X6[0-L$
+M".G'!"0Y````Z(`X9`^4P`^VP*,LX`0(Z8M-F(L51.,$"(V!`/'O`#G0?B:-
+M@@#Q[P`YP7T<H2S@!`B[3-L$"(7`#X6[5=L$".F+#2S@!`B[7ML$"(7)#X6[
+M:-L$".GHD(L5).0$"%6)Y8M%"(72=0J+#>SC!`B%R70)B44(7>F+%0SD!`B%
+MTG0)B44(7>F)10A=Z9!5B>6#[`BAP.($"(M-"(7`=2"+%<SB!`B+0@B#Z`&%
+MP(E""'@BBP*("(/``8D"R3'`PZ',X@0(B0PDB40D!.@QP,G#.T(8?`:`^0J0
+M==.)5"0$B0PDZ.O.58GE@^P(BPT4Y`0(A<ET$"4`\```/0!```!T=,DQP,.)
+MPH'B`/```('Z`*````^$#X>!^@`0```/A('Z`$```(UT)@!T/JA)=,:AP.($
+M"(7`#X6+%<SB!`B+0@B#Z`&%P(E""`^(BP+&`"J#P`&)`K@!````R<.0C70F
+M`(L5P.($"(72#X6+%<SB!`B+0@B#Z`&%P(E""`^(BP+&`"^#P`&)`K@!````
+MR<.!^@#````/A('Z`.````^%H<#B!`B%P`^%BQ7,X@0(BT((@^@!A<")0@@/
+MB(L"Q@`E@\`!B0*X`0```,G#H<#B!`B%P`^%BQ7,X@0(BT((@^@!A<")0@@/
+MB(L"Q@!`@\`!B0*X`0```,G#H<SB!`C'!"0O````B40D!.BX`0```,G#H<#B
+M!`B%P`^%BQ7,X@0(BT((@^@!A<")0@@/B(L"Q@`]@\`!B0*X`0```,G#H<#B
+M!`B%P`^%BQ7,X@0(BT((@^@!A<")0@AX;8L"Q@!\@\`!B0*X`0```,G#.T(8
+M#XV)5"0$QP0D+P```.BX`0```,G#H<SB!`C'!"0J````B40D!.BX`0```,G#
+M.T(8#XV)5"0$QP0D0````.BX`0```,G#.T(8?8Z)5"0$QP0D?````.BX`0``
+M`,G#.T(8#XV)5"0$QP0D/0```.BX`0```,G#.T(8#XV)5"0$QP0D)0```.BX
+M`0```,G#H<SB!`C'!"0E````B40D!.BX`0```,G#H<SB!`C'!"1`````B40D
+M!.BX`0```,G#H<SB!`C'!"1\````B40D!.BX`0```,G#H<SB!`C'!"0]````
+MB40D!.BX`0```,G#.T(8#XV)5"0$QP0D*@```.BX`0```,G#C;0F`````(V\
+M)P````!5B>6#[#B)7?2)PXE]_(G/B77XBW!,H4#D!`C'1>P`````A<`/A:'X
+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
+M1E"-C<O[__^)1"00BT8$BT`8QT0D"!;9!`C'1"0$`00``(D,)(E$)`SHZ8L5
+M).`$"(72#X3IZ(L`B00DZ(V5R_O__XE4)`C'1"0$P-L$"(E$)`RAU.($"(D$
+M).CIQD76*^F)5"0$QP0D"@```.CIB1PDC9W+^___Z(E<)`3'!"3TV`0(Z.E]
+M+9"-M"8`````Z(,X%G0;C8W+^___B4PD!,<$)/38!`CHZ:$DX`0(A<`/A8V=
+MR_O__\=$)`0[````B1PDZ(/X`'X9QP4@X`0(`@```,<%).`$"`$```#I#XWH
+M@S@6#X2-A<O[__^)1"0$QP0D]-@$".CIZ)"0D)"0D%6)Y8/L&*'4X@0(QT0D
+M"$H```#'1"0$`0```,<$)&3<!`B)1"0,Z,<$)`$```#HB?:-O"<`````58GE
+M5U93@>RL````BWT,C95P____BW4(H:#B!`B)1?`QP,=$)`B`````QT0D!```
+M``")%"3HA?_'A6#___\`````=%^-E7#___^-A6S___^)5"0,B7PD"(ET)`2)
+M!"3HA<")PW0Y@_O_=&V#^_X/A(N5;/___X'Z_P```'=*H=#B!`B+1)`TJ0``
+M!`!T*8.%8/___P$!WH7_=:&+5?`S%:#B!`B+A6#___]U9H'$K````%M>7UW#
+MBX5@____C028B85@____Z\V)%"3HZ[6)]HV%</___X/&`8.%8/___P2#[P''
+M1"0(@````,=$)`0`````B00DZ.N6BY5@____C12ZB95@____ZXGHC;8`````
+MC;PG`````%6)Y5=64X'LK````(M%"(L5H.($"(E5\#'2QT0D"(````#'1"0$
+M`````(F%7/___XV%</___XD$).C'A6#___\`````BY5<____C85P____B40D
+M#(V%;/___\=$)`@&````B00DB50D!.B%P(G'#X2#__\/A(/__@^$BYUL____
+M@?O_````#X>AT.($"(M$F#2I```$``^$,?:%_W\WZV:-="8`BQ7,X@0(BX5<
+M____#[8,!HM""(/H`87`B4((#XB+`H@(@\`!B0*#Q@$Y]W0KH<#B!`B%P'3&
+MH<SB!`B+E5S___^)1"0$#[8$%H/&`8D$).@Y]W75BYUL____,<"%VW0H@?O_
+M````#X>AT.($"(M$F#2)PH'B````X`^$B=#!Z!X!O5S___\!A6#____I.T(8
+M#[;9?`F`^PH/A8E4)`2)'"3HZ8L5P.($"(72#X6+%<SB!`B+0@B#Z`&%P(E"
+M"`^(BP+&`#^#P`&)`@&]7/___X.%8/___P'IBQW`X@0(A=L/A8L5S.($"(M"
+M"(/H`87`B4((#XB+`L8`/X/``8D"C95P____@X5<____`8.%8/___P''1"0(
+M@````,=$)`0`````B10DZ.F)'"3HC70F`.FAS.($",<$)#\```")1"0$Z.F+
+M#<#B!`B%R0^%BQ7,X@0(BT((@^@!A<")0@@/B(L"Q@`_@\`!B0*#A6#___\!
+MBU7P,Q6@X@0(BX5@____#X6!Q*P```!;7E]=PZ',X@0(QP0D/P```(E$)`3H
+MZ24```0`@_@!&<"#R`'IB1PDZ.D[0A@/C8E4)`3'!"0_````Z.D[0A@/C8E4
+M)`3'!"0_````Z.FAS.($",<$)#\```")1"0$Z.D[0A@/C8E4)`3'!"0_````
+MZ.GHB?:-O"<`````58GE5U93@>RL````BT4(BQ6@X@0(B57P,=+'1"0(@```
+M`,=$)`0`````B85<____C85P____B00DZ,>%8/___P````"+E5S___^-A7#_
+M__^)1"0,C85L____QT0D"`8```")!"2)5"0$Z(7`B<8/A(/^_@^$@_[_#X0Q
+MVX7V?S/K78L5S.($"(N%7/___P^V#`.+0@B#Z`&%P(E""`^(BP*("(/``8D"
+M@\,!.=YT+(L]P.($"(7_=,6AS.($"(N57/___XE$)`0/M@03@\,!B00DZ#G>
+M==2+G6S___\!M5S___^!^_\```!W<*'0X@0(BT28-*D```0`#X0QP(7;="B!
+M^_\````/AZ'0X@0(BT28-(G"@>(```#@#X2)T,'H'@&%8/___^D[0A@/MOE\
+M"HGX/`H/A8E4)`2)/"3HZ8D<).B0ZXZ-A7#____'1"0(@````,=$)`0`````
+MB00DZ*'`X@0(A<`/A8L5S.($"(N%7/___P^V"(M""(/H`87`B4((#XB+`H@(
+M@\`!B0*#A5S___\!@X5@____`>F+E5S____'!"3TV`0(B50D!.@!A6#___^+
+M5?`S%:#B!`B+A6#___]U:X'$K````%M>7UW#)0``!`"#^`$9P(/(`>F)'"3H
+MZ:',X@0(BY5<____B40D!`^V`HD$).CI.T(8#[;9?`F`^PH/A8E4)`2)'"3H
+MZ>B-=@"-O"<`````58GE5U93@>RL````BT4(BQ6@X@0(B57P,=+'1"0(@```
+M`,=$)`0`````B858____C85P____B00DZ,>%8/___P````"+E5C___^-A7#_
+M__^)1"0,C85L____QT0D"`8```")!"2)5"0$Z(7`B85<____#X2+A5S___^#
+MP`*#^`$/AHN=;/___X'[_P````^'H=#B!`B+1)@TJ0``!``/A(/[(@^$@_M<
+M#X2+O5S___^%_WYO,=OK-8L5S.($"(N%6/___P^V#`.+0@B#Z`&%P(E""`^(
+MBP*("(/``8D"@\,!.YU<____=#"+-<#B!`B%]G3!H<SB!`B+E5C___^)1"0$
+M#[8$$X/#`8D$).@[G5S___]UT(N=;/___S'`A=MT*('[_P````^'H=#B!`B+
+M1)@TB<*!X@```.`/A(G0P>@>`85@____@[U<_____@^$@[U<_____P^$BY5<
+M____`958____Z8.]7/____\/A;\!````,?;ID(UT)@"+%<SB!`B+0@B#Z`&%
+MP(E""`^(BP+&`%R#P`&)`J'`X@0(A<`/A8L5S.($"(G8P.@&#[;`C4@PBT((
+M@^@!A<")0@@/B(L"B`B#P`&)`J'`X@0(A<`/A8L5S.($"(G8P.@#@^`'C4@P
+MBT((@^@!A<")0@@/B(L"B`B#P`&)`J'`X@0(A<`/A8L5S.($"(G8@^`'C4@P
+MBT((@^@!A<")0@@/B(L"B`B#P`&)`H/&`8.%8/___P0Y_@^-H<#B!`B+E5C_
+M__^%P`^V'!8/A*',X@0(QP0D7````(E$)`3HH<#B!`B%P`^$H<SB!`B)1"0$
+MB=C`Z`8/ML"#P#")!"3HH<#B!`B%P`^$C;8`````H<SB!`B)1"0$B=C`Z`.#
+MX`>#P#")!"3HH<#B!`B%P`^$C;0F`````*',X@0(B40D!(G8@^`'@\`PB00D
+MZ.F)]CM"&'P)@/D*#X6)5"0$B0PDZ.F0.T(8#XV)5"0$QP0D7````.CIB?8[
+M0AA\"8#Y"@^%B50D!(D,).CID#M"&'P)@/D*#X6)5"0$B0PDZ.F+#>SC!`B%
+MR700A=MX#('[_P````^.B[U<____A?\/CX.]7/____X/A8M5\#,5H.($"(N%
+M8/___P^%@<2L````6UY?7<.+A5C___^)!"3HB<?KN3M"&`^V\7P*B?`\"@^%
+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
+M+V-R=&XN4RQV(#$N-BXR,BXQ(#(P,#DO,#@O,#,@,#@Z,3,Z,#8@:V5N<VUI
+M=&@@17AP("0````!&P,[%`,```(```!8M___,`,``*CY__],`P``````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M``````````````````````````````````````````````#,VP0(`````&SA
+M!`A0````&.`$"``````N````_____P(```#_______________\4````````
+M``%Z4@`!?`@!&PP$!(@!```8````'````""T__\9`````$,.!$*%`@T%````
+M'````#@```!4]O__AP$```!!#@B%`D(-!46&!(<#`````````0````$````!
+M````70````$```")````#````.2/!`@-````?-@$"`0```!$@00(!0```$R)
+M!`@&````O(,$"`H```!$`P``"P```!`````5``````````,```!TX00(`@``
+M`#`"```4````$0```!<```"TC00($0```'2-!`@2````0````!,````(````
+M_O__;T2-!`C___]O`0```/#__V^0C`0(````````````````````````````
+M````````````````````````````````````_____P````#_____````````
+M``"(X`0(```````````.D`0('I`$""Z0!`@^D`0(3I`$"%Z0!`AND`0(?I`$
+M"(Z0!`B>D`0(KI`$"+Z0!`C.D`0(WI`$".Z0!`C^D`0(#I$$"!Z1!`@ND00(
+M/I$$"$Z1!`A>D00(;I$$"'Z1!`B.D00(GI$$"*Z1!`B^D00(SI$$"-Z1!`CN
+MD00(_I$$"`Z2!`@>D@0(+I($"#Z2!`A.D@0(7I($"&Z2!`A^D@0(CI($")Z2
+M!`BND@0(OI($",Z2!`C>D@0([I($"/Z2!`@.DP0('I,$""Z3!`@^DP0(3I,$
+M"%Z3!`ANDP0(?I,$"(Z3!`B>DP0(KI,$"+Z3!`C.DP0(WI,$".Z3!`C^DP0(
+M#I0$"!Z4!`@NE`0(/I0$"$Z4!`A>E`0(````````````)$9R965"4T0Z('-R
+M8R]L:6(O8W-U+VDS.#8M96QF+V-R=#%?<RY3+'8@,2XQ+C(N-"`R,#$Q+S`Q
+M+S$V(#$P.C0Q.C0W(&MI8B!%>'`@)```)$9R965"4T0Z('-R8R]L:6(O8W-U
+M+V-O;6UO;B]C<G1B<F%N9"YC+'8@,2XV+C(N,2`R,#`Y+S`X+S`S(#`X.C$S
+M.C`V(&ME;G-M:71H($5X<"`D`$=#0SH@*$=.52D@-"XR+C(@,C`P-S`X,S$@
+M<')E<F5L96%S92!;1G)E94)31%T``$=#0SH@*$=.52D@-"XR+C(@,C`P-S`X
+M,S$@<')E<F5L96%S92!;1G)E94)31%T``"1&<F5E0E-$.B!S<F,O8FEN+VQS
+M+V-M<"YC+'8@,2XQ."XQ,"XQ(#(P,#DO,#@O,#,@,#@Z,3,Z,#8@:V5N<VUI
+M=&@@17AP("0`1T-#.B`H1TY5*2`T+C(N,B`R,#`W,#@S,2!P<F5R96QE87-E
+M(%M&<F5E0E-$70``)$9R965"4T0Z('-R8R]B:6XO;',O;',N8RQV(#$N.#8N
+M,BXT(#(P,3`O,#(O,C@@,30Z,#0Z,C`@:F@@17AP("0`1T-#.B`H1TY5*2`T
+M+C(N,B`R,#`W,#@S,2!P<F5R96QE87-E(%M&<F5E0E-$70``)$9R965"4T0Z
+M('-R8R]B:6XO;',O<')I;G0N8RQV(#$N-S@N,BXS(#(P,3`O,#(O,C0@,34Z
+M,C<Z,S$@:F@@17AP("0`1T-#.B`H1TY5*2`T+C(N,B`R,#`W,#@S,2!P<F5R
+M96QE87-E(%M&<F5E0E-$70``)$9R965"4T0Z('-R8R]B:6XO;',O=71I;"YC
+M+'8@,2XT,2XR+C$@,C`P.2\P."\P,R`P.#HQ,SHP-B!K96YS;6ET:"!%>'`@
+M)`!'0T,Z("A'3E4I(#0N,BXR(#(P,#<P.#,Q('!R97)E;&5A<V4@6T9R965"
+M4T1=``!'0T,Z("A'3E4I(#0N,BXR(#(P,#<P.#,Q('!R97)E;&5A<V4@6T9R
+M965"4T1=``!'0T,Z("A'3E4I(#0N,BXR(#(P,#<P.#,Q('!R97)E;&5A<V4@
+M6T9R965"4T1=```N<VAS=')T86(`+FEN=&5R<``N;F]T92Y!0DDM=&%G`"YH
+M87-H`"YD>6YS>6T`+F1Y;G-T<@`N9VYU+G9E<G-I;VX`+F=N=2YV97)S:6]N
+M7W(`+G)E;"YD>6X`+G)E;"YP;'0`+FEN:70`+G1E>'0`+F9I;FD`+G)O9&%T
+M80`N96A?9G)A;65?:&1R`"YD871A`"YE:%]F<F%M90`N9'EN86UI8P`N8W1O
+M<G,`+F1T;W)S`"YJ8W(`+F=O=``N8G-S`"YC;VUM96YT````````````````
+M```````````````````````````````````````````+`````0````(````4
+M@00(%`$``!4```````````````$`````````$P````<````"````+($$""P!
+M```8```````````````$`````````"$````%`````@```$2!!`A$`0``>`(`
+M``0`````````!`````0````G````"P````(```"\@P0(O`,``)`%```%````
+M`0````0````0````+P````,````"````3(D$"$P)``!$`P`````````````!
+M`````````#<```#___]O`@```)",!`B0#```L@````0``````````@````(`
+M``!$````_O__;P(```!$C00(1`T``#`````%`````0````0`````````4P``
+M``D````"````=(T$"'0-``!`````!``````````$````"````%P````)````
+M`@```+2-!`BT#0``,`(```0````+````!`````@```!E`````0````8```#D
+MCP0(Y`\``!$```````````````0`````````8`````$````&````^(\$"/@/
+M``!P!``````````````$````!````&L````!````!@```'"4!`AP%```#$0`
+M````````````$`````````!Q`````0````8```!\V`0(?%@```P`````````
+M``````0`````````=P````$````"````B-@$"(A8``".!``````````````$
+M`````````'\````!`````@```!C=!`@870``'```````````````!```````
+M``"-`````0````,`````X`0(`&```#````````````````0`````````DP``
+M``$````"````,.`$"#!@``!8```````````````$`````````)T````&````
+M`P```(C@!`B(8```V`````4`````````!`````@```"F`````0````,```!@
+MX00(8&$```@```````````````0`````````K0````$````#````:.$$"&AA
+M```(```````````````$`````````+0````!`````P```'#A!`AP80``!```
+M````````````!`````````"Y`````0````,```!TX00(=&$``"0!````````
+M``````0````$````O@````@````#````H.($"*!B``"L`0`````````````@
+M`````````,,````!``````````````"@8@``00,``````````````0``````
+M```!`````P``````````````X64``,P```````````````$````````````5
+M8```6%```!20```3Z```$^@```_D```HH```$U@``!&(```0B```2?```!*H
+M```2J```%!@``!08```3:```%"@``!0H```4*```$[@``!%X```2*```$[@`
+M`!*8```16```%"@``!.X```0"```$[@``!#8```4&```$1@``!*H```3>```
+M$2@``!'(```4&```$.@``!*X```1R```$-@``!*H```4&```$V@``!)(```3
+MN```$J@``!08```2J```%!@``!*H```4&```$K@``!*H```4&```$X@``!.(
+M```3V```$R@``!)X```98```$N@``#?````0&```$G@``!E@```1V```$N@`
+M`!)H```1>```$B@``!(H```WP```$!@``!#(```32```$X@``!.(```3J```
+M$Y@``!"(```12```$@@``$FP```0B```$#@``!"(```3F```$(@``!+(```2
+MV```$M@``!"(```RT```)@```"8````36```$S@``!"(```3"```$\@``!18
+M```46```%%@``!18```46```$#@``!18```2.```$C@``!(X```Q\```$M@`
+M`!0(```0F```$&@``!08```2*```$B@``!"X```2.```$+@``!(X```2.```
+M-#```#0P```T,```-#```#0P```T,```-#```#0P```T,```-#```#0P```1
+MN```$6@``!#X```0>```$$@``!+X```3V```$,@``!-(```0R```$T@``!#(
+M```32```$T@``!-(```32```$,@``!#(```0R```$,@``!-(```U$```-\``
+M`#A@```WP```,?```%;````2B```$H@``#N````0R```$T@``#N````0R```
+M$T@``!#(```32```$H@``!&8```2N```$H@``!08```[@```$,@``!#(```3
+M2```$T@``!(8```2J```$:@``!0X```1.```$_@``!*(```0J```$H@``#9@
+M```WP```,?```!*(```2J```$H@``#9@```U$```$H@``!*(``!6P```$H@`
+M`!*(```0R```.&```!*H```42```$H@``#?````2J```$H@``#9@```V8```
+M$J@``!*H```2:```$7@``!`H```32```$_@``!*X```2:```$K@``!&H```2
+M:```$K@``!/8```3&```$U@``!)8```06```$0@``!)8```3V```$E@``!!8
+M```0R```$T@``!)8```1"```$,@``!#(```1"```$T@``!-(```0R```$T@`
+M`!/8```26```$%@``!#(```32```$0@``!)8```2B```$0@``!#(```32```
+M$]@``!)8```06```$,@``!#(```0R```$,@``!#(```32```$T@``!-(```3
+M2```%!@``!-(```1"```$E@``!'H```1"```$,@``!#(```32```$T@``!/8
+M```5,```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@`
+M``_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```
+M#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/
+M^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X
+M```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@`
+M``_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```
+M#_@```_X```/^```#_@``!'X```5D```$?@``!9````1^```%M```!'X```7
+M8```$?@``!?P```1^```$?@``!B@```A1```(5L``"#]```=7@``'6H``!YQ
+M```>4```'5```!U0```>B@``'S$``!^B```EJ0``'LT``![-```?!0``&H$`
+M`"$;```CMP``)?0``!JD```=5P``&J0``!JD```<````'/$``!S^```<_@``
+M)>```"7@```<5P``'%<``"2R```@R0``''```!QP```@/P``'^D``!XR```=
+MN0``'C(``!FR```EJ0``)<<``"6]```DU```)1H``!HQ```=ZP``(#4``"2-
+M```C00``(Y@``")U```A\@``(:,``"B"```G=P``*`@``"=H```GP```)X``
+M`"A&```GV```*"P``"A9```F@```)H```":2```H;@``)H```":````F@```
+M)Q```"<0```F<@``)H```"9R```F^0``)H```":^```F^0``*8L``#$P```O
+MOP``+#H``#"!```K[0``+`<``#`3```P5```,#P``"_H```P8P``*QP``"L2
+M```K'```*?\``"HF```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,`
+M`"EC```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC```I8P``
+M*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC```I
+M8P``*6,``"EC```I8P``*6,``"EC```IVP``*=L``"G;```KHP``,6T``"NM
+M```K0@``,4P``"NM```KP```*ZT``"NM```KP```,<L``"HF```J)@``*B8`
+M`"HP```I7@``*ZT``"NM```KK0``*ZT``"NM```KK0``,/@``#0D```ST0``
+M-!P``#,I```S(P``,RD``#+D```TX```-$P``#7S```UN```-<L``#9````V
+M'@``-;0``#6T```W10``-R```#>Z```VF```-I@``#:8```V@0``-I@``#:8
+M```VF```-I@``%$0``!+(```3H```#ES```Y)@``.?D``#I*```[4@``.:@`
+M`#HJ```YQ```.+(``#KB```ZP@``.OX``#IF```[-@``.J(``#L:```Y%0``
+M.9<``#GH```Y8@``.-H``#R(```[LP``.ZH``$`\``!`*@``/^L``#_K```_
+MN@``/X0``#]R```_A```/X0``#YT```^K0``/DT``#XT```^-```/+```#UP
+M``!!5```09(``$"@``!!$```11P``$4<``!$]P``1J@``$95``!#5```0U0`
+M`$-4``!(>P``1_4``$@U``!)!@``21H``$CC``!(Q0``1C```$8(``!%<```
+M17```$>P``!%WP``1^4``$?3``!%]```1O```$<```!&T```2,X``$(```!)
+MI0``0?4``$>```!$4P``1((``$2"``!#M```0Z<``$(N``!"(```1/<``$2U
+M``!(1P``2(X``$3)``!%N```1$8``$1U``!$=0``0L$``$-4``!#`P``1S``
+M`$-4``!"@```1,D``$-,``!$]P``0U0``$-4``!#`P``0P,``$@U``!(-0``
+M0U0``$K]``!-I0``3.0``$UO``!-1```3*,``$R!``!-\0``3=\``$MH``!,
+M`0``3`H``$U5``!-_@``2V@``$W%``!.'```2V@``$O)``!,T@``3CH``$Y4
+M``!.<@``31,``$QP``!,70``3,@``$S2``!-"0``31,``$V>``!-E```39X`
+M`%"%``!0:0``4`(``$_4``!.R```4+,``%"A``!.R```3S<``$]```!0P```
+M4-\``$[(``!/R0``3[8``%!6``!030``4%8``%44``!2L@``56D``%3?``!4
+MWP``5-\``%5&``!60```5B@``%44``!5=@``45@``%4T``!3J```5(```%/A
+M``!48```5!```%2@``!40```5,```%*'``!2T```4OX``%,V``!3;@``4Y8`
+M`%,@``!3*0``4N<``%+Q``!36```4V$``%.-``!3E@``5:```%+$``!2E```
+M5KH``%()``!2$@``4;T``%%8``!4^0``5F0``%9^``!6G```4H<``%*'``!2
+M;@``5>P``%7B``!5[```5A,``%8<``!7H@``5\```%<&``!7!@``5T```%=`
+M`'__[(*_<*GBTO8J#[&TS@MGB4R]0=<':N.(W\G9G;.:/7*.,11&`00&``0)
+MP)Q>A&R'N"<`!PL!``0!``$``0`4`P,!&P0!`0`"`0,"``0%!@S`G%[`G%[`
+MG%[`P&H`"`H!/7V2E0``!0$1#P!X`#@`-@!E`'@`90```!0*`0``+4,K<;.=
++`14&`0`A````````
+`
+end
diff --git a/libarchive/test/test_read_format_7zip_bcj2_copy_lzma.7z.uu b/libarchive/test/test_read_format_7zip_bcj2_copy_lzma.7z.uu
new file mode 100644
index 000000000000..ff1ce4a5509b
--- /dev/null
+++ b/libarchive/test/test_read_format_7zip_bcj2_copy_lzma.7z.uu
@@ -0,0 +1,568 @@
+begin 644 test_read_format_7zip_bcj2_copy_lzma.7z
+M-WJ\KR<<``-+E]7GI6(```````!Y`````````%QS)"Q_14Q&`0$!"0``````
+M`````@`#``$```!PE`0(-````+!F````````-``@``<`*``:`!D`!@```#0`
+M```T@`0(-(`$".````#@````!0````0````#````%`$``!2!!`@4@00(%0``
+M`!4````$`````0````$``````````(`$"`"`!`@T70``-%T```4`````$```
+M`0````!@````X`0(`.`$")@"``!,!```!@`````0```"````B&```(C@!`B(
+MX`0(V````-@````&````!`````0````L`0``+($$""R!!`@8````&`````0`
+M```$````4.5T9!A=```8W00(&-T$"!P````<````!`````0````O;&EB97AE
+M8R]L9"UE;&8N<V\N,0`````(````!`````$```!&<F5E0E-$`,<^#`!#````
+M60```$````!5````&``````````]````5``````````\````.@```%(```!&
+M````%P````````!!````-P```$0```!.`````````"T````6````&0````4`
+M``!-````5P```$@`````````'@```"X````G````20``````````````-```
+M`%8```!8````*``````````*````"0````````````````````T````^````
+M-@```%,````,````(````!4````R````(0```"L`````````40```"\```!*
+M````4```````````````0@````````!,````0P````````!/````-0``````
+M```````````````````````````````````````````````````!````````
+M`````````````````````````````P``````````````#@``````````````
+M````````````````!@`````````+`````````!L`````````````````````
+M````'0```````````````````!(`````````'````!H```````````````(`
+M```3```````````````E````#P```!$````0````!P```"(````4````````
+M`````````````````"8````P````(P```````````````````"0````X````
+M`````#L````S```````````````?````*0```"H`````````.0````0```!+
+M````,0```$4`````````/P```$<```````````````@`````````+```````
+M``````````````````"6`0```````*,````2`````P,```````#"````$@``
+M`,$!````````-````!(```#&`@```````#,````2````J`(```````!#````
+M$@```$L!````````2````!(```"N`@`````````````2````E0(```````"A
+M````$@````0!````````;@$``!(````.````B.`$"``````1`/'_R0$`````
+M````````$@```!<`````````/04``!(```!M`````````-0#```2````E@(`
+M``````"A````$@```$("````````6@```!(````U`0```````"H````2````
+M`@,```````":````$@````4"````````E````!(```"B`0```````"T````2
+M````V0(````````S````$@```-@`````````[0```!(```#R````H.($""``
+M```1`!<`N```````````````$@```/,"````````[0```!(```"D`@``````
+M`.<!```2````Q@````````!/````$@```'("````````!0```!(````@`@``
+M`````-D+```2````S@$`````````````$@```"<```#DCP0(`````!(`"@!=
+M`@```````"P!```2````N0$``.3C!`@$````$0`7``L!````````/0```!(`
+M``#J`````````#X````2````[`(````````9````$@```!$"````````(0(`
+M`!(```!)`@``P.($"`0````1`!<`5@(```````!E`@``$@```.L!````X`0(
+M!````!$`$`"^`````````.8"```2````L@`````````M````$@```',`````
+M````]`,``!(```!H`0``Q.($"`0````1`!<`.P(````````T````$@```&<"
+M````````0````!(```#V`0```````!8````2````"`,````````Z`0``$@``
+M`,(!````````.0```!(```#+`@```````.T````2````(0,``)CB!`@`````
+M$`#Q_\\`````````00$``!(````5`P```````$$````2````DP```,CB!`@$
+M````$0`7`'D`````````#@8``!(```#^`0```````'@````2````FP(`````
+M```B!0``$@```"T```!\V`0(`````!(`#0#8`0```````)<"```2````&0(`
+M``````"8````$@```*@```#,X@0(!````!$`%P"M`@```````,L````2````
+M*`(``-#B!`@$````$0`7`&\!````````>@(``!(```"]`@```````,\!```2
+M````?`(```````#.````$@```(8"````````0P```!(```!:`0```````&<&
+M```2````>`$````````J````$@```&X"````````/@```!(````:`P``F.($
+M"``````0`/'_80$```````!5````$@```#,```!TX00(`````!$`\?\M`P``
+M3.0$"``````0`/'_BP(```````!B`P``$@```"L!``#4X@0(!````!$`%P`/
+M`0```````)L(```2````Y`$``-CB!`@$````$0`7`%,!`````````````!(`
+M``"%`0```````!H````2````A`(````````K````$@```+0"````````*0``
+M`!(````4`0`````````````2````Y0(```````"+````$@```*$`````````
+M8````!(```!)```````````````@````&P$```````!]````$@```$(!````
+M`````````!(```"!`````````!0!```2`````&QI8G5T:6PN<V\N.`!?1%E.
+M04U)0P!H=6UA;FEZ95]N=6UB97(`7VEN:70`7V9I;FD`7T=,3T)!3%]/1D93
+M151?5$%"3$5?`%]*=E]296=I<W1E<D-L87-S97,`;&EB;F-U<G-E<RYS;RXX
+M`'1G;W1O`'1P=71S`'1G971E;G0`=&=E='-T<@!L:6)C+G-O+C<`7U]M8E]S
+M8E]L:6UI=`!S=')C<'D`7U]S=&1O=71P`'=A<FYX`&EO8W1L`'-T<FUO9&4`
+M<W1R97)R;W(`<VYP<FEN=&8`86-L7VES7W1R:79I86Q?;G``9G1S7W-E=`!?
+M7W-T86-K7V-H:U]G=6%R9`!G971E;G8`;6%C7V9R964`9V5T<&ED`&%C;%]G
+M971?;&EN:U]N<`!?7W-T9&5R<G``;6%C7V=E=%]L:6YK`')E861L:6YK`&UB
+M<G1O=V,`9V5T=6ED`&UA;&QO8P!I<V%T='D`;W!T87)G`&9T<U]O<&5N`&UA
+M8U]G971?9FEL90!?7W-T86-K7V-H:U]F86EL`&9F;&%G<W1O<W1R`&UA8U]P
+M<F5P87)E7V9I;&5?;&%B96P`96YV:7)O;@!F<')I;G1F`&MI;&P`;'!A=&AC
+M;VYF`&YL7VQA;F=I;F9O`&]P=&EN9`!?7W!R;V=N86UE`%]?97)R;W(`<VEG
+M;F%L`%]?7W)U;F5T>7!E`'-T<F-O;&P`<V5T96YV`')E86QL;V,`7T-U<G)E
+M;G12=6YE3&]C86QE`'-S8V%N9@!S=')D=7``7U]I<W1H<F5A9&5D`&=E=&]P
+M=`!L;V-A;'1I;64`;65M<V5T`&5R<@!?:6YI=%]T;',`7U]S=V)U9@!A=&5X
+M:70`<V5T;&]C86QE`&9P=71C`&9T<U]R96%D`'-T<F9T:6UE`&9W<FET90!A
+M8VQ?9G)E90!G971B<VEZ90!A=&]I`'5S97)?9G)O;5]U:60`;6%C7W1O7W1E
+M>'0`<W1R;&5N`'-T<F-H<@!G<F]U<%]F<F]M7V=I9`!F<'5T<P!F='-?8VAI
+M;&1R96X`=V%R;@!?961A=&$`7U]B<W-?<W1A<G0`7V5N9`!&0E-$7S$N,0!&
+M0E-$7S$N,`````(``@`"``(``@`"``(``@`"``$``@```````@`"``(``@`"
+M``(``@`#``(``@`"``(``@`"``(``P`!``(``0`"``,``@`"``(``@`!``(`
+M`@````(``@`"``(``P`"``(``0`"``(``@````(``P`!``(``@`"``(``@`#
+M``(``@`"``(``@`"``$``@`!``$``@`"``(``@`"``(``@`"``(``@`"````
+M`@`"```````!``(`B0```!``````````L2AZ!P```P`R`P``$````+`H>@<`
+M``(`.P,```````"@X@0(!18``,#B!`@%)0``Q.($"`4K``#(X@0(!34``,SB
+M!`@%/```T.($"`4^``#4X@0(!4L``-CB!`@%30``@.$$"`<!``"$X00(!P(`
+M`(CA!`@'`P``C.$$"`<$``"0X00(!P4``)3A!`@'!@``F.$$"`<'``"<X00(
+M!P@``*#A!`@'"0``I.$$"`<+``"HX00(!PP``*SA!`@'#0``L.$$"`<.``"T
+MX00(!P\``+CA!`@'$```O.$$"`<1``#`X00(!Q(``,3A!`@'$P``R.$$"`<4
+M``#,X00(!Q4``-#A!`@'%P``U.$$"`<8``#8X00(!QD``-SA!`@'&@``X.$$
+M"`<;``#DX00(!QP``.CA!`@''0``[.$$"`<?``#PX00(!R$``/3A!`@'(@``
+M^.$$"`<C``#\X00(!R0```#B!`@')@``!.($"`<H```(X@0(!RD```SB!`@'
+M*@``$.($"`<L```4X@0(!RT``!CB!`@'+@``'.($"`<O```@X@0(!S```"3B
+M!`@',0``*.($"`<S```LX@0(!S0``##B!`@'-@``-.($"`<W```XX@0(!S@`
+M`#SB!`@'.@``0.($"`<[``!$X@0(!ST``$CB!`@'/P``3.($"`=```!0X@0(
+M!T$``%3B!`@'0@``6.($"`=#``!<X@0(!T0``&#B!`@'10``9.($"`='``!H
+MX@0(!TH``&SB!`@'3```<.($"`=.``!TX@0(!T\``'CB!`@'4```?.($"`=1
+M``"`X@0(!U(``(3B!`@'4P``B.($"`=4``",X@0(!U8``)#B!`@'5P``E.($
+M"`=8``"#[`SHZ(/$#,,```#_-7CA!`C_)7SA!`@`````_R6`X00(:`````#I
+M_R6$X00(:`@```#I_R6(X00(:!````#I_R6,X00(:!@```#I_R60X00(:"``
+M``#I_R64X00(:"@```#I_R68X00(:#````#I_R6<X00(:#@```#I_R6@X00(
+M:$````#I_R6DX00(:$@```#I_R6HX00(:%````#I_R6LX00(:%@```#I_R6P
+MX00(:&````#I_R6TX00(:&@```#I_R6XX00(:'````#I_R6\X00(:'@```#I
+M_R7`X00(:(````#I_R7$X00(:(@```#I_R7(X00(:)````#I_R7,X00(:)@`
+M``#I_R70X00(:*````#I_R74X00(:*@```#I_R78X00(:+````#I_R7<X00(
+M:+@```#I_R7@X00(:,````#I_R7DX00(:,@```#I_R7HX00(:-````#I_R7L
+MX00(:-@```#I_R7PX00(:.````#I_R7TX00(:.@```#I_R7XX00(:/````#I
+M_R7\X00(:/@```#I_R4`X@0(:``!``#I_R4$X@0(:`@!``#I_R4(X@0(:!`!
+M``#I_R4,X@0(:!@!``#I_R40X@0(:"`!``#I_R44X@0(:"@!``#I_R48X@0(
+M:#`!``#I_R4<X@0(:#@!``#I_R4@X@0(:$`!``#I_R4DX@0(:$@!``#I_R4H
+MX@0(:%`!``#I_R4LX@0(:%@!``#I_R4PX@0(:&`!``#I_R4TX@0(:&@!``#I
+M_R4XX@0(:'`!``#I_R4\X@0(:'@!``#I_R5`X@0(:(`!``#I_R5$X@0(:(@!
+M``#I_R5(X@0(:)`!``#I_R5,X@0(:)@!``#I_R50X@0(:*`!``#I_R54X@0(
+M:*@!``#I_R58X@0(:+`!``#I_R5<X@0(:+@!``#I_R5@X@0(:,`!``#I_R5D
+MX@0(:,@!``#I_R5HX@0(:-`!``#I_R5LX@0(:-@!``#I_R5PX@0(:.`!``#I
+M_R5TX@0(:.@!``#I_R5XX@0(:/`!``#I_R5\X@0(:/@!``#I_R6`X@0(:``"
+M``#I_R6$X@0(:`@"``#I_R6(X@0(:!`"``#I_R6,X@0(:!@"``#I_R60X@0(
+M:"`"``#I_R64X@0(:"@"``#I```````````Q[56)Y8/D\(U%"(/L!%#_=012
+MZ,R0D)"0D)"058GE5U93@^P,BW4,BUT0A?:-?+,$B3WDXP0(?C6+`X7`="^C
+M`.`$"`^V$(32=".#P`'K"@^V$(/``832=!2`^B]U\:,`X`0(#[80@\`!A-)U
+M[+B(X`0(A<!T-(M%"(D$).C'!"1\V`0(Z.B)?"0(B5PD!(DT).B)!"3HZ.O0
+MD)"0D)"0D)"0D%6)Y8/L"(`]W.($"`!T#.L<@\`$HPC@!`C_TJ$(X`0(BQ"%
+MTG7KQ@7<X@0(`<G#D%6)Y8/L"*%PX00(A<!T$K@`````A<!T"<<$)'#A!`C_
+MT,G#D)"0D)"0D)"0D)"0D%6)Y8/L#(D<)(ET)`2)?"0(BW4,BWT(BT9,BU@T
+MBT@PBT=,BU`TBT`P.=-]%+C_____BQPDBW0D!(M\)`B)[%W#?@VX`0```.OH
+MC;8`````.<%W[SG3?A^+1E")10R+1U")10B+'"2+="0$BWPD"(GL7>E\M#G!
+M<]N-=@#KJXVT)@````"-O"<`````58GEBU4,BT4(B54(B44,7>F-="8`C;PG
+M`````%6)Y8/L"(D<)(ET)`2+=0B+70R+5DR+2TR+0B@Y02A^$+@!````BQPD
+MBW0D!(GL7<-\#XM"+#E!+'_FD(UT)@!]![C_____Z]V+0U")10R+1E")10B+
+M'"2+="0$B>Q=Z8VV`````(V_`````%6)Y8M5#(M%"(E5"(E%#%WIC70F`(V\
+M)P````!5B>6#[`B)'"2)="0$BW4(BUT,BU9,BTM,BT)0.4%0?A"X`0```(L<
+M)(MT)`2)[%W#?`^+0E0Y051_YI"-="8`?0>X_____^O=BT-0B44,BT90B44(
+MBQPDBW0D!(GL7>F-M@````"-OP````!5B>6+50R+10B)50B)10Q=Z8UT)@"-
+MO"<`````58GE@^P(B1PDB70D!(MU"(M=#(M63(M+3(M"&#E!&'X0N`$```"+
+M'"2+="0$B>Q=PWP/BT(<.4$<?^:0C70F`'T'N/_____KW8M#4(E%#(M&4(E%
+M"(L<)(MT)`2)[%WIC;8`````C;\`````58GEBU4,BT4(B54(B44,7>F-="8`
+MC;PG`````%6)Y8/L"(D<)(ET)`2+=0B+70R+5DR+2TR+0B`Y02!^$+@!````
+MBQPDBW0D!(GL7<-\#XM")#E!)'_FD(UT)@!]![C_____Z]V+0U")10R+1E")
+M10B+'"2+="0$B>Q=Z8VV`````(V_`````%6)Y8M5#(M%"(E5"(E%#%WIC70F
+M`(V\)P````!5B>6+10B+50R+0%")10R+0E")10A=Z9"-="8`58GEBT4,BT!0
+MB44,BT4(BT!0B44(7>F0D)"0D%6)Y8/L"(D<)(ET)`2+10B+30R+`(M00(/Z
+M!W1SBQF+2T"#^0=T:8/Z"G1,@_D*=$<YRG0KBW`\A?9U)(LU[.($"(7V=1J#
+MZ@&^`0```'1"@^D!OO____]T.(VV`````(E=#(E%"(L-Y.($"(L<)(MT)`2)
+M[%W_X8E=#(E%"(L<)(MT)`2)[%WIC78`,?:)\(L<)(MT)`2)[%W#D%6)Y5=6
+M4X'L+`4``(F%&/O__Z&@X@0(B47L,<"A0.0$"(F5%/O__XF-$/O__\>%E/O_
+M_P````"%P'4-H43D!`B%P`^$QX5`^___`0```,<$)-S8!`CHQX6(^___````
+M`,>%C/O__P````#'A:#[__\`````QX6<^___`````,>%F/O__P````"%P(G#
+MQX6H^___`````,>%K/O__P````#'A;#[__\`````QX6T^___`````,>%I/O_
+M_P````!T"8`X``^%B[T4^___A?\/A(N%$/O__XN]%/O__\>%+/O__P````#'
+MA3#[__\`````@^`"QX4\^___`````,>%3/O__P````")A0S[___I@_@*#X2+
+MM1C[__^%]@^$BT=0@#@N#X2+1RP[A:S[__]V!HF%K/O__XL5).0$"(72=0J+
+M->SC!`B%]G0=B40D!(M'4(D$).@[A:S[__]V!HF%K/O__XN=0/O__X7;#X2+
+M5TR)T(M(/(N%M/O__XF5*/O__XM2.(G&P?X?.?%\#'\$.<)V!HF5M/O__XN5
+M*/O__XM"!#N%L/O__W8&B86P^___BXTH^___#[=!"CN%J/O__W8&B86H^___
+MBXTH^___BU$T.Y6,^___BT$P?!9_"#N%B/O__W8,B86(^___B96,^___BX4H
+M^___BPU$Y`0(BT`X`84L^___A<D/A(L5`.,$"(72#X2+E2C[__^-==*-7=^+
+M0@S'1"0(]]@$",=$)`0-````B30DB40D#.B+C2C[__^+01#'1"0(]]@$",=$
+M)`0-````B1PDB40D#.B)M43[__^)G4C[__^+A43[__^)!"3H.X68^___B84X
+M^___=@:)A9C[__^+E4C[__^)%"3H.X6<^___B<-V!HF%G/O__Z$\Y`0(QX4T
+M^___`````(7`#X6A".0$"#'2QX64^___`````(7`#X6+M3C[__^+C33[__\!
+MWHU$,1@!T(D$).B%P(G##X2+E43[__^-0!")`XD$)(E4)`3HBXTX^___BY5(
+M^___C409$8E#!(E4)`2)!"3HBXTH^___#[=!""4`\```/0`@```/A#T`8```
+M#X2A/.0$"(7`#X6+#0CD!`B%R71`BY4T^___@\(!@ST\Y`0(`1G`]]`APHN%
+ME/O__XT4%HU4$Q*)4PR)1"0$B10DZ(N%E/O__XD$).B)7Q20C70F`(.%//O_
+M_P&+?PB%_W1-BT=`@_@'#X6+1R")!"3HB40D"(M'4,<$)/#8!`B)1"0$Z,='
+M#`$```#'1Q``````BW\(QP4@XP0(`0```(7_=;.+E3S[__^%T@^$BX44^___
+MBY4\^___B858^___BX6L^___B95@^___B85D^___BX5`^___A<`/A8V%6/O_
+M_XD$)/\5X.($"*%$Y`0(QP4DXP0(`0```(7`="6+O13[__^%_W0;BYT4^___
+MC78`BT,4B00DZ(M;"(7;=>Z+5>PS%:#B!`@/A8'$+`4``%M>7UW#C70F`(L-
+M\.($"(7)#X7'1PP!````QT<0`````.F#Z`$/A8L=[.($"(7;#X7KU(N5*/O_
+M_\=$)`0`````BT(,B00DZ(N-*/O__\=$)`0`````B85$^___BT$0B00DZ(F%
+M2/O__^F#O3#[__\.#X>+E2C[__^+0A0PY#T``0``H3SD!`@9R8/A^8/!#X7`
+MB8TP^___#X2+E4S[__^-1#,2B4,(B00DB50D!.B+C4S[__^)#"3HZ8N-*/O_
+M_XM!1(D$).B%P(F%3/O__P^$@#@`=2*)!"3HQP0D^M@$".B%P(F%3/O__P^$
+MBX5,^___B00DZ#N%H/O__XF%-/O__P^&B86@^___Z8V5D/O__XD4).B#P`$/
+MA(M'/(7`#X6+1U"-M;G[___'1"0(]-@$",=$)`0!!```B30DB40D#.B+A0S[
+M__^%P'1SBX60^___B30DB40D!.B#P`%T<XV%E/O__XE$)`2+A9#[__^)!"3H
+M@\`!=%:+A9#[__^)!"3HBX64^___A<!T<XN%E/O__XD$).@[A:3[__^)P@^&
+MB86D^___Z8N%D/O__XDT)(E$)`3H@\`!=8V+1U")1"0(BT<$BT`<QP0D"-D$
+M"(E$)`3HBX60^___B00DZ(N%E/O__X7`=8W'!"3ZV`0(Z(F%E/O__^F+1U"-
+MM;G[__^)1"00BT<$BT`8QT0D"!;9!`C'1"0$`00``(DT)(E$)`SHZ<>%+/O_
+M_P````#'A3S[__\`````QX4P^___`````*%$Y`0(A<!U#:'XXP0(A<`/A(N%
+M&/O__X7`#X7I,<"#/?CC!`@`#Y7`B85`^___Z8D$).B-1``"B00DZ(7`B84<
+M^___#X0/M@,\.@^$BXT<^___B`&+C1S[__^+A1S[__^#P0'&0`$`#[9#`83`
+M=#V)VNL4B`&#P0'&00$`#[9"`H/"`83`="6`.CIUYSPZ=>/&`3`/MD(!B$$!
+M@\$"QD$!``^V0@*#P@&$P'7;@'G_.@^$C86D^___BY4<^___B40D*(V%K/O_
+M_XE$)"2-A8C[__^)1"0@C86@^___B40D'(V%G/O__XE$)!B-A9C[__^)1"04
+MC86H^___B40D$(V%M/O__XE$)`R-A;#[__^)1"0(QT0D!)39!`B)%"3HQP48
+MY`0(`0```(/X"`^&B[6P^___,<"%]G0@N0$```"X"@```/?A@^X!B<%U\L>%
+ML/O__P````"-0/^+O;3[__^)A;#[__\QP(7_?C6)_KD!````,=MKTPJX"@``
+M`(F5!/O___?AB=.)P0.=!/O__X/N`77AQX6T^___`````(U`_XNUJ/O__XF%
+MM/O__S'`A?9T(+D!````N`H```#WX8/N`8G!=?+'A:C[__\`````C4#_BXV,
+M^___BY6(^___B86H^___@_D`B94@^___B8TD^___#XZ+C2#[__^^`0```#'_
+MBYTD^___:\<*B84$^___N`H```#WYHG7B<8#O03[__^#P?^#T_^)V@G*==J)
+M\(GZ@\#_QX6(^___`````(/2_\>%C/O__P````"+C1S[__^)A8C[__^)E8S[
+M__^)#"3HZ8N-+/O__XU=NHN%M/O__\=$)`@<V00(QT0D!!@```")C5S[__^)
+M1"0,B1PDZ(D<).C'1"0('-D$",=$)`08````B1PDB85H^___BX6@^___B85L
+M^___BX6D^___B85P^___BX6<^___B85T^___BX6P^___B40D#.B)'"3HQT0D
+M"!S9!`C'1"0$&````(D<)(F%>/O__XN%J/O__XE$)`SHB1PDZ(F%?/O__Z'\
+MXP0(A<!T6,>%@/O__P4```"+A3#[__\[A8#[__]V!HF%@/O__XN%F/O__XF%
+MA/O__^F+1U")1"0(BT<$BT`<QP0D"-D$"(E$)`3HZ?\DA?#9!`B+E8S[__^+
+MA8C[___'1"0((-D$",=$)`08````B50D$(E$)`R)'"3HB1PDZ(F%@/O__^E\
+M"H/Z`)`/AS'`,=+IQX6P^___`````,>%M/O__P````#'A:C[__\`````QX68
+M^___`````,>%G/O__P````#'A:#[__\`````QX6(^___`````,>%C/O__P``
+M``#'A:S[__\`````@ST<Y`0(`<>%I/O__P`````9P/?0(048Y`0(Z<=$)`3I
+MV`0(QP0D`0```.AFQP$P`.F+E1S[__^)T8/!`F;'`C`ZQD("`.G'1"0$_-@$
+M",<$)`$```#HZ(VT)@````!5B>575E.#[!R#/?SB!`@!B47LB4WH&<`EP)@$
+M"(E$)`B)3"0$B10DZ(7`B<</A,=$)`0`````B00DZ(7`=`R+3>B)PC'`Z*'L
+MX@0(A<`/A8LU!.,$"(7V#X3'1?``````C;0F`````(D\).B%P(G##X2+0T"#
+M^`(/A(GV#X^#Z`%UU8M+/(7)=`R+0U"`."X/A*$DXP0(A<`/A*'`X@0(A<`/
+MA8L5S.($"(M""(/H`87`B4((#XB+`L8`"H/``8D"BT,<B00DZ,<$)$K9!`CH
+MBT7PB3PDB40D!.B+3>B)PHG&B=CHH03C!`B%P`^%A?8/A(E<)`3'1"0(!```
+M`(D\).B)/"3HA<")PP^%Z(L`A<`/A8/$'%M>7UW#D(/X!'0)@_@'#X6+0R")
+M!"3HB40D"(M#',<$)/#8!`B)1"0$Z,<%(.,$"`$```#ID(M#4,<$)"W9!`B)
+M1"0$Z.F#?>P!#XZ+0QR)!"3HQP0D2MD$".C'!23C!`@!````Z8L=".0$"(7;
+M#X7V1>@(QT7P``$```^%Z:',X@0(QP0D"@```(E$)`3HZ8L5\.($"(72#X3I
+MB50D!,<$)`H```#HZ<=$)`1,V00(QP0D`0```.C'1"0$)-D$",<$)`$```#H
+MC78`C;PG`````(U,)`2#Y/#_<?Q5B>575E-1@>PX!@``BQFAH.($"(E%[#'`
+MC87L_?__BWD$B87D^?__QT0D!,S;!`C'!"0`````Z,<$)`$```#HA<`/A,<%
+M#.`$"%````#'!"15V00(Z(7`=`F`.``/A8V%W/G__XE$)`C'1"0$:'0(0,<$
+M)`$```#H@\`!=!0/MX7>^?__9H7`=`@/M\"C#.`$",<%#.0$"`$```"^$```
+M`,=$)`C(V00(B7PD!(D<).B#^/]T/X/H,8/X1W8PZ.O8QP4,XP0(`0```,<$
+M)%79!`CHA<!TN8D$).BC#.`$".NJ_R2%%-H$"*'8X@0(*<.)A<CY__^A\.($
+M"(F=S/G__X7`#X3'!"1=V00(Z(7`=#O'!"0!````Z(7`#X3'!"1UV00(Z(E$
+M)`2-A>SY__^)!"3H@^@!#X2+%1SD!`B%TG1&QP48Y`0(`0```,=$)`1@L@0(
+MQP0D`@```.C'1"0$8+($",<$)`,```#HQP0DB=D$".B)!"3HH4#D!`B%P'5!
+MH43D!`B%P'4XH?CC!`B%P'4OH13C!`B%P'4FH1CC!`B%P'4=H3#D!`B%P'44
+MBQT<Y`0(A=MU"H/."(VT)@````"+#?CB!`B%R74?BQ5$Y`0(A=)U%:'LX@0(
+MA<!U#*$PY`0(A<!U`X/.`:$<XP0(A<!T!H'.@````*%$Y`0(A<`/A*'HX@0(
+MA<`/A,<%$.0$"`(```"+'0CC!`B%VW1CBPT4XP0(A<D/A8L5&.,$"(72#X2A
+M#.,$",<%Y.($"""6!`B%P'5AH43D!`B%P`^$BX7,^?__QP7@X@0(P,$$"(7`
+M=52)\;H0X`0(N`$```#HZU>A%.,$"(7`#X6A&.,$"(7`#X3'!>3B!`B0E00(
+MH0SC!`B%P'2?QP7@X@0(L+P$"(N%S/G__X7`=*R+A<CY__^)\8T4AXN%S/G_
+M_^BA(.,$"(D$).BA^.,$"(7`#X2AZ.($"(7`#X6-A>CY___'1"0$$.0$"(D$
+M).B+%1#D!`B)T,'X'\'H%P'0P?@)HQ#D!`CIQP0D9MD$".B%P`^%Z8/.(,<%
+M\.($"`$```#IQP4,Y`0(`````,<%).0$"`$```#'!>SC!`@`````Z:'$X@0(
+MH_3C!`CIQP4,XP0(`````,<%1.0$"`````#'!33D!`@`````Z<<%&.,$"`$`
+M``#'!13C!`@`````Z<<%!.,$"`$```#I@^;\@\X0QP7XX@0(`0```.F#YN^#
+MS@+'!?CB!`@`````Z<<%].($"`$```#I@\X!QP7XX@0(`````.G'1"0(`0``
+M`,=$)`3,VP0(QP0D7=D$".CIQP4PY`0(`0```,<%%.0$"`````#IQP4,XP0(
+M`0```,<%1.0$"`````#'!1#C!`@`````Z<<%-.0$"`$```#'!43D!`@`````
+MQP4,XP0(`````.G'!0SD!`@`````QP4DY`0(`````,<%[.,$"`````#IQP4$
+MY`0(`0```,<%Z.,$"`````#'!3CD!`@`````Z<<%%.,$"`$```#'!1CC!`@`
+M````Z<<%^.,$"`$```#IQP4(XP0(`0```.G'!0SD!`@!````QP4DY`0(````
+M`,<%[.,$"`````#IQP44Y`0(`0```,<%,.0$"`$```#IQP4\Y`0(`0```.G'
+M!0#C!`@!````Z<<%$.,$"`$```#'!0SC!`@`````QP5$Y`0(`````.G'!43D
+M!`@!````QP4,XP0(`````,<%$.,$"`````#IQP7\XP0(`````,<%Z.($"`$`
+M``#IQP5`Y`0(`0```.G'!?SC!`@!````Z<<%_.($"`$```#IQP7LX@0(`0``
+M`,<%!.,$"`````#IQP7HXP0(`0```,<%!.0$"`````#'!3CD!`@`````Z<<%
+M#.0$"`````#'!23D!`@`````QP7LXP0(`0```.G'!0CD!`@!````Z<<%'.,$
+M"`$```#IQP4XY`0(`0```,<%!.0$"`````#'!>CC!`@`````Z<<%(.0$"`$`
+M``#IZ(7`#X6A].($"(7`#X7'!?#B!`@!````Z8L=&.,$"(7;#X6+#03D!`B%
+MR0^$QP7DX@0(8)<$".FA&.,$"(7`#X6A!.0$"(7`#X3'!>3B!`C0EP0(Z:$0
+MXP0(A<!T+<<%X.($"(#`!`CIQP7DX@0(@)@$".G'!>3B!`B@F`0(Z<<%X.($
+M"$"]!`CIC9WD^?__B5PD!,<$)'K9!`CHB5PD!,<$)'W9!`BC\.,$".B)7"0$
+MQP0D@-D$"*,LY`0(Z(E<)`3'!"2#V00(HTCD!`CHB5PD!,<$)(;9!`BC*.0$
+M".B%P*,`Y`0(#X2A\.,$"(7`#X2+'2SD!`B%VP^$BPT`Y`0(A<D/A,<%'.0$
+M"`$```#IB00DZ,<%#.0$"`$```"C#.`$".FA..0$"(7`=4FAZ.,$"(7`=$_'
+M!>3B!`BPE@0(Z8L5..0$"(72=1BAZ.,$"(7`=#S'!>3B!`A`E@0(Z<<%Y.($
+M"-"6!`CIQP7DX@0(0)<$".G'!>3B!`A@F`0(Z<<%Y.($"/"7!`CIB5PD!,<$
+M).W8!`CHHP#D!`CID)"0D)"0D)"0D)!5B>6#[!B%P'0]H0#D!`C'1"0(H+($
+M",=$)`0!````B00DZ+B@L@0(B40D"*%(Y`0(QT0D!`$```")!"3HR<.A`.0$
+M",=$)`@`N`0(QT0D!`$```")!"3HN`"X!`CKP9"-="8`58GE4X/L%(M="(G8
+MZ(D<),=$)`0`````Z.B)7"0$B00DZ(/$%%M=PY"-M"8`````58GE@^PHBT4(
+MQT0D"`$```#'!"0!````B$7_C47_B40D!.@QP,G#D(UT)@!5B>575E.#["R+
+M10B%P`^$BT4(,?^)!"3HBQ5@W`0(9L=%V@``QT7<`````(E5X(E%U.L\C70F
+M``^^PH/H,&:#?=H`B0,/A&;'1=H!`(/&`8/#!(/^`G5%@\<!@T7<#(-%X`*#
+M_PL/A(M%W,>`:.,$"`````"-!#\Y1=1W.8M5X`^V`HA%\@^V0@&(1?.-!'\Q
+M]HT<A6#C!`@/ME0N\HU"T#P'=HN-0I\\!W<D#[["@^AAB0/KDXM5"`^V!'J(
+M1?(/MD1Z`8A%\^O#C;8`````C4*_/`=W*P^^PH/H08D#BT7<QX!HXP0(`0``
+M`.G'!"3LVP0(Z.D/MLH[#<CB!`A]#*'0X@0(BXR(-`0``(/Y>'03#[["B40D
+M!,<$)#3<!`CHQP/_____Z8/$+%M>7UW#QT4(S-L$".E5B>564XG#C31`@^P0
+MBQ2U:.,$"(72#X6+!+5@XP0(@_C_=#B)1"0(H?#C!`C'1"0$`````(D$).B%
+MP'0;QT0D"`"X!`C'1"0$`0```(D$).B-=@"-!%N+!(5DXP0(@_C_=#6)1"0(
+MH2SD!`C'1"0$`````(D$).B%P'08QT0D"`"X!`C'1"0$`0```(D$).B#Q!!;
+M7EW#D(UT)@"A*.0$",=$)`@`N`0(QT0D!`$```")!"3HZ8VT)@````"-O"<`
+M````#[?`B<)5@>(`\```B>6#[`B!^@!````/A'Y1@?H`H```#X2!^@#```!T
+M8H'Z`&````^$,=*H271?]L0(#X7VQ`0/A+@(````C70F`.BZ`0```.LXC70F
+M`('Z`!```'18@?H`(```B?9UO;@&````Z+H!````R8G0P[@"````Z+H!````
+MR8G0P[@!````Z+H!````R8G0P[@%````Z+H!````R8G0PXGVN`,```#HN@$`
+M``#)B=##J`)T./;$`G01N`D```#HN@$```#KI[@*````Z+H!````ZY:X!```
+M`.BZ`0```.N%,<#HN@$```#IN`<```#HN@$```"0Z8UT)@"-O"<`````58GE
+M4X/L=(E%F*&@X@0(B47X,<"A+.`$"(7`#XBA1.,$"(7`=':+'?3C!`B%VP^$
+MC468B00DZ(E<)`B-7:C'1"0$4````(D<)(E$)`SHH<SB!`B)'"2)1"0$Z*',
+MX@0(QP0D(````(E$)`3HBT7X,P6@X@0(#X6#Q'1;7<.-M"8`````QP0D````
+M`.B+'?3C!`B%VZ-$XP0(#X60H2#D!`B%P'0[H2S@!`B[--L$"(7`#X6[0-L$
+M".G'!"0Y````Z(`X9`^4P`^VP*,LX`0(Z8M-F(L51.,$"(V!`/'O`#G0?B:-
+M@@#Q[P`YP7T<H2S@!`B[3-L$"(7`#X6[5=L$".F+#2S@!`B[7ML$"(7)#X6[
+M:-L$".GHD(L5).0$"%6)Y8M%"(72=0J+#>SC!`B%R70)B44(7>F+%0SD!`B%
+MTG0)B44(7>F)10A=Z9!5B>6#[`BAP.($"(M-"(7`=2"+%<SB!`B+0@B#Z`&%
+MP(E""'@BBP*("(/``8D"R3'`PZ',X@0(B0PDB40D!.@QP,G#.T(8?`:`^0J0
+M==.)5"0$B0PDZ.O.58GE@^P(BPT4Y`0(A<ET$"4`\```/0!```!T=,DQP,.)
+MPH'B`/```('Z`*````^$#X>!^@`0```/A('Z`$```(UT)@!T/JA)=,:AP.($
+M"(7`#X6+%<SB!`B+0@B#Z`&%P(E""`^(BP+&`"J#P`&)`K@!````R<.0C70F
+M`(L5P.($"(72#X6+%<SB!`B+0@B#Z`&%P(E""`^(BP+&`"^#P`&)`K@!````
+MR<.!^@#````/A('Z`.````^%H<#B!`B%P`^%BQ7,X@0(BT((@^@!A<")0@@/
+MB(L"Q@`E@\`!B0*X`0```,G#H<#B!`B%P`^%BQ7,X@0(BT((@^@!A<")0@@/
+MB(L"Q@!`@\`!B0*X`0```,G#H<SB!`C'!"0O````B40D!.BX`0```,G#H<#B
+M!`B%P`^%BQ7,X@0(BT((@^@!A<")0@@/B(L"Q@`]@\`!B0*X`0```,G#H<#B
+M!`B%P`^%BQ7,X@0(BT((@^@!A<")0@AX;8L"Q@!\@\`!B0*X`0```,G#.T(8
+M#XV)5"0$QP0D+P```.BX`0```,G#H<SB!`C'!"0J````B40D!.BX`0```,G#
+M.T(8#XV)5"0$QP0D0````.BX`0```,G#.T(8?8Z)5"0$QP0D?````.BX`0``
+M`,G#.T(8#XV)5"0$QP0D/0```.BX`0```,G#.T(8#XV)5"0$QP0D)0```.BX
+M`0```,G#H<SB!`C'!"0E````B40D!.BX`0```,G#H<SB!`C'!"1`````B40D
+M!.BX`0```,G#H<SB!`C'!"1\````B40D!.BX`0```,G#H<SB!`C'!"0]````
+MB40D!.BX`0```,G#.T(8#XV)5"0$QP0D*@```.BX`0```,G#C;0F`````(V\
+M)P````!5B>6#[#B)7?2)PXE]_(G/B77XBW!,H4#D!`C'1>P`````A<`/A:'X
+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
+M1E"-C<O[__^)1"00BT8$BT`8QT0D"!;9!`C'1"0$`00``(D,)(E$)`SHZ8L5
+M).`$"(72#X3IZ(L`B00DZ(V5R_O__XE4)`C'1"0$P-L$"(E$)`RAU.($"(D$
+M).CIQD76*^F)5"0$QP0D"@```.CIB1PDC9W+^___Z(E<)`3'!"3TV`0(Z.E]
+M+9"-M"8`````Z(,X%G0;C8W+^___B4PD!,<$)/38!`CHZ:$DX`0(A<`/A8V=
+MR_O__\=$)`0[````B1PDZ(/X`'X9QP4@X`0(`@```,<%).`$"`$```#I#XWH
+M@S@6#X2-A<O[__^)1"0$QP0D]-@$".CIZ)"0D)"0D%6)Y8/L&*'4X@0(QT0D
+M"$H```#'1"0$`0```,<$)&3<!`B)1"0,Z,<$)`$```#HB?:-O"<`````58GE
+M5U93@>RL````BWT,C95P____BW4(H:#B!`B)1?`QP,=$)`B`````QT0D!```
+M``")%"3HA?_'A6#___\`````=%^-E7#___^-A6S___^)5"0,B7PD"(ET)`2)
+M!"3HA<")PW0Y@_O_=&V#^_X/A(N5;/___X'Z_P```'=*H=#B!`B+1)`TJ0``
+M!`!T*8.%8/___P$!WH7_=:&+5?`S%:#B!`B+A6#___]U9H'$K````%M>7UW#
+MBX5@____C028B85@____Z\V)%"3HZ[6)]HV%</___X/&`8.%8/___P2#[P''
+M1"0(@````,=$)`0`````B00DZ.N6BY5@____C12ZB95@____ZXGHC;8`````
+MC;PG`````%6)Y5=64X'LK````(M%"(L5H.($"(E5\#'2QT0D"(````#'1"0$
+M`````(F%7/___XV%</___XD$).C'A6#___\`````BY5<____C85P____B40D
+M#(V%;/___\=$)`@&````B00DB50D!.B%P(G'#X2#__\/A(/__@^$BYUL____
+M@?O_````#X>AT.($"(M$F#2I```$``^$,?:%_W\WZV:-="8`BQ7,X@0(BX5<
+M____#[8,!HM""(/H`87`B4((#XB+`H@(@\`!B0*#Q@$Y]W0KH<#B!`B%P'3&
+MH<SB!`B+E5S___^)1"0$#[8$%H/&`8D$).@Y]W75BYUL____,<"%VW0H@?O_
+M````#X>AT.($"(M$F#2)PH'B````X`^$B=#!Z!X!O5S___\!A6#____I.T(8
+M#[;9?`F`^PH/A8E4)`2)'"3HZ8L5P.($"(72#X6+%<SB!`B+0@B#Z`&%P(E"
+M"`^(BP+&`#^#P`&)`@&]7/___X.%8/___P'IBQW`X@0(A=L/A8L5S.($"(M"
+M"(/H`87`B4((#XB+`L8`/X/``8D"C95P____@X5<____`8.%8/___P''1"0(
+M@````,=$)`0`````B10DZ.F)'"3HC70F`.FAS.($",<$)#\```")1"0$Z.F+
+M#<#B!`B%R0^%BQ7,X@0(BT((@^@!A<")0@@/B(L"Q@`_@\`!B0*#A6#___\!
+MBU7P,Q6@X@0(BX5@____#X6!Q*P```!;7E]=PZ',X@0(QP0D/P```(E$)`3H
+MZ24```0`@_@!&<"#R`'IB1PDZ.D[0A@/C8E4)`3'!"0_````Z.D[0A@/C8E4
+M)`3'!"0_````Z.FAS.($",<$)#\```")1"0$Z.D[0A@/C8E4)`3'!"0_````
+MZ.GHB?:-O"<`````58GE5U93@>RL````BT4(BQ6@X@0(B57P,=+'1"0(@```
+M`,=$)`0`````B85<____C85P____B00DZ,>%8/___P````"+E5S___^-A7#_
+M__^)1"0,C85L____QT0D"`8```")!"2)5"0$Z(7`B<8/A(/^_@^$@_[_#X0Q
+MVX7V?S/K78L5S.($"(N%7/___P^V#`.+0@B#Z`&%P(E""`^(BP*("(/``8D"
+M@\,!.=YT+(L]P.($"(7_=,6AS.($"(N57/___XE$)`0/M@03@\,!B00DZ#G>
+M==2+G6S___\!M5S___^!^_\```!W<*'0X@0(BT28-*D```0`#X0QP(7;="B!
+M^_\````/AZ'0X@0(BT28-(G"@>(```#@#X2)T,'H'@&%8/___^D[0A@/MOE\
+M"HGX/`H/A8E4)`2)/"3HZ8D<).B0ZXZ-A7#____'1"0(@````,=$)`0`````
+MB00DZ*'`X@0(A<`/A8L5S.($"(N%7/___P^V"(M""(/H`87`B4((#XB+`H@(
+M@\`!B0*#A5S___\!@X5@____`>F+E5S____'!"3TV`0(B50D!.@!A6#___^+
+M5?`S%:#B!`B+A6#___]U:X'$K````%M>7UW#)0``!`"#^`$9P(/(`>F)'"3H
+MZ:',X@0(BY5<____B40D!`^V`HD$).CI.T(8#[;9?`F`^PH/A8E4)`2)'"3H
+MZ>B-=@"-O"<`````58GE5U93@>RL````BT4(BQ6@X@0(B57P,=+'1"0(@```
+M`,=$)`0`````B858____C85P____B00DZ,>%8/___P````"+E5C___^-A7#_
+M__^)1"0,C85L____QT0D"`8```")!"2)5"0$Z(7`B85<____#X2+A5S___^#
+MP`*#^`$/AHN=;/___X'[_P````^'H=#B!`B+1)@TJ0``!``/A(/[(@^$@_M<
+M#X2+O5S___^%_WYO,=OK-8L5S.($"(N%6/___P^V#`.+0@B#Z`&%P(E""`^(
+MBP*("(/``8D"@\,!.YU<____=#"+-<#B!`B%]G3!H<SB!`B+E5C___^)1"0$
+M#[8$$X/#`8D$).@[G5S___]UT(N=;/___S'`A=MT*('[_P````^'H=#B!`B+
+M1)@TB<*!X@```.`/A(G0P>@>`85@____@[U<_____@^$@[U<_____P^$BY5<
+M____`958____Z8.]7/____\/A;\!````,?;ID(UT)@"+%<SB!`B+0@B#Z`&%
+MP(E""`^(BP+&`%R#P`&)`J'`X@0(A<`/A8L5S.($"(G8P.@&#[;`C4@PBT((
+M@^@!A<")0@@/B(L"B`B#P`&)`J'`X@0(A<`/A8L5S.($"(G8P.@#@^`'C4@P
+MBT((@^@!A<")0@@/B(L"B`B#P`&)`J'`X@0(A<`/A8L5S.($"(G8@^`'C4@P
+MBT((@^@!A<")0@@/B(L"B`B#P`&)`H/&`8.%8/___P0Y_@^-H<#B!`B+E5C_
+M__^%P`^V'!8/A*',X@0(QP0D7````(E$)`3HH<#B!`B%P`^$H<SB!`B)1"0$
+MB=C`Z`8/ML"#P#")!"3HH<#B!`B%P`^$C;8`````H<SB!`B)1"0$B=C`Z`.#
+MX`>#P#")!"3HH<#B!`B%P`^$C;0F`````*',X@0(B40D!(G8@^`'@\`PB00D
+MZ.F)]CM"&'P)@/D*#X6)5"0$B0PDZ.F0.T(8#XV)5"0$QP0D7````.CIB?8[
+M0AA\"8#Y"@^%B50D!(D,).CID#M"&'P)@/D*#X6)5"0$B0PDZ.F+#>SC!`B%
+MR700A=MX#('[_P````^.B[U<____A?\/CX.]7/____X/A8M5\#,5H.($"(N%
+M8/___P^%@<2L````6UY?7<.+A5C___^)!"3HB<?KN3M"&`^V\7P*B?`\"@^%
+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
+M+V-R=&XN4RQV(#$N-BXR,BXQ(#(P,#DO,#@O,#,@,#@Z,3,Z,#8@:V5N<VUI
+M=&@@17AP("0````!&P,[%`,```(```!8M___,`,``*CY__],`P``````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M``````````````````````````````````````````````#,VP0(`````&SA
+M!`A0````&.`$"``````N````_____P(```#_______________\4````````
+M``%Z4@`!?`@!&PP$!(@!```8````'````""T__\9`````$,.!$*%`@T%````
+M'````#@```!4]O__AP$```!!#@B%`D(-!46&!(<#`````````0````$````!
+M````70````$```")````#````.2/!`@-````?-@$"`0```!$@00(!0```$R)
+M!`@&````O(,$"`H```!$`P``"P```!`````5``````````,```!TX00(`@``
+M`#`"```4````$0```!<```"TC00($0```'2-!`@2````0````!,````(````
+M_O__;T2-!`C___]O`0```/#__V^0C`0(````````````````````````````
+M````````````````````````````````````_____P````#_____````````
+M``"(X`0(```````````.D`0('I`$""Z0!`@^D`0(3I`$"%Z0!`AND`0(?I`$
+M"(Z0!`B>D`0(KI`$"+Z0!`C.D`0(WI`$".Z0!`C^D`0(#I$$"!Z1!`@ND00(
+M/I$$"$Z1!`A>D00(;I$$"'Z1!`B.D00(GI$$"*Z1!`B^D00(SI$$"-Z1!`CN
+MD00(_I$$"`Z2!`@>D@0(+I($"#Z2!`A.D@0(7I($"&Z2!`A^D@0(CI($")Z2
+M!`BND@0(OI($",Z2!`C>D@0([I($"/Z2!`@.DP0('I,$""Z3!`@^DP0(3I,$
+M"%Z3!`ANDP0(?I,$"(Z3!`B>DP0(KI,$"+Z3!`C.DP0(WI,$".Z3!`C^DP0(
+M#I0$"!Z4!`@NE`0(/I0$"$Z4!`A>E`0(````````````)$9R965"4T0Z('-R
+M8R]L:6(O8W-U+VDS.#8M96QF+V-R=#%?<RY3+'8@,2XQ+C(N-"`R,#$Q+S`Q
+M+S$V(#$P.C0Q.C0W(&MI8B!%>'`@)```)$9R965"4T0Z('-R8R]L:6(O8W-U
+M+V-O;6UO;B]C<G1B<F%N9"YC+'8@,2XV+C(N,2`R,#`Y+S`X+S`S(#`X.C$S
+M.C`V(&ME;G-M:71H($5X<"`D`$=#0SH@*$=.52D@-"XR+C(@,C`P-S`X,S$@
+M<')E<F5L96%S92!;1G)E94)31%T``$=#0SH@*$=.52D@-"XR+C(@,C`P-S`X
+M,S$@<')E<F5L96%S92!;1G)E94)31%T``"1&<F5E0E-$.B!S<F,O8FEN+VQS
+M+V-M<"YC+'8@,2XQ."XQ,"XQ(#(P,#DO,#@O,#,@,#@Z,3,Z,#8@:V5N<VUI
+M=&@@17AP("0`1T-#.B`H1TY5*2`T+C(N,B`R,#`W,#@S,2!P<F5R96QE87-E
+M(%M&<F5E0E-$70``)$9R965"4T0Z('-R8R]B:6XO;',O;',N8RQV(#$N.#8N
+M,BXT(#(P,3`O,#(O,C@@,30Z,#0Z,C`@:F@@17AP("0`1T-#.B`H1TY5*2`T
+M+C(N,B`R,#`W,#@S,2!P<F5R96QE87-E(%M&<F5E0E-$70``)$9R965"4T0Z
+M('-R8R]B:6XO;',O<')I;G0N8RQV(#$N-S@N,BXS(#(P,3`O,#(O,C0@,34Z
+M,C<Z,S$@:F@@17AP("0`1T-#.B`H1TY5*2`T+C(N,B`R,#`W,#@S,2!P<F5R
+M96QE87-E(%M&<F5E0E-$70``)$9R965"4T0Z('-R8R]B:6XO;',O=71I;"YC
+M+'8@,2XT,2XR+C$@,C`P.2\P."\P,R`P.#HQ,SHP-B!K96YS;6ET:"!%>'`@
+M)`!'0T,Z("A'3E4I(#0N,BXR(#(P,#<P.#,Q('!R97)E;&5A<V4@6T9R965"
+M4T1=``!'0T,Z("A'3E4I(#0N,BXR(#(P,#<P.#,Q('!R97)E;&5A<V4@6T9R
+M965"4T1=``!'0T,Z("A'3E4I(#0N,BXR(#(P,#<P.#,Q('!R97)E;&5A<V4@
+M6T9R965"4T1=```N<VAS=')T86(`+FEN=&5R<``N;F]T92Y!0DDM=&%G`"YH
+M87-H`"YD>6YS>6T`+F1Y;G-T<@`N9VYU+G9E<G-I;VX`+F=N=2YV97)S:6]N
+M7W(`+G)E;"YD>6X`+G)E;"YP;'0`+FEN:70`+G1E>'0`+F9I;FD`+G)O9&%T
+M80`N96A?9G)A;65?:&1R`"YD871A`"YE:%]F<F%M90`N9'EN86UI8P`N8W1O
+M<G,`+F1T;W)S`"YJ8W(`+F=O=``N8G-S`"YC;VUM96YT````````````````
+M```````````````````````````````````````````+`````0````(````4
+M@00(%`$``!4```````````````$`````````$P````<````"````+($$""P!
+M```8```````````````$`````````"$````%`````@```$2!!`A$`0``>`(`
+M``0`````````!`````0````G````"P````(```"\@P0(O`,``)`%```%````
+M`0````0````0````+P````,````"````3(D$"$P)``!$`P`````````````!
+M`````````#<```#___]O`@```)",!`B0#```L@````0``````````@````(`
+M``!$````_O__;P(```!$C00(1`T``#`````%`````0````0`````````4P``
+M``D````"````=(T$"'0-``!`````!``````````$````"````%P````)````
+M`@```+2-!`BT#0``,`(```0````+````!`````@```!E`````0````8```#D
+MCP0(Y`\``!$```````````````0`````````8`````$````&````^(\$"/@/
+M``!P!``````````````$````!````&L````!````!@```'"4!`AP%```#$0`
+M````````````$`````````!Q`````0````8```!\V`0(?%@```P`````````
+M``````0`````````=P````$````"````B-@$"(A8``".!``````````````$
+M`````````'\````!`````@```!C=!`@870``'```````````````!```````
+M``"-`````0````,`````X`0(`&```#````````````````0`````````DP``
+M``$````"````,.`$"#!@``!8```````````````$`````````)T````&````
+M`P```(C@!`B(8```V`````4`````````!`````@```"F`````0````,```!@
+MX00(8&$```@```````````````0`````````K0````$````#````:.$$"&AA
+M```(```````````````$`````````+0````!`````P```'#A!`AP80``!```
+M````````````!`````````"Y`````0````,```!TX00(=&$``"0!````````
+M``````0````$````O@````@````#````H.($"*!B``"L`0`````````````@
+M`````````,,````!``````````````"@8@``00,``````````````0``````
+M```!`````P``````````````X64``,P```````````````$``````````'__
+M[(*_<*GBTO8J#[&TS@MGB4R]0=<':N.(W\G9G;.:/7*.,11&``!@4S^M8<&.
+MP63`)`;+,KS2"?Z;A7RA_=0$&\'"AAXY)C^XW9C3((:>FU,#`MX3R^HAEXQ`
+MW/V/);AC03P4*HO-^D@)`C6HHPG!%`$%U86]?<,`<*I^42Y[@7]MBJ?,QX3M
+M3/:EZ9/S)=617P5Y5PZIU*:8JM;V!QV(A,(RF!F:C2+OF&6]C`#8M3!B-GH,
+M)PY1-;%69(1/24\>8N]NI<D/JQOF"KF-;OV"45D#/4I27]E'\_6?3#U8#$Y-
+M_,"$]ILU+L)6?U3"HVU`Z_`SAK-7<L#8C.OLFL#9+B.X@>*`*RQTX*!#U)B'
+MXKW5%V6Y*;=1\]!=G:91]&D7!#43@0-P7``RF#3BJBB%M%,.7\)4T&U&X/C8
+M(4LW\ASM]>54Z@W1_9`Y0CEW_N9NJZWW4]4HZ+``;=&4+41:XH6=V/B0#[WJ
+M(5^F^T'@XPE].>(76"[6@J7/$,#_3Q.^?,D1G90(-7#9N@JW\W:I<_X```!@
+M/'"(&^G]6XWUER><Y,<ZSU,^C7_E+-N6`+XTNF,NE@G"G"9W@L<L)%>2<XCC
+M^T[[NX.44F,[D3ZJW(=B\+4I#J;KQI7$GMXO+MMM8"W`S+,7Y6=,.5$,1,"7
+MI2#"RR0G36KU)G=*C%-;PUVA)<OXGK'JV>3R-9*V(/<4/R5B3&<XX.,]FUJ<
+M?5VF9IJQ"OD+"Z2FU*K3G?F<!_!)WUQ59U7E/?X,AOVP.P::RORAXI+[[4>S
+M"7\S:FU`^C#>_:,*%#(5*,IB!S*]O_15LX>H!Q!D_\VM,"PZ>:N6=BRN-=V=
+M;8TR>_16]XO)!,A.D@6P8A?CZ_F5]Y=LR5(L0_`-GEX7GC8W3"%D_*N+DI*?
+M<<`9203"1\B,5J$NKBQHD#];WLNRL5=_I/F(56'DZS_[30XJJ6`%1N59KHI,
+M34]#8GP&HK\5L?&1B\W3[53)J.$==T?J@L".%=K\:(+=23HOAFY\)[RYNK6G
+MM_%6\6J<O9P1&IVY,`U'FL^4J;;']L!1!NRKKY?-_L_Z_&X':%XVO-VI4,71
+MK7X.\HHG37P-?D#SP6>+[6K>Q@(&1V3,R4CM@RS(*,9ND0\DP`%]N-<NW);&
+MRC#C&/('#Z]A%I7[Q@CI8%K(E@G.(^>8Z\$_!<G4HSV=12-\PRU`I>I=>$FD
+M6-@V*1+[X<RX02P>_4)<S=(3-5GL&61XXZ)(^:D08O^<@6U9V^AE:)TI-;?I
+ML^V:9UG]$14?%-.>1^T`S7A=L5?A?\;7>+&9J?QRU9T<$I,GGM99UXHTC#[.
+M<1Z:'3+=7"C\.5#<_IX&%MCL$FP4:Z>CD,7_>K)W5]^R>!3._10]``$$!@`$
+M"<"<7B>!;H)T``<+`0`$(P,!`05L```!`",#`0$%;````0`!`!0#`P$;!`$%
+M``0!`P("!@$`#(>XA&S`G%[`P&H`"`H!/7V2E0``!0$1#P!X`#@`-@!E`'@`
+:90```!0*`0``+4,K<;.=`14&`0`A````````
+`
+end
diff --git a/libarchive/test/test_read_format_7zip_bcj2_deflate.7z.uu b/libarchive/test/test_read_format_7zip_bcj2_deflate.7z.uu
new file mode 100644
index 000000000000..2780eca3c901
--- /dev/null
+++ b/libarchive/test/test_read_format_7zip_bcj2_deflate.7z.uu
@@ -0,0 +1,313 @@
+begin 644 test_read_format_7zip_bcj2_deflate.7z
+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
+M```3>```$2@``!'(```4&```$.@``!*X```1R```$-@``!*H```4&```$V@`
+M`!)(```3N```$J@``!08```2J```%!@``!*H```4&```$K@``!*H```4&```
+M$X@``!.(```3V```$R@``!)X```98```$N@``#?````0&```$G@``!E@```1
+MV```$N@``!)H```1>```$B@``!(H```WP```$!@``!#(```32```$X@``!.(
+M```3J```$Y@``!"(```12```$@@``$FP```0B```$#@``!"(```3F```$(@`
+M`!+(```2V```$M@``!"(```RT```)@```"8````36```$S@``!"(```3"```
+M$\@``!18```46```%%@``!18```46```$#@``!18```2.```$C@``!(X```Q
+M\```$M@``!0(```0F```$&@``!08```2*```$B@``!"X```2.```$+@``!(X
+M```2.```-#```#0P```T,```-#```#0P```T,```-#```#0P```T,```-#``
+M`#0P```1N```$6@``!#X```0>```$$@``!+X```3V```$,@``!-(```0R```
+M$T@``!#(```32```$T@``!-(```32```$,@``!#(```0R```$,@``!-(```U
+M$```-\```#A@```WP```,?```%;````2B```$H@``#N````0R```$T@``#N`
+M```0R```$T@``!#(```32```$H@``!&8```2N```$H@``!08```[@```$,@`
+M`!#(```32```$T@``!(8```2J```$:@``!0X```1.```$_@``!*(```0J```
+M$H@``#9@```WP```,?```!*(```2J```$H@``#9@```U$```$H@``!*(``!6
+MP```$H@``!*(```0R```.&```!*H```42```$H@``#?````2J```$H@``#9@
+M```V8```$J@``!*H```2:```$7@``!`H```32```$_@``!*X```2:```$K@`
+M`!&H```2:```$K@``!/8```3&```$U@``!)8```06```$0@``!)8```3V```
+M$E@``!!8```0R```$T@``!)8```1"```$,@``!#(```1"```$T@``!-(```0
+MR```$T@``!/8```26```$%@``!#(```32```$0@``!)8```2B```$0@``!#(
+M```32```$]@``!)8```06```$,@``!#(```0R```$,@``!#(```32```$T@`
+M`!-(```32```%!@``!-(```1"```$E@``!'H```1"```$,@``!#(```32```
+M$T@``!/8```5,```#_@```_X```/^```#_@```_X```/^```#_@```_X```/
+M^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X
+M```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@`
+M``_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```
+M#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/
+M^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X
+M```/^```#_@```_X```/^```#_@``!'X```5D```$?@``!9````1^```%M``
+M`!'X```78```$?@``!?P```1^```$?@``!B@```A1```(5L``"#]```=7@``
+M'6H``!YQ```>4```'5```!U0```>B@``'S$``!^B```EJ0``'LT``![-```?
+M!0``&H$``"$;```CMP``)?0``!JD```=5P``&J0``!JD```<````'/$``!S^
+M```<_@``)>```"7@```<5P``'%<``"2R```@R0``''```!QP```@/P``'^D`
+M`!XR```=N0``'C(``!FR```EJ0``)<<``"6]```DU```)1H``!HQ```=ZP``
+M(#4``"2-```C00``(Y@``")U```A\@``(:,``"B"```G=P``*`@``"=H```G
+MP```)X```"A&```GV```*"P``"A9```F@```)H```":2```H;@``)H```":`
+M```F@```)Q```"<0```F<@``)H```"9R```F^0``)H```":^```F^0``*8L`
+M`#$P```OOP``+#H``#"!```K[0``+`<``#`3```P5```,#P``"_H```P8P``
+M*QP``"L2```K'```*?\``"HF```I8P``*6,``"EC```I8P``*6,``"EC```I
+M8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC
+M```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,`
+M`"EC```I8P``*6,``"EC```I8P``*6,``"EC```IVP``*=L``"G;```KHP``
+M,6T``"NM```K0@``,4P``"NM```KP```*ZT``"NM```KP```,<L``"HF```J
+M)@``*B8``"HP```I7@``*ZT``"NM```KK0``*ZT``"NM```KK0``,/@``#0D
+M```ST0``-!P``#,I```S(P``,RD``#+D```TX```-$P``#7S```UN```-<L`
+M`#9````V'@``-;0``#6T```W10``-R```#>Z```VF```-I@``#:8```V@0``
+M-I@``#:8```VF```-I@``%$0``!+(```3H```#ES```Y)@``.?D``#I*```[
+M4@``.:@``#HJ```YQ```.+(``#KB```ZP@``.OX``#IF```[-@``.J(``#L:
+M```Y%0``.9<``#GH```Y8@``.-H``#R(```[LP``.ZH``$`\``!`*@``/^L`
+M`#_K```_N@``/X0``#]R```_A```/X0``#YT```^K0``/DT``#XT```^-```
+M/+```#UP``!!5```09(``$"@``!!$```11P``$4<``!$]P``1J@``$95``!#
+M5```0U0``$-4``!(>P``1_4``$@U``!)!@``21H``$CC``!(Q0``1C```$8(
+M``!%<```17```$>P``!%WP``1^4``$?3``!%]```1O```$<```!&T```2,X`
+M`$(```!)I0``0?4``$>```!$4P``1((``$2"``!#M```0Z<``$(N``!"(```
+M1/<``$2U``!(1P``2(X``$3)``!%N```1$8``$1U``!$=0``0L$``$-4``!#
+M`P``1S```$-4``!"@```1,D``$-,``!$]P``0U0``$-4``!#`P``0P,``$@U
+M``!(-0``0U0``$K]``!-I0``3.0``$UO``!-1```3*,``$R!``!-\0``3=\`
+M`$MH``!,`0``3`H``$U5``!-_@``2V@``$W%``!.'```2V@``$O)``!,T@``
+M3CH``$Y4``!.<@``31,``$QP``!,70``3,@``$S2``!-"0``31,``$V>``!-
+ME```39X``%"%``!0:0``4`(``$_4``!.R```4+,``%"A``!.R```3S<``$]`
+M``!0P```4-\``$[(``!/R0``3[8``%!6``!030``4%8``%44``!2L@``56D`
+M`%3?``!4WP``5-\``%5&``!60```5B@``%44``!5=@``45@``%4T``!3J```
+M5(```%/A``!48```5!```%2@``!40```5,```%*'``!2T```4OX``%,V``!3
+M;@``4Y8``%,@``!3*0``4N<``%+Q``!36```4V$``%.-``!3E@``5:```%+$
+M``!2E```5KH``%()``!2$@``4;T``%%8``!4^0``5F0``%9^``!6G```4H<`
+M`%*'``!2;@``5>P``%7B``!5[```5A,``%8<``!7H@``5\```%<&``!7!@``
+M5T```%=``'__[(*_<*GBTO8J#[&TS@MGB4R]0=<':N.(W\G9G;.:/7*.,11&
+M`00&``0)J8R$;(>X)P`'"P$``@,$`0@4`P,!&P0!`0```@,$#,"<7L#`:@`(
+M"@$]?9*5```%`1$/`'@`.``V`&4`>`!E````%`H!```M0RMQLYT!%08!`"$`
+$````````
+`
+end
diff --git a/libarchive/test/test_read_format_7zip_bcj2_lzma1_1.7z.uu b/libarchive/test/test_read_format_7zip_bcj2_lzma1_1.7z.uu
new file mode 100644
index 000000000000..11c2133f5f7e
--- /dev/null
+++ b/libarchive/test/test_read_format_7zip_bcj2_lzma1_1.7z.uu
@@ -0,0 +1,287 @@
+begin 644 test_read_format_7zip_bcj2_lzma1_1.7z
+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
+M=I9FG8(OQJ,M*1GQ%+%`3@WP-A,.*:T(>!\C6X+H6[?]`JJ2%]6QX&(A=:Q\
+MUJIM+))_2U.!1"!5[<8U5AZH-@VYF$C.Q2VV^AM!1<O"_G/1_^CP.S-((2N\
+M)>1S(=G;M#;*N85A^C%4I*V9?@T_ZA@8&3#]%">19T>(+BE_$:EBI7YB!'N<
+M33*E_Y(CHT6.,H8#WG[0W6:79>/K<1M9FB6'B_X9\I";A;Q,[1^.O9_=(<*C
+M@3']U97@UWA/Y=W4=$_FR\SB61"7M3!)+>;]&ZW+0#4*85?-$^YUVT?:7N?Q
+M0_AF%#BW'`L\FJ:18?4X!NR._`[7GE?61$.FY\..[%QZ2^'F&W]Z(+7X<U#8
+M[_9Y@;.C6M5'C+8/IDP%BZ2VG%%9%I,5MRA'@U\P!MV`<A6!:Q>(0;R?[J'5
+MN2]KY%$HDA^S"*VK;TQ,Z$8K3A-:)>@'K`'FO%ZX*KRLKG+P3:,,.V"@QC!S
+M^DN*76M228@B^B&U20&!KB-8<&L<PF$WFXZ+'R_8V8>;ZL]W4H#38W]M7^72
+M.W"!1W,5VV%8LV>:KDE:%9F)*ML^_&]6-_O?)H;R!Z%6NLWK$H/0KXUT!!I(
+M.GD=DD,'GWUVF>1DX9:%G"1^#<[VJE5@!B@P"5:X1(?!J2A+`6"B```58```
+M6%```!20```3Z```$^@```_D```HH```$U@``!&(```0B```2?```!*H```2
+MJ```%!@``!08```3:```%"@``!0H```4*```$[@``!%X```2*```$[@``!*8
+M```16```%"@``!.X```0"```$[@``!#8```4&```$1@``!*H```3>```$2@`
+M`!'(```4&```$.@``!*X```1R```$-@``!*H```4&```$V@``!)(```3N```
+M$J@``!08```2J```%!@``!*H```4&```$K@``!*H```4&```$X@``!.(```3
+MV```$R@``!)X```98```$N@``#?````0&```$G@``!E@```1V```$N@``!)H
+M```1>```$B@``!(H```WP```$!@``!#(```32```$X@``!.(```3J```$Y@`
+M`!"(```12```$@@``$FP```0B```$#@``!"(```3F```$(@``!+(```2V```
+M$M@``!"(```RT```)@```"8````36```$S@``!"(```3"```$\@``!18```4
+M6```%%@``!18```46```$#@``!18```2.```$C@``!(X```Q\```$M@``!0(
+M```0F```$&@``!08```2*```$B@``!"X```2.```$+@``!(X```2.```-#``
+M`#0P```T,```-#```#0P```T,```-#```#0P```T,```-#```#0P```1N```
+M$6@``!#X```0>```$$@``!+X```3V```$,@``!-(```0R```$T@``!#(```3
+M2```$T@``!-(```32```$,@``!#(```0R```$,@``!-(```U$```-\```#A@
+M```WP```,?```%;````2B```$H@``#N````0R```$T@``#N````0R```$T@`
+M`!#(```32```$H@``!&8```2N```$H@``!08```[@```$,@``!#(```32```
+M$T@``!(8```2J```$:@``!0X```1.```$_@``!*(```0J```$H@``#9@```W
+MP```,?```!*(```2J```$H@``#9@```U$```$H@``!*(``!6P```$H@``!*(
+M```0R```.&```!*H```42```$H@``#?````2J```$H@``#9@```V8```$J@`
+M`!*H```2:```$7@``!`H```32```$_@``!*X```2:```$K@``!&H```2:```
+M$K@``!/8```3&```$U@``!)8```06```$0@``!)8```3V```$E@``!!8```0
+MR```$T@``!)8```1"```$,@``!#(```1"```$T@``!-(```0R```$T@``!/8
+M```26```$%@``!#(```32```$0@``!)8```2B```$0@``!#(```32```$]@`
+M`!)8```06```$,@``!#(```0R```$,@``!#(```32```$T@``!-(```32```
+M%!@``!-(```1"```$E@``!'H```1"```$,@``!#(```32```$T@``!/8```5
+M,```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X
+M```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@`
+M``_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```
+M#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/
+M^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X
+M```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@`
+M``_X```/^```#_@``!'X```5D```$?@``!9````1^```%M```!'X```78```
+M$?@``!?P```1^```$?@``!B@```A1```(5L``"#]```=7@``'6H``!YQ```>
+M4```'5```!U0```>B@``'S$``!^B```EJ0``'LT``![-```?!0``&H$``"$;
+M```CMP``)?0``!JD```=5P``&J0``!JD```<````'/$``!S^```<_@``)>``
+M`"7@```<5P``'%<``"2R```@R0``''```!QP```@/P``'^D``!XR```=N0``
+M'C(``!FR```EJ0``)<<``"6]```DU```)1H``!HQ```=ZP``(#4``"2-```C
+M00``(Y@``")U```A\@``(:,``"B"```G=P``*`@``"=H```GP```)X```"A&
+M```GV```*"P``"A9```F@```)H```":2```H;@``)H```":````F@```)Q``
+M`"<0```F<@``)H```"9R```F^0``)H```":^```F^0``*8L``#$P```OOP``
+M+#H``#"!```K[0``+`<``#`3```P5```,#P``"_H```P8P``*QP``"L2```K
+M'```*?\``"HF```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC
+M```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,`
+M`"EC```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC```I8P``
+M*6,``"EC```I8P``*6,``"EC```IVP``*=L``"G;```KHP``,6T``"NM```K
+M0@``,4P``"NM```KP```*ZT``"NM```KP```,<L``"HF```J)@``*B8``"HP
+M```I7@``*ZT``"NM```KK0``*ZT``"NM```KK0``,/@``#0D```ST0``-!P`
+M`#,I```S(P``,RD``#+D```TX```-$P``#7S```UN```-<L``#9````V'@``
+M-;0``#6T```W10``-R```#>Z```VF```-I@``#:8```V@0``-I@``#:8```V
+MF```-I@``%$0``!+(```3H```#ES```Y)@``.?D``#I*```[4@``.:@``#HJ
+M```YQ```.+(``#KB```ZP@``.OX``#IF```[-@``.J(``#L:```Y%0``.9<`
+M`#GH```Y8@``.-H``#R(```[LP``.ZH``$`\``!`*@``/^L``#_K```_N@``
+M/X0``#]R```_A```/X0``#YT```^K0``/DT``#XT```^-```/+```#UP``!!
+M5```09(``$"@``!!$```11P``$4<``!$]P``1J@``$95``!#5```0U0``$-4
+M``!(>P``1_4``$@U``!)!@``21H``$CC``!(Q0``1C```$8(``!%<```17``
+M`$>P``!%WP``1^4``$?3``!%]```1O```$<```!&T```2,X``$(```!)I0``
+M0?4``$>```!$4P``1((``$2"``!#M```0Z<``$(N``!"(```1/<``$2U``!(
+M1P``2(X``$3)``!%N```1$8``$1U``!$=0``0L$``$-4``!#`P``1S```$-4
+M``!"@```1,D``$-,``!$]P``0U0``$-4``!#`P``0P,``$@U``!(-0``0U0`
+M`$K]``!-I0``3.0``$UO``!-1```3*,``$R!``!-\0``3=\``$MH``!,`0``
+M3`H``$U5``!-_@``2V@``$W%``!.'```2V@``$O)``!,T@``3CH``$Y4``!.
+M<@``31,``$QP``!,70``3,@``$S2``!-"0``31,``$V>``!-E```39X``%"%
+M``!0:0``4`(``$_4``!.R```4+,``%"A``!.R```3S<``$]```!0P```4-\`
+M`$[(``!/R0``3[8``%!6``!030``4%8``%44``!2L@``56D``%3?``!4WP``
+M5-\``%5&``!60```5B@``%44``!5=@``45@``%4T``!3J```5(```%/A``!4
+M8```5!```%2@``!40```5,```%*'``!2T```4OX``%,V``!3;@``4Y8``%,@
+M``!3*0``4N<``%+Q``!36```4V$``%.-``!3E@``5:```%+$``!2E```5KH`
+M`%()``!2$@``4;T``%%8``!4^0``5F0``%9^``!6G```4H<``%*'``!2;@``
+M5>P``%7B``!5[```5A,``%8<``!7H@``5\```%<&``!7!@``5T```%=``'__
+M[(*_<*GBTO8J#[&TS@MGB4R]0=<':N.(W\G9G;.:/7*.,11&`00&``0)I/&$
+M;(>X)P`'"P$``B,#`0$%70```0`4`P,!&P0!`0```@,$#,"<7L#`:@`("@$]
+M?9*5```%`1$/`'@`.``V`&4`>`!E````%`H!```M0RMQLYT!%08!`"$`````
+!````
+`
+end
diff --git a/libarchive/test/test_read_format_7zip_bcj2_lzma1_2.7z.uu b/libarchive/test/test_read_format_7zip_bcj2_lzma1_2.7z.uu
new file mode 100644
index 000000000000..a8316cf599e5
--- /dev/null
+++ b/libarchive/test/test_read_format_7zip_bcj2_lzma1_2.7z.uu
@@ -0,0 +1,240 @@
+begin 644 test_read_format_7zip_bcj2_lzma1_2.7z
+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
+>90!X`&4````4"@$``"U#*W&SG0$5!@$`(0``````
+`
+end
diff --git a/libarchive/test/test_read_format_7zip_bcj2_lzma2_1.7z.uu b/libarchive/test/test_read_format_7zip_bcj2_lzma2_1.7z.uu
new file mode 100644
index 000000000000..a9a19b905dd4
--- /dev/null
+++ b/libarchive/test/test_read_format_7zip_bcj2_lzma2_1.7z.uu
@@ -0,0 +1,287 @@
+begin 644 test_read_format_7zip_bcj2_lzma2_1.7z
+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
+M2U/W5(E==I9FG8(OQJ,M*1GQ%+%`3@WP-A,.*:T(>!\C6X+H6[?]`JJ2%]6Q
+MX&(A=:Q\UJIM+))_2U.!1"!5[<8U5AZH-@VYF$C.Q2VV^AM!1<O"_G/1_^CP
+M.S-((2N\)>1S(=G;M#;*N85A^C%4I*V9?@T_ZA@8&3#]%">19T>(+BE_$:EB
+MI7YB!'N<33*E_Y(CHT6.,H8#WG[0W6:79>/K<1M9FB6'B_X9\I";A;Q,[1^.
+MO9_=(<*C@3']U97@UWA/Y=W4=$_FR\SB61"7M3!)+>;]&ZW+0#4*85?-$^YU
+MVT?:7N?Q0_AF%#BW'`L\FJ:18?4X!NR._`[7GE?61$.FY\..[%QZ2^'F&W]Z
+M(+7X<U#8[_9Y@;.C6M5'C+8/IDP%BZ2VG%%9%I,5MRA'@U\P!MV`<A6!:Q>(
+M0;R?[J'5N2]KY%$HDA^S"*VK;TQ,Z$8K3A-:)>@'K`'FO%ZX*KRLKG+P3:,,
+M.V"@QC!S^DN*76M228@B^B&U20&!KB-8<&L<PF$WFXZ+'R_8V8>;ZL]W4H#3
+M8W]M7^72.W"!1W,5VV%8LV>:KDE:%9F)*ML^_&]6-_O?)H;R!Z%6NLWK$H/0
+MKXUT!!I(.GD=DD,'GWUVF>1DX9:%G"1^#<[VJE5@!B@P"5:X1(?!J2A+`6"B
+M````%6```%A0```4D```$^@``!/H```/Y```**```!-8```1B```$(@``$GP
+M```2J```$J@``!08```4&```$V@``!0H```4*```%"@``!.X```1>```$B@`
+M`!.X```2F```$5@``!0H```3N```$`@``!.X```0V```%!@``!$8```2J```
+M$W@``!$H```1R```%!@``!#H```2N```$<@``!#8```2J```%!@``!-H```2
+M2```$[@``!*H```4&```$J@``!08```2J```%!@``!*X```2J```%!@``!.(
+M```3B```$]@``!,H```2>```&6```!+H```WP```$!@``!)X```98```$=@`
+M`!+H```2:```$7@``!(H```2*```-\```!`8```0R```$T@``!.(```3B```
+M$Z@``!.8```0B```$4@``!((``!)L```$(@``!`X```0B```$Y@``!"(```2
+MR```$M@``!+8```0B```,M```"8````F````$U@``!,X```0B```$P@``!/(
+M```46```%%@``!18```46```%%@``!`X```46```$C@``!(X```2.```,?``
+M`!+8```4"```$)@``!!H```4&```$B@``!(H```0N```$C@``!"X```2.```
+M$C@``#0P```T,```-#```#0P```T,```-#```#0P```T,```-#```#0P```T
+M,```$;@``!%H```0^```$'@``!!(```2^```$]@``!#(```32```$,@``!-(
+M```0R```$T@``!-(```32```$T@``!#(```0R```$,@``!#(```32```-1``
+M`#?````X8```-\```#'P``!6P```$H@``!*(```[@```$,@``!-(```[@```
+M$,@``!-(```0R```$T@``!*(```1F```$K@``!*(```4&```.X```!#(```0
+MR```$T@``!-(```2&```$J@``!&H```4.```$3@``!/X```2B```$*@``!*(
+M```V8```-\```#'P```2B```$J@``!*(```V8```-1```!*(```2B```5L``
+M`!*(```2B```$,@``#A@```2J```%$@``!*(```WP```$J@``!*(```V8```
+M-F```!*H```2J```$F@``!%X```0*```$T@``!/X```2N```$F@``!*X```1
+MJ```$F@``!*X```3V```$Q@``!-8```26```$%@``!$(```26```$]@``!)8
+M```06```$,@``!-(```26```$0@``!#(```0R```$0@``!-(```32```$,@`
+M`!-(```3V```$E@``!!8```0R```$T@``!$(```26```$H@``!$(```0R```
+M$T@``!/8```26```$%@``!#(```0R```$,@``!#(```0R```$T@``!-(```3
+M2```$T@``!08```32```$0@``!)8```1Z```$0@``!#(```0R```$T@``!-(
+M```3V```%3````_X```/^```#_@```_X```/^```#_@```_X```/^```#_@`
+M``_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```
+M#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/
+M^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X
+M```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@`
+M``_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```
+M#_@```_X```/^```#_@```_X```1^```%9```!'X```60```$?@``!;0```1
+M^```%V```!'X```7\```$?@``!'X```8H```(40``"%;```@_0``'5X``!UJ
+M```><0``'E```!U0```=4```'HH``!\Q```?H@``):D``![-```>S0``'P4`
+M`!J!```A&P``([<``"7T```:I```'5<``!JD```:I```'````!SQ```<_@``
+M'/X``"7@```EX```'%<``!Q7```DL@``(,D``!QP```<<```(#\``!_I```>
+M,@``';D``!XR```9L@``):D``"7'```EO0``)-0``"4:```:,0``'>L``"`U
+M```DC0``(T$``".8```B=0``(?(``"&C```H@@``)W<``"@(```G:```)\``
+M`">````H1@``)]@``"@L```H60``)H```":````FD@``*&X``":````F@```
+M)H```"<0```G$```)G(``":````F<@``)OD``":````FO@``)OD``"F+```Q
+M,```+[\``"PZ```P@0``*^T``"P'```P$P``,%0``#`\```OZ```,&,``"L<
+M```K$@``*QP``"G_```J)@``*6,``"EC```I8P``*6,``"EC```I8P``*6,`
+M`"EC```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC```I8P``
+M*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC```I
+M8P``*6,``"EC```I8P``*6,``"EC```I8P``*=L``"G;```IVP``*Z,``#%M
+M```KK0``*T(``#%,```KK0``*\```"NM```KK0``*\```#'+```J)@``*B8`
+M`"HF```J,```*5X``"NM```KK0``*ZT``"NM```KK0``*ZT``##X```T)```
+M,]$``#0<```S*0``,R,``#,I```RY```-.```#1,```U\P``-;@``#7+```V
+M0```-AX``#6T```UM```-T4``#<@```WN@``-I@``#:8```VF```-H$``#:8
+M```VF```-I@``#:8``!1$```2R```$Z````Y<P``.28``#GY```Z2@``.U(`
+M`#FH```Z*@``.<0``#BR```ZX@``.L(``#K^```Z9@``.S8``#JB```[&@``
+M.14``#F7```YZ```.6(``#C:```\B```.[,``#NJ``!`/```0"H``#_K```_
+MZP``/[H``#^$```_<@``/X0``#^$```^=```/JT``#Y-```^-```/C0``#RP
+M```]<```050``$&2``!`H```01```$4<``!%'```1/<``$:H``!&50``0U0`
+M`$-4``!#5```2'L``$?U``!(-0``208``$D:``!(XP``2,4``$8P``!&"```
+M17```$5P``!'L```1=\``$?E``!'TP``1?0``$;P``!'````1M```$C.``!"
+M````2:4``$'U``!'@```1%,``$2"``!$@@``0[0``$.G``!"+@``0B```$3W
+M``!$M0``2$<``$B.``!$R0``1;@``$1&``!$=0``1'4``$+!``!#5```0P,`
+M`$<P``!#5```0H```$3)``!#3```1/<``$-4``!#5```0P,``$,#``!(-0``
+M2#4``$-4``!*_0``3:4``$SD``!-;P``340``$RC``!,@0``3?$``$W?``!+
+M:```3`$``$P*``!-50``3?X``$MH``!-Q0``3AP``$MH``!+R0``3-(``$XZ
+M``!.5```3G(``$T3``!,<```3%T``$S(``!,T@``30D``$T3``!-G@``390`
+M`$V>``!0A0``4&D``%`"``!/U```3L@``%"S``!0H0``3L@``$\W``!/0```
+M4,```%#?``!.R```3\D``$^V``!05@``4$T``%!6``!5%```4K(``%5I``!4
+MWP``5-\``%3?``!51@``5D```%8H``!5%```578``%%8``!5-```4Z@``%2`
+M``!3X0``5&```%00``!4H```5$```%3```!2AP``4M```%+^``!3-@``4VX`
+M`%.6``!3(```4RD``%+G``!2\0``4U@``%-A``!3C0``4Y8``%6@``!2Q```
+M4I0``%:Z``!2"0``4A(``%&]``!16```5/D``%9D``!6?@``5IP``%*'``!2
+MAP``4FX``%7L``!5X@``5>P``%83``!6'```5Z(``%?```!7!@``5P8``%=`
+M``!70`!__^R"OW"IXM+V*@^QM,X+9XE,O4'7!VKCB-_)V9VSFCURCC$41@$$
+M!@`$":3XA&R'N"<`!PL!``(A(0$(%`,#`1L$`0$```(#!`S`G%[`P&H`"`H!
+M/7V2E0``!0$1#P!X`#@`-@!E`'@`90```!0*`0``+4,K<;.=`14&`0`A````
+"````
+`
+end
diff --git a/libarchive/test/test_read_format_7zip_bcj2_lzma2_2.7z.uu b/libarchive/test/test_read_format_7zip_bcj2_lzma2_2.7z.uu
new file mode 100644
index 000000000000..8a31482b9319
--- /dev/null
+++ b/libarchive/test/test_read_format_7zip_bcj2_lzma2_2.7z.uu
@@ -0,0 +1,240 @@
+begin 644 test_read_format_7zip_bcj2_lzma2_2.7z
+M-WJ\KR<<``-OBM(#`2D```````!Z`````````']'IDO@7ILD\%T`/Y%%A&@[
+MWP)!,(6+]:YDCG/TF9,6Y4@I6&:W,\L.GXAK)SG^7$ASM;Y]KP;]Q:,S]93R
+M>,&)>5<,&FZE"`#6^N9W.O9$'UE^T-50DI_AD]BN$0G/D?)@D^5S4+=>0I33
+M8+60+5WO?S\=&H#(CWK#P8A*.F39U-N85;*`7:QH4MPY]Z"R4@0-G[PN0P/I
+M&4U*T@DV'"`CQ@7=GL@J7_2-A[.]&`<]D>$^(9=0(?Z*\Z.%M#RG1BD;5#6(
+M4_PL?`47!00BJ=5&HZ7@@B$C<B:7G5+BU\D93(72,@V,AXSY]N)()U=,T%KY
+M^_Q^$0#V<O6P>!NO::D+1C%8P).\)*UDX0P@<+::RMJNW=<@+:$ZER\IE^S3
+M<>=HCZTGM[:O[2?'(:Q@840D]\]5Y73NXY[]$A&S9_<=T[^)S9E-I@,/"Z%N
+M3%P8EQ8N.<>T1U:G?9*=LX1R,65>5\LCE.PG__FU`+L]UUEKFS13]3C4N`J/
+M2*#MK;D6R_YC0[KZK#6ZDVED3OA(WO_#+'G.!7!DNT&:A<:N8%2S1T,0<.CX
+MWI?5110E(]/(V5U26WQEEBY"+^%%%QQ*$$LVGS;&M##OO=PE)#7IOV]4!T0>
+MMCVFR7A^)`*]D,D*8(TTY<\22+QK022#]K1P8Q>ZDOE"5%*XR1S_RD)#8:OF
+MV8PM<:&:XO9&=U7J?O95W3V[0_>S$IA67];6D(/WJJ:Q>6%"L4.3$3?0E!!$
+M%?%!2/7&XB4BNO1`#<J3[T8<*V))G$F+G#:@?'L>[FYN$MKM,TL^'./,4GY)
+MNO_;YJ7P.<8Z"R!*LK]S`B1=P4X(^JK3]7X8N(%H?=H&K>KB'G7(0C'R=1Z0
+MZ`IBTR?O>DKYV:WR$Q0MRO.CI2E[0;'KUGX`,?^8H_"$EOK=81Z5Z4VZQ'O;
+M;O;-'3N/M(@343API(#U5#X1=PK%4)/F?[I"DE\39HS<'P)7H49\16$$ES92
+MA@%4O+Y4AD=?Q`Q6L[^+YH+AJ-Z!]8./"Y'^Q"*$TJ#,%/ESOJCC)X:D@0R_
+M?J)%YC&F):9`]N(:_,O,>0]$-QL,-?ZE@EH7Z=TEA\M7949(]"*65F<KQMX'
+M]Z2J4/%(YMK(6R`Z>N\?-CF(U?7P0?R&\DOWV5DVFK[.JXEP>WU1IL?6K&/C
+MWJ(7%PM9ZI:B)8)Q$N-53QL+1O[;'7O/7/O^;3JY[WU7(!DWS`YXM'QL?+>(
+M"XZ7)FJ3#T4640CH[0Q8U319C-]L^2259=A(C)[[!/*9P+!6MXIH$N)1*Z:&
+MQIZ7]E*8%(B.D'_@P=8!H(?*X?N@HB+MAKFN3F][.%W':*1!5I4=/"TFY>,\
+M=4<$EI/)\S[27U*=0/;8!0P4W/=5+RC"*W]L[Z>GIXO;=$L;^CKMC<M]VV%U
+MDDM(3=>.FK$GA0?W<=3^K@8Y^D_FAZ!W7WZ#<PX4\A=O8"B1".+>.6HO6/_:
+MM&X<5E:RAU)=J;SF.%&+0R;V*[FQB?;-D6E*-E9A9B[,4F',0KL8S]AZ3/3,
+MAZ!6('R])>:,3R!'4,\HCK1#'3_?PE4$NKGPX,R?.IK6$:/[E%8278\-K\&D
+M4\:14"/(J(V,!$2BJH@D@[TOT`^<-9#'>!Y!%G[3Q4L[4EU[56_:"*>E#X'=
+ME='@D%<V7:ALNQ#3%Q&&F)5?%Z`+@K:N[%472^PWOJJ\;W*WI3F48(K[\95K
+MQ0K\<@QZCO3-RE(T_%U[(6W*"G^]EP8Q*BF@^1*KF#\I!J8"#B_$J%&62LX+
+MHU84)`V]@9F_MU(DLD8OF.A/H/$&)"JW<6@D/5:4`.TD:QQ':N,!';*FTXY"
+M/D!(;8Z;OS$1#&;0F073-,'1%TU'U6'K=^6`TD@FV(>RN4=E!\F6P+B>NF-E
+M.')J;D/S>](@#H.CZB,"S;X1F.)O-8.%W0+\OBW-QVYBLHRW$*]^CP(Y/U\G
+M<3B;CDT0]"EG+*#EDEZI35$5+9S<?!^YHF*TNF_:#'$VKZ/_[V<4Z(7J163C
+M3Q!L9<*AU3P1+N"/4=DB,?I:O%_B:4A:O]</9I@%]7O2ZB9V8`K;`N;G$9*9
+MW%=-EN`/*J)L81BO\44WPC\'M_VUFXO9G)SLP\`CWU3;UX1EK#%@S0_<Z/*U
+M39%7+R,5):I&P&N<;FSH637[TSER0RR\_ZZ*+!DT0E-VC%@Z$7;T[30R%M7C
+M4LP;ELMK)I%1L_*Z($@(8Z'ZH$O/<O6KB'N?KA8RC"NIF8U&J&Q[;1WNZ+MY
+MK;TQ1P,S=)NETY">&_^!_A78^X7/<2I.4Y;"H60LCL"Q.5U=,LHK4"6W:HZF
+MZ?(LI+*?1?]2$%"5;V^Y]A>V$A;XY*$P"@WF:#I'$>>Z@'G8"9##/BP&7S4P
+MR+!4&:25@0#?WAT5NTR6,RW,<NIWU9.3OG-Q0??P]E/)I">0XNFDRGJJ'"[!
+MB#`M[^0!B$_UO("?`8';,_EYIF/`YS,HY7,OO1Y`A$BAQXI(K,:Z?[$DK[LF
+M1JP-RIXI[\KEKZST5NF-26U91M2>F]R-?H6.97>%;M$0B&E;\FPR!_8150K#
+M<]3V($5-6SHJ[/"&TYD;ST3!R#@B92\![8+L/;^9;:^+(C'(Z[&A,_Y7P=$6
+MSKYQ6J=0*0/@I?K_Y@L:A'XR_=%D=4UM5^8.7CZKI3H%Z.&F'T_0IX<D+B</
+MOW\"<>B62\2+(R4=NDDVG8N]A(]M&ZH6-!N;N%IEGNP%1\$646$4*?JTOC-1
+M%3H/UB]S<G%3S&[=`8%%>-NON.J5*JN\71XV9L`?IV0DNQY87`Q/JQERXF.B
+M<<1R$A7$??LEM.:+%*JG+/SM23OHC_X[]'*WW.H;R658END(V=8SJK]K^DVX
+M!XR.GLR_FS_7>CF[]F7&4V3E<#!^5`/B!C955]_-N(F0[!^%U)G(D<Z*3]\I
+MHU\KZRD94]*B4[8$H:^JZV3XM'>X,Y-SWE%.TJ1,KN7K_JS^OH?.6U\4@Z>K
+M5-0[1GY`57LW:6>GO'!>FU^^MH"`=0.VICBJW_"`.<R6QHUUQKYZ>AN^14_A
+ML&:(BY,W+\E%!4$G^;3$!WW_)J>_-%0KHJUB`ADT\<V=^]GYG=E*Z)L!=G$7
+M2^H>]#`$W3*]RC&JDCHP0&BAT2\;Q#N>&MUFH8&I[^72X/_V&S]J0[4:!R+L
+M=FR<(I>K3G<79].'1C5M'U>E=@A:6<8C&M4)IEIC='07>AK,.RT4,[9^6M!/
+MQSSK`/9&I/X#T`#T0[ZY:H-6_F*QC:."_0I<'O:3-EJ910,KJ[^>E@H2O$OK
+MG>0HH/;\>`:*1^*-<'X_;P-,1-C>?E?<23A=YI-VJFS]NL;H`D?>=%N\ZC)L
+M4V5TO-RL,S:O8KM?0')<[`-@&.`>$;')_TT/3IZX02G6'789"M6-5^4_;N;L
+M$B053<U($5P?;A@[[W6=JZU/($R,_7-R:I,;B:[Q=0'1(2XA3(4>#PY8*6KD
+M%Q\#"G99*RY0Z]!B"5/58<Z7LAY#'2M.PZMMQQ"A_/;%'L3QH'*#K*^1T>PT
+MJAH.UI_>?7]0O.%'W&>\4J*)FOS]X!HZC^6GLFA%'@VA%5#''Q\V@K:?WJ>\
+ML3D"9G\%![+R^KAFA7Y:!61'?B`@^9'[)U]1R,&85*!E\A5CGU:'E%0\O$LH
+MS2\"B(18$R)+4?8NA^8`SJ]-5YD)A:3U7\GMJ,K(\79#AA8J#X81K0]V6#WS
+MKG7W7G1]WTS59JPM\?#9<UB_1$JRS=$"N)YR7`O%Q";J!8\%3NDMIXT.U-YZ
+M+D;`XO?$0-_[J!)@A>`DSGO[3FCJ1U>0F[XY,5-D!`)ERPIK8YNZ<1#3T^S:
+M+C8/16@5=L/='P>_ER`"1V@R?`1@:Q1[!6=R<"SM.1N==H%HFO'0C;.%HC""
+MAY8(+BC0_^(<;#3G4^ZS(=R32LH'F5REZ:9J?G-L9X46GT<ARI^@WI*7SZJ,
+MB&1^2%0_^SB=ZJ,<-57)2B^:99HG9(&+QZ[W,'.M^9N(YG+>)QPNQD%CIER2
+M^OB@<;/$_%R:QR)8XMOG._E1^&KX=&ZLC"B'D1YVJ;&*&^[OM/-`LW*+@$^I
+MEI1*2HUNJQ$;!@T3%"-OC(Y!&.N$]^G=1CAVWG>^;4K_CU%0O?[>H$C:%&Z#
+M9RH1=WZI-'G2?PM[0D<!&+WM>M@VUD@'#-X[!I3X\F&Q$/-C9._<FP$PHEWX
+M$`X\]+-I^NY'K/,^H)#KB5K2Z(DQY7G&K,U(-16-=98RLPQ`41TP_CLWPP3S
+MG\O!=/^,F@]E!Z!)RYC88K#3Q)>6,;]T=KCX)Y#+K,"OJP?9GAK-^S5RJ)0L
+MK;Y3A54>@BNYR?&'45;186QEIU)WBT\DW7B?FWL.W>MQ@X.Z>"2*RFEB$JP=
+M]&M4<+V>]D82H%QX6X:9COZU1JD]$X=;-3)%D'S;\?5L1[^;7F11T)=3:EQ;
+M3M#([X>4>&:!^+/A#!=)N+/]DT'U'1FKJPXL=@G^!$A6=H049Y(?^4G-.Y.4
+MJ(BY#1.4:$>D@T;H$PNN>VP6G9',Q;\'M<S+]Y2]\6[N;KJU4EI`9-%ZRX"\
+M>$']7TDC/%-"4)#^/D2F%I!-LN&EJCEVS]<X8N>-O:`+MVO0,`YI(<X=K]NC
+M3UD8U?UC&=_9+V<IYZ&_*--T5?8KGKPR.SVG;KFLK93S_PW`4XY?1,-VY=V6
+M,@QN'S2[OCW\4F#*Z#2_Q?=-HT.QZP;@Y/''*8<O]0$6K&S(3L;>KBH\>4I`
+MAQT>X'U5T('3V/#GB:4M'08,UE]/U:&?L]AOUO6U$NF:J\#BSS8'[5F"/95"
+MR)[@B@^(_]/+<%9),KA*@T80#.%W^/LT\['V\G=-6-_`,Q8=,W"*9.8P@^@Y
+MN))H,NOY4W@9@ZTU-J@XV.(D=_XT[[">*B,8"9RT/@M,K3(/J\Q8T(/_QSJF
+MC-[EWGPVDLJ=P'\G6VL2'<>CKJGX$)05&0H?$N4,=*`+_5?7W7@?[KBY*@$<
+M'%7QWH>&1A6<5`$UD3B8;S@,[1!$--9<5)=Y\0MU&;I860&<'[2K:C35?'HK
+MD.YL1#(/_N\WBKS'7LT6Z`7I&6JZ*4`0E,!)N,,`S\L-<M$?*$THK,53AG&-
+M\87Y$)/Y$>7)?K&;9;I81V+/*(=<[ZW;%I*D+@@"IEC63J81?NT^^A/!B?OJ
+MZ1?6IFN`L,JZ`]?W8FW'LNFBO+EJ^%>$*E64)G.V]D?]7FHW3G24:D)`BB6.
+MR)PC>@T/MH1)Y2]ED,YCW&6Y1#H.N`M\NW&B(K4/GEXYR4]/3E5/JM&7(TBV
+M9#Y73UIJ"74MB'_A_60"U=9$<:=?E_:EQ#$Q['-B%F4Z'\V\^B?(>UWEK:?:
+MN9:&]7VNQT"K/+E7./L_%?*NNYFS?WBHYFQ.MTF7[U%<(M&(>,>E4FK[GJC2
+M,B8B)J[W]@R<X!J'=+.L<UO?P5X+Y0U\3EW_FDGB;%6FH>5F;=);<ZJF3%<H
+MTC<&,V.F&6<9(R9==+J41V]8ZP&5J([O+7N.X7Z/[]I_Z?$^6-S8?)$=<KE5
+MMY-=^3"U@2=#9B%U]P\FV#9_OJ_9LD8N'N_/`&2MDK!`JI4377YT^\Q-=*]R
+MA2$$0A`H,*("69I->`Y+[*PK'#H@PRD3RVKND8UI9/\:#<>R2`H<]#GY@H6D
+M,GKG_+@OSOG[5;B=T6?,IKNB/)37_L8<ZM6V%2@!-C<[V=.9($!@14_$$;)T
+M9]`EB@+S4/)&/"X1$O/?`!)<?_'_/[7RAK)0>`3<W[8Z^@H[H7H,W.ES'CO)
+M;WH=2>N"CV04E30(C[`_,C1ZM\8:&B^^KOU5L$`AL/B4[FM$"'X(X,3>V,:2
+M1%"T%K_=",4-.[%]PW[1EW<R!I*^#>0*.N;E=7M&MR14C4SFP,;2RTAT93N<
+M6`4Y'.]'<0Y*G?\Y)K'Y,`E[^!:SZ7;[J%F(,BDT)O\.4%"^OY7BYH=[M`;A
+MPMZLWJTV#PLN&E9SS*W%+IK"\`](5W89"?A2QZE;+:.;UU0V*!4@-OK9WM:"
+M)2G$X-G+YDLV!!0N[S-``]+V<'+4F9,3Z/IJL[?+K6%^$LW7+/+T28:LZHN_
+M^^%)%O;V`!$@U\W)O\%V1=N1KA?>#2.+$,J5</8<+3,EI@QRK[6G('R*O%BF
+M-YT+)VG=Z':J$C_3DFK[/BA(66VE[)5P*RFI#+A)PX/2PL_R9B;V.<=^"@BU
+M6VAX_[[P>I\X]`L7D@B_\LHJJS%\C@&6O,)W^$1^X6SH@Q;4\*<JYJJ0!2?-
+M[F.#93'1&]K;N7TS4SY!5[DN:YKO/%=7OJVH.7''!ETFA!5%L78@DKG3'8B$
+ME.4Q[L8]YEM'\G@:5]Q_@UDC,Z==UPW1N+47U37,8/+EG5%/J'.'$F@J2T0L
+M]'V-;T52A$8D!:A<^:O<.@A$]L`+=<]G&K:QC6JN-<`E.S?$63]*5O1/`5_;
+M1_VG%:S.(H7@?-B[GOT8C_^[\+_2#'T19%Y$)!-DL&#?:I"5L'/]18#Z90<?
+M8[_[XKJ\PE7M"(WP7.C>F6*L<]"^U7,:ECU%;Y;Z^AY9QD+86BL72A*#)L82
+M8G*3ZFIDP:@S,=0>12UD`2LN_77?>SHB3H+5:(J['1-,?=,CL]S+Q5:`=U%\
+M;L;^S03-*=G[8HV`*E5O4<@A)[3-2Q(!23U#1&MG_9B/`IT9E&\^J3SLK[AL
+ML*HQ:F5TP7H>R>=_SQ.6[2K^^;]C@3A9ZQQ_1''XFFAE@R1]$R:,;WYJ9><8
+M)B@P,H`YP>:6RAX5-<J<+#A/:^CZ^K2;?7$=>?]\Q,TY;<Y^]+XNXIZ>A\*B
+M58&9FYM_/5(=II"YZBL!Q07-BQ7''E@?+M9(1A(^7K2(_K_0^1!%-R"BG9%\
+MWX$S&BQI447_A:E]3`MY8L3$15/PLL,,V.D"<#!TS&&,2D>/W15B5L`*5Q,V
+MXX3>OU:E8M.QP!MX`_DR^G^>>F$ZJ%`#44].FM;>9R>],DI:A+5J4M-\([Y<
+M'B$8HT6O,3L7$@>Z6V23)DXL30&7P!MD^*E2C%HN;RG0#P:#?^H$9WSH\QV.
+MA&\N_#PEE#(*4>VY3*]&JS-JQA;>ZVX*@>\RR'>XPOO[Q/-B89$#95Q>^-#U
+MX"<?#&*@/S?ONK&E:8WH59Q<6O;,>;H%=R0+:J`P\Q,.US(!JB`7Q6EO8AC@
+M:1'HJ!DV\R$FV#MK0'W.*XGF@LVCAF0BY*_CQ@8Y\>9KAXX$<*60D=9]I1`^
+MV8!;IZJ15\1HK%V;2.$5*(11I^PR9$L!=LS0.>V5)8=N$`J3X-?:&W$02^%;
+MED7R]>'E3G:C,5I"=R(S#>;VFF!T:8H>:N\A;$3`DZ\[QS*(TM['0KDC+"PJ
+M]?;?LX)"]RT?;(0ICY;HY/XV4C]LL^9+6<:]Z"]2>V*7*82U#8X5`WI%\]/_
+MFJ,J?[^&P&,U*C<G9IM(#ME<6V+G+:0K5O*U[NF']NN(;1>?*1!%W!JGEO"E
+ML]HQ.G#\B1&H%Y:ZLO@L^0TH9"#?80.54)Y:)NR;2G_;/?66G880!=2O?<U7
+M@A'&S1F-H[>"(Q4&^TZ-&J#+RNDBC<$HYE6M7<KWXMC_;4OXRBYS?GJ.+4Q)
+M/P$7B<XG(DSKHYBZ*.SP9!"=E2LT89J`.!7@*TKD]6B#"]&SN94F@W$ABDM5
+M4!IF21Z/7V[$V9`R`'V"_'5E+0D275->ZQ_RKG/H;+MJN"J[SNK[H*>V^OFI
+M@^GJPQ-0VZM-/PMMC7(C$7W6IC.D$NV'S'^R`["3]:2:)ZU4E"-\FO-GFK)T
+M=U[O7*>/9&F(F&)=3D`5J'B5WE"G9-D4=I".:5-V_I83LAB7+V]2#']4.#T9
+MJ_O9UD?,@ONJR/<K"&=^LY3WCKEI^M62/08#6=0)\.\_G^A`"H`J-$<:IO:C
+M[3)M^[P0BES!WD.WWG_CE#WW@J,;6)3=G#V<5I)*A?;*,YT/Y\QE8*U*.WR1
+MHW[#ZB(:^A4;B.9A4&-%MRM5\ZD;_P#2G/06D%1[RYJ"#UPD;7;%=HG%G8:@
+M2S8(3R!9)ZD3B<A>4A`Z1)*<T'W:7KF^WEF_8B1=_,**EE:WX15EJSH+G['$
+MP=YOYTX4+'C2^L;IE1)&]2HZ:!E@E\KT`AHW*=]R"+:'P-=32L?`T"]WS%!M
+M.[4/5)+7VK,[)@8N^<X8,HO*+4[;H5%;@J&=310C*']IK.4Q^2S+/6W$\6/J
+M/I8\$(7>JT?P_B,SW4S,;XG4><,28D@FJ%N66*K&<1&R%E2*"5&O%[>U20*L
+MM"@$-WS:2G[W3L-3;Q\IXG#N&GXAEB$ENVP+`]QWWI;FUFNFZZMC6)[@AGZ4
+M4AJ:/[!*HCE?QE',)MJ!0O-N+!,F(5=0#\][W5:O6)6"NV+K,DJB-KHRE-1B
+MZW_Q%TW39.+UJ4-UB-P&!,GZ(V(D1/4E+I%R,=[OZ,5[[W<#:.F;)&.'6P:7
+MR82KS$=QBQCV_D+<&B.1F?NVQFNA5#-UD;VRE3:Q1>20U5U0CSDH\6+IE8D'
+M&T3`X)V@/G-NDUCKD15JBL@DX]8XM(;XEX%\JU/O^977K]H4$CKJ>N^/F2\6
+M:7IE-D5$WV?@R"XQRK#!F8CDKD*84=P7]!/+$U5\!D$&:$8--5F@!+QO\_,N
+M:@8QAP.>ETO'5=*$*7^!B&C,<7].Z7>;D?+A>ZPQA$BF,<9^/\/\"#:/9@86
+M7V="7`M'6;4Y4..L9^9#-Y:ECQJ:UVJ/TY+=N0`1"$82TGD$2O.%/9:-NX,_
+MKLBYXFR2!AY-\F>4\X-2,6^GP57R?T%!]JEGA@IIM:8G)._0!'Z,Z>(1CO2$
+M#CN-&!D:W=^<PF1;.?:RCV/>$#VYAHWK`*97^NZ";B18_)$&0$,P54J^T+]Q
+M:1&X7ZOX+.6-SGM=)-;O6X(WW`6.EI%")'=N?^/'91?K1`N.!">2.%4RLKR*
+M&UX;S+1"\PVI,<WI:+?'&574/^YD"(C,DOQ5QN5C*IT8%=UK+!D=M!`7LZKY
+MU$ZE1:.)>2L&5X(&ED%7HG&)//_$)+O\_F-OH4'FF:+SUT?L&PK(K;I+IX@W
+M6B1![(%W2A>[GK>WE,34L\P7KQ07_QANUF7(ULOVASH42%#LT^!]CHL3D>"Y
+M2"[DF(`ST3/='[0!8%[XDG/ZI,T^X0J<T#FN@ILW(M5C\5PVV/1D+M\INPJ_
+MIZ:1Q*/LN-L-ZH4X&QZ-'!KP0(E[(@PD@7=@K<)']L8L!4<,FVYD</'V>XA:
+MIRH]*>X=]"Z=V.LJ1;]78D8*DD+[!]%)2%CX=G^<@_9MIOC`_8_AA"(TPBH7
+MXN-*:]1VF<`QGL87I#TH.+%QJH][(T5NE40+NI"CP%<5NGZ*?;628\O/:4R@
+M[<2)3O+!E*I9ERFSXK:\&N3(-+9_O0N69;#7VU7U@Q`-&42_6O5T1J$F<,A?
+M,GW92OO,R+V^>0`2"XIT4CEF[<)^AZ#).1%MS4B!:!E">OT'X'.*<&SJ.R6@
+MF$EC%54$F36,5'`;Q([%_M"\#G\WH/$M%L/F%^=YUND)Q:J^IPPSS^3E(&QT
+M*75E^,)MW#[_;$`)>3].RC7!<R(2>."?J^0/2,S8(0"SL\QO:(OR!!1J)MDM
+M9@OPYW\&:H*^6B-X6!C,L!Q9/1*]F.8FNJR,&2.]!B/EQYT6*[RF0`_('NY8
+MDC493"!#[_8)N+5KG.`')R.``AW^93-2"9?),:`E"?N1N`B0[C21TZC#T5*W
+MJR8AH)];CBEV41)9?5[&7(^LTPRIU^A@,;Y8/-9H9.2.@0+OP`IH+*&A0J*<
+MEN]^="*Y&E05<Z]D+@57*(7S.UWLT)'K\++]]&7^I^!N`+W2&.F99*LF/`.[
+MD%;E)^'^YJ_W,XZIVX$C!&\!VE@;(3V%/N59;Y?L2TQ-D6T>'`U/X%3\7GN+
+M,C);X*IE)FD27"H8M*O/VT^J5%(-F/9L;)FJ(1H&U=##?58FI(N4ZC=C:+NQ
+MS]1O*D"EL:C9%MF>5$M#%YO&2@%&TII1N1M234_2CF`9!;?P>,9WKE^4+%9J
+M=DNM$OTA04QHA.U=\2^:]X$!!L^($1>51^JVZE]<PJ,9]*`CS5K4RO43O._0
+MX0]OJ+!"&#VL+`/9^>J'!*H;BZ>.GE&O!4,=T"@!>>/L&\$J@`%=`;*N=ESG
+M(O<R[AEYM(LA8[YE(`UBW1%!ER>AG7MIF`(Q2^:_W`JH\IU@D<PY58T$:D!_
+M:68G_!FU!RP;H9]3"]9*Q299_OQ^6D%7[?G!-NXC$KZS1A4_@Q&.]))`?J7D
+M^=S#OT##/[F"Z4^&?:)OXD\^;$==]0EZC*R`V&[O/K=&.Q.K"JUXHXPA%9CQ
+M*C23`0/O3T\<Q29]_G&.OD9$AA=,"HP8W,^`8Z(+FC_9G]3!2[L=ZZ-SC)F%
+M,B9<5K,+_`6)16L.KE!9)_&X7.62V<4*"I2H!+X5,._XH_[WMIW1Z,B<)GJC
+M0&;F^U]C%9=DL"5-7@-HTYCJ'>Q^KHZKRM*;HOB5OB0Q\-[\U")X@PWIU!I_
+MC:[4\X.U]"!MK&&R.7\,>(*6ZE,\2^TE?2,GJ9WYAJXU6L"5VFX-5R%>L])(
+MPI"$[J<AHJ.$7MQR1^2T[PATVT`Y@<L;HRVR#K-LH\FOO^I>1@`2L@#TC@E[
+M0B8H"MQKOIUWTIUB'E7.Q$`MKQ&*OT*V$27$CIJK;*CEO?=6PWJBD2\!B5'N
+M72(D?<L"T:[\!Q[I!$KRR1)GP%9K(SZC^Q59&RRP#Q`-;[01D]A&GL6#`!E&
+M9;=_T37PBFZP)`;J-WG;5T_Y(0$M\^\=U9D2E)A4!#SB^_4^D+ZP)E1$#S3<
+MD=FKF=4S3MXRQ02[Q7V25[!SW)@?!"(MS>>$I4!I[06.KT!)Y:^8B3E$A\6]
+MGVKQ5H$-X\,#5;HA*G]>TQ[58K!(*%N"S0Q<(&=ILTVS_6!K>@77J#T8].5$
+M(8%8V[<DJ2</MR</CQQ1W<TAJ(PD,M#@R%0P7J%D4Z#83;N6JK4,>M^S#"]#
+MLO@=SO4$DMK!M3083U<&)`DI+4^*.W/A(J-!(:R5#N3+"^LUGH!(/T7O3#T?
+MA;=!AR>F&AFC3:2S/"'3'!G>V80+^\>:'A<^;H#1)E[^&?=WN*C4>E\<TW:N
+M;)]FZL3@A"-'*HIBRTR6S>8)[61*2L^><<<DCJR8[4.GT`K\>;#R8A]"'5ND
+M6O&_<'@CD"CWV]FE_[1);\69),/-(+,LJ.0LU?\H]XL8_:7H($?.0)&_"HQG
+M,3&]EBG5G2W%^1-%OU&WDS@Y6?$`^;B)C`I]!83*J#II"K<]X1'6YT,(JU!H
+MG35]1X*S-5,5QA;;UJ!D1=0%3I?PF::/OZ<#L;R=$U\QS1.H.=Y+AEC.K)V!
+ME])AA-S.DA!KDN^QV]F62-./+*.UTH:114D"$V$DWD#/0ME2$7S:X(*:2#N,
+M#_QI>28\KDT-3,MQ%:]@6<H;'U"/!SUK7FP+0E7:4X25SW``75K"Z\;='5U*
+MK;?6Q-[J.MPE6[9#Q8Q9W/O7T7&^]/E]@`B3%W`\PWE>4-;GIS8V8\4X(3Y_
+M#`Q03=@9"XPK'J.,QB(W?OXW5`7?\SO5-PIJV<IU!QT?4JZT87DKB*M/UB`!
+MM*0+V^>H*]GUT45V.6$YM+*Y,`Q=QC(+E`H"&\85Q"3.&FB6$+IQ=$_^HA`N
+M$;=S<KSXV\(3=%0:^H.6\E@6.\C8R;/M,9\[056SO215U%1PD3*+A0Z]D%8Q
+MO:Z7@*@SHYX&"1LJQV;->IDL-@1?3\>O!E;O\[$YU^(*"D@ALTGYRJR<DJGV
+M,GQ.RLRNQ3\8ODY?+4U2PZIF(@`1\O$+1]T,C]?D+UV#=5N+-D2`C:NOZ]<%
+M#&Z1I':?P(>F<*+]`@[O!L.,Y<XX[9VX[;_^I]+L8^44KWL$[-/Q\!7+DSY3
+M]KE'+Z?;8*HF7I-\!S@1!V504\\0;-F#Q4LP_^>9)<Y+14D4V#8K2#RFPP`2
+MV\%!"(RC,TH?#%L^*SKT1W=59QAT_C+KR_I;-CB[0"%5]^3!T?<!6ST+9K4`
+M\8W"LX+1UE!^_(M4IUCX"0M4@CK*^6[>3XPOHE[D2K5$LD',W4Q>/%F\+/'"
+M2U/W5(E==I9FG8(OQJ,M*1GQ%+%`3@WP-A,.*:T(>!\C6X+H6[?]`JJ2%]6Q
+MX&(A=:Q\UJIM+))_2U.!1"!5[<8U5AZH-@VYF$C.Q2VV^AM!1<O"_G/1_^CP
+M.S-((2N\)>1S(=G;M#;*N85A^C%4I*V9?@T_ZA@8&3#]%">19T>(+BE_$:EB
+MI7YB!'N<33*E_Y(CHT6.,H8#WG[0W6:79>/K<1M9FB6'B_X9\I";A;Q,[1^.
+MO9_=(<*C@3']U97@UWA/Y=W4=$_FR\SB61"7M3!)+>;]&ZW+0#4*85?-$^YU
+MVT?:7N?Q0_AF%#BW'`L\FJ:18?4X!NR._`[7GE?61$.FY\..[%QZ2^'F&W]Z
+M(+7X<U#8[_9Y@;.C6M5'C+8/IDP%BZ2VG%%9%I,5MRA'@U\P!MV`<A6!:Q>(
+M0;R?[J'5N2]KY%$HDA^S"*VK;TQ,Z$8K3A-:)>@'K`'FO%ZX*KRLKG+P3:,,
+M.V"@QC!S^DN*76M228@B^B&U20&!KB-8<&L<PF$WFXZ+'R_8V8>;ZL]W4H#3
+M8W]M7^72.W"!1W,5VV%8LV>:KDE:%9F)*ML^_&]6-_O?)H;R!Z%6NLWK$H/0
+MKXUT!!I(.GD=DD,'GWUVF>1DX9:%G"1^#<[VJE5@!B@P"5:X1(?!J2A+`6"B
+M``!__^R"OW"IXM+V*@^QM,X+9XE,O4'7!VKCB-_)V9VSFCURCC$41@``8%,_
+MK6'!CL%DP"0&RS*\T@G^FX5\H?W4!!O!PH8>.28_N-V8TR"&GIM3`P+>$\OJ
+M(9>,0-S]CR6X8T$\%"J+S?I("0(UJ*,)P10!!=6%O7W#`'"J?E$N>X%_;8JG
+MS,>$[4SVI>F3\R75D5\%>5<.J=2FF*K6]@<=B(3",I@9FHTB[YAEO8P`V+4P
+M8C9Z#"<.436Q5F2$3TE/'F+O;J7)#ZL;Y@JYC6[]@E%9`SU*4E_91_/UGTP]
+M6`Q.3?S`A/:;-2["5G]4PJ-M0.OP,X:S5W+`V(SK[)K`V2XCN('B@"LL=."@
+M0]28A^*]U1=EN2FW4?/079VF4?1I%P0U$X$#<%P`,I@TXJHHA;13#E_"5-!M
+M1N#XV"%+-_(<[?7E5.H-T?V0.4(Y=_[F;JNM]U/5*.BP`&W1E"U$6N*%G=CX
+MD`^]ZB%?IOM!X.,)?3GB%U@NUH*ESQ#`_T\3OGS)$9V4"#5PV;H*M_-VJ7/^
+M````8#QPB!OI_5N-]9<GG.3'.L]3/HU_Y2S;E@"^-+IC+I8)PIPF=X+'+"17
+MDG.(X_M.^[N#E%)C.Y$^JMR'8O"U*0ZFZ\:5Q)[>+R[;;6`MP,RS%^5G3#E1
+M#$3`EZ4@PLLD)TUJ]29W2HQ36\-=H27+^)ZQZMGD\C62MB#W%#\E8DQG..#C
+M/9M:G'U=IF::L0KY"PNDIM2JTYWYG`?P2=]<56=5Y3W^#(;]L#L&FLK\H>*2
+M^^U'LPE_,VIM0/HPWOVC"A0R%2C*8@<RO;_T5;.'J`<09/_-K3`L.GFKEG8L
+MKC7=G6V-,GOT5O>+R03(3I(%L&(7X^OYE?>7;,E2+$/P#9Y>%YXV-TPA9/RK
+MBY*2GW'`&4D$PD?(C%:A+JXL:)`_6][+LK%7?Z3YB%5AY.L_^TT.*JE@!4;E
+M6:Z*3$U/0V)\!J*_%;'QD8O-T^U4R:CA'7='ZH+`CA7:_&B"W4DZ+X9N?">\
+MN;JUI[?Q5O%JG+V<$1J=N3`-1YK/E*FVQ_;`40;LJZ^7S?[/^OQN!VA>-KS=
+MJ5#%T:U^#O**)TU\#7Y`\\%GB^UJWL8"!D=DS,E([8,LR"C&;I$/),`!?;C7
+M+MR6QLHPXQCR!P^O81:5^\8(Z6!:R)8)SB/GF.O!/P7)U*,]G44C?,,M0*7J
+M77A)I%C8-BD2^^',N$$L'OU"7,W2$S59[!ED>..B2/FI$&+_G(%M6=OH96B=
+M*36WZ;/MFF=9_1$5'Q33GD?M`,UX7;%7X7_&UWBQF:G\<M6='!*3)Y[66=>*
+M-(P^SG$>FATRW5PH_#E0W/Z>!A;8[!)L%&NGHY#%_WJR=U??LG@4SOT4/0`!
+M!`8`!`FD^">!;H)T``<+`0`$(P,!`05L```!`",#`0$%;````0`A(0$(%`,#
+M`1L$`04`!`$#`@(&`0`,A[B$;,"<7L#`:@`("@$]?9*5```%`1$/`'@`.``V
+?`&4`>`!E````%`H!```M0RMQLYT!%08!`"$`````````
+`
+end
diff --git a/libarchive/test/test_read_format_7zip_bcj_bzip2.7z.uu b/libarchive/test/test_read_format_7zip_bcj_bzip2.7z.uu
new file mode 100644
index 000000000000..7bff5c0d55e3
--- /dev/null
+++ b/libarchive/test/test_read_format_7zip_bcj_bzip2.7z.uu
@@ -0,0 +1,281 @@
+begin 644 test_read_format_7zip_bcj_bzip2.7z
+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
+*%08!`"$`````````
+`
+end
diff --git a/libarchive/test/test_read_format_7zip_bcj_copy.7z.uu b/libarchive/test/test_read_format_7zip_bcj_copy.7z.uu
new file mode 100644
index 000000000000..3883ab74bb77
--- /dev/null
+++ b/libarchive/test/test_read_format_7zip_bcj_copy.7z.uu
@@ -0,0 +1,613 @@
+begin 644 test_read_format_7zip_bcj_copy.7z
+M-WJ\KR<<``/3^:6)P&H```````!2`````````&3-#_Q_14Q&`0$!"0``````
+M`````@`#``$```!PE`0(-````+!F````````-``@``<`*``:`!D`!@```#0`
+M```T@`0(-(`$".````#@````!0````0````#````%`$``!2!!`@4@00(%0``
+M`!4````$`````0````$``````````(`$"`"`!`@T70``-%T```4`````$```
+M`0````!@````X`0(`.`$")@"``!,!```!@`````0```"````B&```(C@!`B(
+MX`0(V````-@````&````!`````0````L`0``+($$""R!!`@8````&`````0`
+M```$````4.5T9!A=```8W00(&-T$"!P````<````!`````0````O;&EB97AE
+M8R]L9"UE;&8N<V\N,0`````(````!`````$```!&<F5E0E-$`,<^#`!#````
+M60```$````!5````&``````````]````5``````````\````.@```%(```!&
+M````%P````````!!````-P```$0```!.`````````"T````6````&0````4`
+M``!-````5P```$@`````````'@```"X````G````20``````````````-```
+M`%8```!8````*``````````*````"0````````````````````T````^````
+M-@```%,````,````(````!4````R````(0```"L`````````40```"\```!*
+M````4```````````````0@````````!,````0P````````!/````-0``````
+M```````````````````````````````````````````````````!````````
+M`````````````````````````````P``````````````#@``````````````
+M````````````````!@`````````+`````````!L`````````````````````
+M````'0```````````````````!(`````````'````!H```````````````(`
+M```3```````````````E````#P```!$````0````!P```"(````4````````
+M`````````````````"8````P````(P```````````````````"0````X````
+M`````#L````S```````````````?````*0```"H`````````.0````0```!+
+M````,0```$4`````````/P```$<```````````````@`````````+```````
+M``````````````````"6`0```````*,````2`````P,```````#"````$@``
+M`,$!````````-````!(```#&`@```````#,````2````J`(```````!#````
+M$@```$L!````````2````!(```"N`@`````````````2````E0(```````"A
+M````$@````0!````````;@$``!(````.````B.`$"``````1`/'_R0$`````
+M````````$@```!<`````````/04``!(```!M`````````-0#```2````E@(`
+M``````"A````$@```$("````````6@```!(````U`0```````"H````2````
+M`@,```````":````$@````4"````````E````!(```"B`0```````"T````2
+M````V0(````````S````$@```-@`````````[0```!(```#R````H.($""``
+M```1`!<`N```````````````$@```/,"````````[0```!(```"D`@``````
+M`.<!```2````Q@````````!/````$@```'("````````!0```!(````@`@``
+M`````-D+```2````S@$`````````````$@```"<```#DCP0(`````!(`"@!=
+M`@```````"P!```2````N0$``.3C!`@$````$0`7``L!````````/0```!(`
+M``#J`````````#X````2````[`(````````9````$@```!$"````````(0(`
+M`!(```!)`@``P.($"`0````1`!<`5@(```````!E`@``$@```.L!````X`0(
+M!````!$`$`"^`````````.8"```2````L@`````````M````$@```',`````
+M````]`,``!(```!H`0``Q.($"`0````1`!<`.P(````````T````$@```&<"
+M````````0````!(```#V`0```````!8````2````"`,````````Z`0``$@``
+M`,(!````````.0```!(```#+`@```````.T````2````(0,``)CB!`@`````
+M$`#Q_\\`````````00$``!(````5`P```````$$````2````DP```,CB!`@$
+M````$0`7`'D`````````#@8``!(```#^`0```````'@````2````FP(`````
+M```B!0``$@```"T```!\V`0(`````!(`#0#8`0```````)<"```2````&0(`
+M``````"8````$@```*@```#,X@0(!````!$`%P"M`@```````,L````2````
+M*`(``-#B!`@$````$0`7`&\!````````>@(``!(```"]`@```````,\!```2
+M````?`(```````#.````$@```(8"````````0P```!(```!:`0```````&<&
+M```2````>`$````````J````$@```&X"````````/@```!(````:`P``F.($
+M"``````0`/'_80$```````!5````$@```#,```!TX00(`````!$`\?\M`P``
+M3.0$"``````0`/'_BP(```````!B`P``$@```"L!``#4X@0(!````!$`%P`/
+M`0```````)L(```2````Y`$``-CB!`@$````$0`7`%,!`````````````!(`
+M``"%`0```````!H````2````A`(````````K````$@```+0"````````*0``
+M`!(````4`0`````````````2````Y0(```````"+````$@```*$`````````
+M8````!(```!)```````````````@````&P$```````!]````$@```$(!````
+M`````````!(```"!`````````!0!```2`````&QI8G5T:6PN<V\N.`!?1%E.
+M04U)0P!H=6UA;FEZ95]N=6UB97(`7VEN:70`7V9I;FD`7T=,3T)!3%]/1D93
+M151?5$%"3$5?`%]*=E]296=I<W1E<D-L87-S97,`;&EB;F-U<G-E<RYS;RXX
+M`'1G;W1O`'1P=71S`'1G971E;G0`=&=E='-T<@!L:6)C+G-O+C<`7U]M8E]S
+M8E]L:6UI=`!S=')C<'D`7U]S=&1O=71P`'=A<FYX`&EO8W1L`'-T<FUO9&4`
+M<W1R97)R;W(`<VYP<FEN=&8`86-L7VES7W1R:79I86Q?;G``9G1S7W-E=`!?
+M7W-T86-K7V-H:U]G=6%R9`!G971E;G8`;6%C7V9R964`9V5T<&ED`&%C;%]G
+M971?;&EN:U]N<`!?7W-T9&5R<G``;6%C7V=E=%]L:6YK`')E861L:6YK`&UB
+M<G1O=V,`9V5T=6ED`&UA;&QO8P!I<V%T='D`;W!T87)G`&9T<U]O<&5N`&UA
+M8U]G971?9FEL90!?7W-T86-K7V-H:U]F86EL`&9F;&%G<W1O<W1R`&UA8U]P
+M<F5P87)E7V9I;&5?;&%B96P`96YV:7)O;@!F<')I;G1F`&MI;&P`;'!A=&AC
+M;VYF`&YL7VQA;F=I;F9O`&]P=&EN9`!?7W!R;V=N86UE`%]?97)R;W(`<VEG
+M;F%L`%]?7W)U;F5T>7!E`'-T<F-O;&P`<V5T96YV`')E86QL;V,`7T-U<G)E
+M;G12=6YE3&]C86QE`'-S8V%N9@!S=')D=7``7U]I<W1H<F5A9&5D`&=E=&]P
+M=`!L;V-A;'1I;64`;65M<V5T`&5R<@!?:6YI=%]T;',`7U]S=V)U9@!A=&5X
+M:70`<V5T;&]C86QE`&9P=71C`&9T<U]R96%D`'-T<F9T:6UE`&9W<FET90!A
+M8VQ?9G)E90!G971B<VEZ90!A=&]I`'5S97)?9G)O;5]U:60`;6%C7W1O7W1E
+M>'0`<W1R;&5N`'-T<F-H<@!G<F]U<%]F<F]M7V=I9`!F<'5T<P!F='-?8VAI
+M;&1R96X`=V%R;@!?961A=&$`7U]B<W-?<W1A<G0`7V5N9`!&0E-$7S$N,0!&
+M0E-$7S$N,`````(``@`"``(``@`"``(``@`"``$``@```````@`"``(``@`"
+M``(``@`#``(``@`"``(``@`"``(``P`!``(``0`"``,``@`"``(``@`!``(`
+M`@````(``@`"``(``P`"``(``0`"``(``@````(``P`!``(``@`"``(``@`#
+M``(``@`"``(``@`"``$``@`!``$``@`"``(``@`"``(``@`"``(``@`"````
+M`@`"```````!``(`B0```!``````````L2AZ!P```P`R`P``$````+`H>@<`
+M``(`.P,```````"@X@0(!18``,#B!`@%)0``Q.($"`4K``#(X@0(!34``,SB
+M!`@%/```T.($"`4^``#4X@0(!4L``-CB!`@%30``@.$$"`<!``"$X00(!P(`
+M`(CA!`@'`P``C.$$"`<$``"0X00(!P4``)3A!`@'!@``F.$$"`<'``"<X00(
+M!P@``*#A!`@'"0``I.$$"`<+``"HX00(!PP``*SA!`@'#0``L.$$"`<.``"T
+MX00(!P\``+CA!`@'$```O.$$"`<1``#`X00(!Q(``,3A!`@'$P``R.$$"`<4
+M``#,X00(!Q4``-#A!`@'%P``U.$$"`<8``#8X00(!QD``-SA!`@'&@``X.$$
+M"`<;``#DX00(!QP``.CA!`@''0``[.$$"`<?``#PX00(!R$``/3A!`@'(@``
+M^.$$"`<C``#\X00(!R0```#B!`@')@``!.($"`<H```(X@0(!RD```SB!`@'
+M*@``$.($"`<L```4X@0(!RT``!CB!`@'+@``'.($"`<O```@X@0(!S```"3B
+M!`@',0``*.($"`<S```LX@0(!S0``##B!`@'-@``-.($"`<W```XX@0(!S@`
+M`#SB!`@'.@``0.($"`<[``!$X@0(!ST``$CB!`@'/P``3.($"`=```!0X@0(
+M!T$``%3B!`@'0@``6.($"`=#``!<X@0(!T0``&#B!`@'10``9.($"`='``!H
+MX@0(!TH``&SB!`@'3```<.($"`=.``!TX@0(!T\``'CB!`@'4```?.($"`=1
+M``"`X@0(!U(``(3B!`@'4P``B.($"`=4``",X@0(!U8``)#B!`@'5P``E.($
+M"`=8``"#[`SH8!4``.A06```@\0,PP```/\U>.$$"/\E?.$$"`````#_)8#A
+M!`AH`````.GX#P``_R6$X00(:`@```#I^`\``/\EB.$$"&@0````Z?@/``#_
+M)8SA!`AH&````.GX#P``_R60X00(:"````#I^`\``/\EE.$$"&@H````Z?@/
+M``#_)9CA!`AH,````.GX#P``_R6<X00(:#@```#I^`\``/\EH.$$"&A`````
+MZ?@/``#_):3A!`AH2````.GX#P``_R6HX00(:%````#I^`\``/\EK.$$"&A8
+M````Z?@/``#_);#A!`AH8````.GX#P``_R6TX00(:&@```#I^`\``/\EN.$$
+M"&AP````Z?@/``#_);SA!`AH>````.GX#P``_R7`X00(:(````#I^`\``/\E
+MQ.$$"&B(````Z?@/``#_)<CA!`AHD````.GX#P``_R7,X00(:)@```#I^`\`
+M`/\ET.$$"&B@````Z?@/``#_)=3A!`AHJ````.GX#P``_R78X00(:+````#I
+M^`\``/\EW.$$"&BX````Z?@/``#_)>#A!`AHP````.GX#P``_R7DX00(:,@`
+M``#I^`\``/\EZ.$$"&C0````Z?@/``#_)>SA!`AHV````.GX#P``_R7PX00(
+M:.````#I^`\``/\E].$$"&CH````Z?@/``#_)?CA!`AH\````.GX#P``_R7\
+MX00(:/@```#I^`\``/\E`.($"&@``0``Z?@/``#_)03B!`AH"`$``.GX#P``
+M_R4(X@0(:!`!``#I^`\``/\E#.($"&@8`0``Z?@/``#_)1#B!`AH(`$``.GX
+M#P``_R44X@0(:"@!``#I^`\``/\E&.($"&@P`0``Z?@/``#_)1SB!`AH.`$`
+M`.GX#P``_R4@X@0(:$`!``#I^`\``/\E).($"&A(`0``Z?@/``#_)2CB!`AH
+M4`$``.GX#P``_R4LX@0(:%@!``#I^`\``/\E,.($"&A@`0``Z?@/``#_)33B
+M!`AH:`$``.GX#P``_R4XX@0(:'`!``#I^`\``/\E/.($"&AX`0``Z?@/``#_
+M)4#B!`AH@`$``.GX#P``_R5$X@0(:(@!``#I^`\``/\E2.($"&B0`0``Z?@/
+M``#_)4SB!`AHF`$``.GX#P``_R50X@0(:*`!``#I^`\``/\E5.($"&BH`0``
+MZ?@/``#_)5CB!`AHL`$``.GX#P``_R5<X@0(:+@!``#I^`\``/\E8.($"&C`
+M`0``Z?@/``#_)63B!`AHR`$``.GX#P``_R5HX@0(:-`!``#I^`\``/\E;.($
+M"&C8`0``Z?@/``#_)7#B!`AHX`$``.GX#P``_R5TX@0(:.@!``#I^`\``/\E
+M>.($"&CP`0``Z?@/``#_)7SB!`AH^`$``.GX#P``_R6`X@0(:``"``#I^`\`
+M`/\EA.($"&@(`@``Z?@/``#_)8CB!`AH$`(``.GX#P``_R6,X@0(:!@"``#I
+M^`\``/\ED.($"&@@`@``Z?@/``#_)93B!`AH*`(``.GX#P`````````````Q
+M[56)Y8/D\(U%"(/L!%#_=012Z)`4``#,D)"0D)"0D%6)Y5=64X/L#(MU#(M=
+M$(7VC7RS!(D]Y.,$"'XUBP.%P'0OHP#@!`@/MA"$TG0C@\`!ZPH/MA"#P`&$
+MTG04@/HO=?&C`.`$"`^V$(/``832=>RXB.`$"(7`=#2+10B)!"3HZ!,``,<$
+M)'S8!`CHZ!,``.CD#P``B7PD"(E<)`2)-"3HH"@``(D$).A8$P``Z(@1``#K
+MT)"0D)"0D)"0D)!5B>6#[`B`/=SB!`@`=`SK'(/`!*,(X`0(_]*A".`$"(L0
+MA=)UZ\8%W.($"`')PY!5B>6#[`BA<.$$"(7`=!*X`````(7`=`G'!"1PX00(
+M_]#)PY"0D)"0D)"0D)"0D)!5B>6#[`R)'"2)="0$B7PD"(MU#(M]"(M&3(M8
+M-(M(,(M'3(M0-(M`,#G3?12X_____XL<)(MT)`2+?"0(B>Q=PWX-N`$```#K
+MZ&O,`````#G!=^\YTWX?BT90B44,BT=0B44(BQPDBW0D!(M\)`B)[%WI^!$`
+M`'RT.<%SVXUV`.NKC;0F`````(V\)P````!5B>6+50R+10B)50B)10Q=Z9`5
+M``"-="8`C;PG`````%6)Y8/L"(D<)(ET)`2+=0B+70R+5DR+2TR+0B@Y02A^
+M$+@!````BQPDBW0D!(GL7<-\#XM"+#E!+'_FD(UT)@!]![C_____Z]V+0U")
+M10R+1E")10B+'"2+="0$B>Q=Z?@1``"-M@````"-OP````!5B>6+50R+10B)
+M50B)10Q=Z4`6``"-="8`C;PG`````%6)Y8/L"(D<)(ET)`2+=0B+70R+5DR+
+M2TR+0E`Y05!^$+@!````BQPDBW0D!(GL7<-\#XM"5#E!5'_FD(UT)@!]![C_
+M____Z]V+0U")10R+1E")10B+'"2+="0$B>Q=Z?@1``"-M@````"-OP````!5
+MB>6+50R+10B)50B)10Q=Z=`6``"-="8`C;PG`````%6)Y8/L"(D<)(ET)`2+
+M=0B+70R+5DR+2TR+0A@Y01A^$+@!````BQPDBW0D!(GL7<-\#XM"'#E!''_F
+MD(UT)@!]![C_____Z]V+0U")10R+1E")10B+'"2+="0$B>Q=Z?@1``"-M@``
+M``"-OP````!5B>6+50R+10B)50B)10Q=Z6`7``"-="8`C;PG`````%6)Y8/L
+M"(D<)(ET)`2+=0B+70R+5DR+2TR+0B`Y02!^$+@!````BQPDBW0D!(GL7<-\
+M#XM")#E!)'_FD(UT)@!]![C_____Z]V+0U")10R+1E")10B+'"2+="0$B>Q=
+MZ?@1``"-M@````"-OP````!5B>6+50R+10B)50B)10Q=Z?`7``"-="8`C;PG
+M`````%6)Y8M%"(M5#(M`4(E%#(M"4(E%"%WI^!$``)"-="8`58GEBT4,BT!0
+MB44,BT4(BT!0B44(7>GX$0``D)"0D)!5B>6#[`B)'"2)="0$BT4(BTT,BP"+
+M4$"#^@=T<XL9BTM`@_D'=&F#^@IT3(/Y"G1'.<IT*XMP/(7V=22+->SB!`B%
+M]G4:@^H!O@$```!T0H/I%]?_____=#B-M@````")70R)10B+#>3B!`B+'"2+
+M="0$B>Q=_^&)70R)10B+'"2+="0$B>Q=Z:`8``"-=@`Q]HGPBQPDBW0D!(GL
+M7<.058GE5U93@>PL!0``B848^___H:#B!`B)1>PQP*%`Y`0(B944^___B8T0
+M^___QX64^___`````(7`=0VA1.0$"(7`#X2<!P``QX5`^___`0```,<$)-S8
+M!`CHB!```,>%B/O__P````#'A8S[__\`````QX6@^___`````,>%G/O__P``
+M``#'A9C[__\`````A<")P\>%J/O__P````#'A:S[__\`````QX6P^___````
+M`,>%M/O__P````#'A:3[__\`````=`F`.``/A2H'``"+O13[__^%_P^$O@8`
+M`(N%$/O__XN]%/O__\>%+/O__P````#'A3#[__\`````@^`"QX4\^___````
+M`,>%3/O__P````")A0S[___I7AT``(/X"@^$X`(``(NU&/O__X7V#X39`P``
+MBT=0@#@N#X2L`P``BT<L.X6L^___=@:)A:S[__^+%23D!`B%TG4*BS7LXP0(
+MA?9T'8E$)`2+1U")!"3H\$D``#N%K/O__W8&B86L^___BYU`^___A=L/A%P"
+M``"+5TR)T(M(/(N%M/O__XF5*/O__XM2.(G&P?X?.?%\#'\$.<)V!HF5M/O_
+M_XN5*/O__XM"!#N%L/O__W8&B86P^___BXTH^___#[=!"CN%J/O__W8&B86H
+M^___BXTH^___BU$T.Y6,^___BT$P?!9_"#N%B/O__W8,B86(^___B96,^___
+MBX4H^___BPU$Y`0(BT`X`84L^___A<D/A+H!``"+%0#C!`B%T@^$Y@(``(N5
+M*/O__XUUTHU=WXM"#,=$)`CWV`0(QT0D!`T```")-"2)1"0,Z*@2``"+C2C[
+M__^+01#'1"0(]]@$",=$)`0-````B1PDB40D#.BH$@``B;5$^___B9U(^___
+MBX5$^___B00DZ!@4```[A9C[__^)A3C[__]V!HF%F/O__XN52/O__XD4).@8
+M%```.X6<^___B<-V!HF%G/O__Z$\Y`0(QX4T^___`````(7`#X7:`@``H0CD
+M!`@QTL>%E/O__P````"%P`^%,@,``(NU./O__XN--/O__P'>C40Q&`'0B00D
+MZ&@3``"%P(G##X03"0``BY5$^___C4`0B0.)!"2)5"0$Z"@4``"+C3C[__^+
+ME4C[__^-1!D1B4,$B50D!(D$).@H%```BXTH^___#[=!""4`\```/0`@```/
+MA.<!```]`&````^$W`$``*$\Y`0(A<`/A0<"``"+#0CD!`B%R71`BY4T^___
+M@\(!@ST\Y`0(`1G`]]`APHN%E/O__XT4%HU4$Q*)4PR)1"0$B10DZ"@4``"+
+MA93[__^)!"3HN!,``(E?%)"-="8`@X4\^___`8M_"(7_=$V+1T"#^`</A1?]
+M__^+1R")!"3H>!$``(E$)`B+1U#'!"3PV`0(B40D!.@H$@``QT<,`0```,='
+M$`````"+?PC'!2#C!`@!````A?]ULXN5//O__X72#X1B`P``BX44^___BY4\
+M^___B858^___BX6L^___B95@^___B85D^___BX5`^___A<`/A<P%``"-A5C[
+M__^)!"3_%>#B!`BA1.0$",<%).,$"`$```"%P'0EB[T4^___A?]T&XN=%/O_
+M_XUV`(M#%(D$).BX$P``BUL(A=MU[HM5[#,5H.($"`^%LP<``('$+`4``%M>
+M7UW#C70F`(L-\.($"(7)#X5&_/__QT<,`0```,='$`````#I5QT``(/H`0^%
+M*OS__XL=[.($"(7;#X4<_/__Z]2+E2C[___'1"0$`````(M"#(D$).B8$@``
+MBXTH^___QT0D!`````")A43[__^+01")!"3H6!$``(F%2/O__^D`'```@[TP
+M^___#@^'%_[__XN5*/O__XM"%##D/0`!``"A/.0$"!G)@^'Y@\$/A<")C3#[
+M__\/A/G]__^+E4S[__^-1#,2B4,(B00DB50D!.@H%```BXU,^___B0PDZ+@3
+M``#I_AP``(N-*/O__XM!1(D$).@($```A<")A4S[__\/A)`&``"`.`!U(HD$
+M).BX$P``QP0D^M@$".C8$```A<")A4S[__\/A&D&``"+A4S[__^)!"3H&!0`
+M`#N%H/O__XF%-/O__P^&P/S__XF%H/O__^E7'```C960^___B10DZ!@1``"#
+MP`$/A/D$``"+1SR%P`^%!0$``(M'4(VUN?O__\=$)`CTV`0(QT0D!`$$``")
+M-"2)1"0,Z*@2``"+A0S[__^%P'1SBX60^___B30DB40D!.AX$P``@\`!='.-
+MA93[__^)1"0$BX60^___B00DZ"@1``"#P`%T5HN%D/O__XD$).C($0``BX64
+M^___A<!T<XN%E/O__XD$).@8%```.X6D^___B<(/AA7\__^)A:3[___I<!P`
+M`(N%D/O__XDT)(E$)`3HZ!```(/``76-BT=0B40D"(M'!(M`',<$)`C9!`B)
+M1"0$Z+@2``"+A9#[__^)!"3HR!$``(N%E/O__X7`=8W'!"3ZV`0(Z-@0``")
+MA93[___I/R```(M'4(VUN?O__XE$)!"+1P2+0!C'1"0(%MD$",=$)`0!!```
+MB30DB40D#.BH$@``Z>D?``#'A2S[__\`````QX4\^___`````,>%,/O__P``
+M``"A1.0$"(7`=0VA^.,$"(7`#X0!_?__BX48^___A<`/A7K\___I,AX``#'`
+M@SWXXP0(``^5P(F%0/O__^FR&0``B00DZ!@4``"-1``"B00DZ&@3``"%P(F%
+M'/O__P^$+`0```^V`SPZ#X0_!```BXT<^___B`&+C1S[__^+A1S[__^#P0'&
+M0`$`#[9#`83`=#V)VNL4B`&#P0'&00$`#[9"`H/"`83`="6`.CIUYSPZ=>/&
+M`3`/MD(!B$$!@\$"QD$!``^V0@*#P@&$P'7;@'G_.@^$RP,``(V%I/O__XN5
+M'/O__XE$)"B-A:S[__^)1"0DC86(^___B40D((V%H/O__XE$)!R-A9S[__^)
+M1"08C868^___B40D%(V%J/O__XE$)!"-A;3[__^)1"0,C86P^___B40D",=$
+M)`24V00(B10DZ$@2``#'!1CD!`@!````@_@(#X9?`@``B[6P^___,<"%]G0@
+MN0$```"X"@```/?A@^X!B<%U\L>%L/O__P````"-0/^+O;3[__^)A;#[__\Q
+MP(7_?C6)_KD!````,=MKTPJX"@```(F5!/O___?AB=.)P0.=!/O__X/N`77A
+MQX6T^___`````(U`_XNUJ/O__XF%M/O__S'`A?9T(+D!````N`H```#WX8/N
+M`8G!=?+'A:C[__\`````C4#_BXV,^___BY6(^___B86H^___@_D`B94@^___
+MB8TD^___#X[9`0``BXT@^___O@$````Q_XN=)/O__VO'"HF%!/O__[@*````
+M]^:)UXG&`[T$^___@\'_@]/_B=H)RG7:B?")^H/`_\>%B/O__P````"#TO_'
+MA8S[__\`````BXT<^___B86(^___B96,^___B0PDZ+@3``#I,1H``(N-+/O_
+M_XU=NHN%M/O__\=$)`@<V00(QT0D!!@```")C5S[__^)1"0,B1PDZ*@2``")
+M'"3H&!0``,=$)`@<V00(QT0D!!@```")'"2)A6C[__^+A:#[__^)A6S[__^+
+MA:3[__^)A7#[__^+A9S[__^)A73[__^+A;#[__^)1"0,Z*@2``")'"3H&!0`
+M`,=$)`@<V00(QT0D!!@```")'"2)A7C[__^+A:C[__^)1"0,Z*@2``")'"3H
+M&!0``(F%?/O__Z'\XP0(A<!T6,>%@/O__P4```"+A3#[__\[A8#[__]V!HF%
+M@/O__XN%F/O__XF%A/O__^GK'0``BT=0B40D"(M'!(M`',<$)`C9!`B)1"0$
+MZ+@2``#I-2```/\DA?#9!`B+E8S[__^+A8C[___'1"0((-D$",=$)`08````
+MB50D$(E$)`R)'"3HJ!(``(D<).@8%```B86`^___Z8TD``!\"H/Z`)`/AQO^
+M__\QP#'2Z9@C``#'A;#[__\`````QX6T^___`````,>%J/O__P````#'A9C[
+M__\`````QX6<^___`````,>%H/O__P````#'A8C[__\`````QX6,^___````
+M`,>%K/O__P````"#/1SD!`@!QX6D^___`````!G`]]`A!1CD!`CI=2(``,=$
+M)`3IV`0(QP0D`0```.B($P``9L<!,`#I\B$``(N5'/O__XG1@\$"9L<",#K&
+M0@(`Z:,A``#'1"0$_-@$",<$)`$```#HB!,``.C8$P``C;0F`````%6)Y5=6
+M4X/L'(,]_.($"`&)1>R)3>@9P"7`F`0(B40D"(E,)`2)%"3H*!,``(7`B<</
+MA$L"``#'1"0$`````(D$).AX$@``A<!T#(M-Z(G",<#H8!D``*'LX@0(A<`/
+MA1,!``"+-03C!`B%]@^$E@$``,=%\`````"-M"8`````B3PDZ.@2``"%P(G#
+M#X36````BT-`@_@"#X0B`0``B?8/C]H```"#Z`%UU8M+/(7)=`R+0U"`."X/
+MA(@!``"A).,$"(7`#X0-`0``H<#B!`B%P`^%5`$``(L5S.($"(M""(/H`87`
+MB4((#XAJ`0``BP+&``J#P`&)`HM#'(D$).C`-P``QP0D2MD$".@8$```BT7P
+MB3PDB40D!.AX$@``BTWHB<*)QHG8Z&`9``"A!.,$"(7`#X5&____A?8/A#[_
+M__^)7"0$QT0D"`0```")/"3HV!$``(D\).CH$@``A<")PP^%*O___^AH$@``
+MBP"%P`^%]P```(/$'%M>7UW#D(/X!'0)@_@'#X7R_O__BT,@B00DZ'@1``")
+M1"0(BT,<QP0D\-@$"(E$)`3H*!(``,<%(.,$"`$```#I@"8``)"+0U#'!"0M
+MV00(B40D!.@H$@``Z8`F``"#?>P!#XXN____BT,<B00DZ,`W``#'!"1*V00(
+MZ!@0``#'!23C!`@!````Z1`G``"+'0CD!`B%VP^%7/[___9%Z`C'1?```0``
+M#X59_O__Z7(F``"AS.($",<$)`H```")1"0$Z,@0``#I^28``(L5\.($"(72
+M#X0L_O__Z;XF``")5"0$QP0D"@```.A($P``Z?DF``#'1"0$3-D$",<$)`$`
+M``#HB!,``,=$)`0DV00(QP0D`0```.B($P``C78`C;PG`````(U,)`2#Y/#_
+M<?Q5B>575E-1@>PX!@``BQFAH.($"(E%[#'`C87L_?__BWD$B87D^?__QT0D
+M!,S;!`C'!"0`````Z*@3``#'!"0!````Z)@3``"%P`^$D0```,<%#.`$"%``
+M``#'!"15V00(Z(@0``"%P'0)@#@`#X43"```C87<^?__B40D",=$)`1H=`A`
+MQP0D`0```.A($0``@\`!=!0/MX7>^?__9H7`=`@/M\"C#.`$",<%#.0$"`$`
+M``"^$````,=$)`C(V00(B7PD!(D<).@($@``@_C_=#^#Z#&#^$=V,.BP20``
+MZ]C'!0SC!`@!````QP0D5=D$".B($```A<!TN8D$).@X$```HPS@!`CKJO\D
+MA13:!`BAV.($""G#B87(^?__H?#B!`B)G<SY__^%P`^$Y`4``,<$)%W9!`CH
+MB!```(7`=#O'!"0!````Z)@3``"%P`^$.P(``,<$)'79!`CHB!```(E$)`2-
+MA>SY__^)!"3HR!(``(/H`0^$6P8``(L5'.0$"(72=$;'!1CD!`@!````QT0D
+M!&"R!`C'!"0"````Z-@2``#'1"0$8+($",<$)`,```#HV!(``,<$)(G9!`CH
+MB!```(D$).C0,@``H4#D!`B%P'5!H43D!`B%P'4XH?CC!`B%P'4OH13C!`B%
+MP'4FH1CC!`B%P'4=H3#D!`B%P'44BQT<Y`0(A=MU"H/."(VT)@````"+#?CB
+M!`B%R74?BQ5$Y`0(A=)U%:'LX@0(A<!U#*$PY`0(A<!U`X/.`:$<XP0(A<!T
+M!H'.@````*%$Y`0(A<`/A.@```"AZ.($"(7`#X3U````QP40Y`0(`@```(L=
+M".,$"(7;=&.+#13C!`B%R0^%WP0``(L5&.,$"(72#X02!0``H0SC!`C'!>3B
+M!`@@E@0(A<!U8:%$Y`0(A<`/A-H$``"+A<SY___'!>#B!`C`P00(A<!U5(GQ
+MNA#@!`BX`0```.@`)@``ZU>A%.,$"(7`#X52!```H1CC!`B%P`^$P`0``,<%
+MY.($")"5!`BA#.,$"(7`=)_'!>#B!`BPO`0(BX7,^?__A<!TK(N%R/G__XGQ
+MC12'BX7,^?__Z``F``"A(.,$"(D$).A8$P``H?CC!`B%P`^$(O___Z'HX@0(
+MA<`/A0O___^-A>CY___'1"0$$.0$"(D$).@X$P``BQ40Y`0(B=#!^!_!Z!<!
+MT,'X":,0Y`0(Z1PK``#'!"1FV00(Z(@0``"%P`^%L?W__^DF*@``@\X@QP7P
+MX@0(`0```.EC*0``QP4,Y`0(`````,<%).0$"`$```#'!>SC!`@`````Z6,I
+M``"AQ.($"*/TXP0(Z6,I``#'!0SC!`@`````QP5$Y`0(`````,<%-.0$"```
+M``#I8RD``,<%&.,$"`$```#'!13C!`@`````Z6,I``#'!03C!`@!````Z6,I
+M``"#YOR#SA#'!?CB!`@!````Z6,I``"#YN^#S@+'!?CB!`@`````Z6,I``#'
+M!?3B!`@!````Z6,I``"#S@''!?CB!`@`````Z6,I``#'1"0(`0```,=$)`3,
+MVP0(QP0D7=D$".@($P``Z6,I``#'!3#D!`@!````QP44Y`0(`````.EC*0``
+MQP4,XP0(`0```,<%1.0$"`````#'!1#C!`@`````Z6,I``#'!33D!`@!````
+MQP5$Y`0(`````,<%#.,$"`````#I8RD``,<%#.0$"`````#'!23D!`@`````
+MQP7LXP0(`````.EC*0``QP4$Y`0(`0```,<%Z,0R"`````#'!3CD!`@`````
+MZ6,I``#'!13C!`@!````QP48XP0(`````.EC*0``QP7XXP0(`0```.EC*0``
+MQP4(XP0(`0```.EC*0``QP4,Y`0(`0```,<%).0$"`````#'!>SC!`@`````
+MZ6,I``#'!13D!`@!````QP4PY`0(`0```.EC*0``QP4\Y`0(`0```.EC*0``
+MQP4`XP0(`0```.EC*0``QP40XP0(`0```,<%#.,$"`````#'!43D!`@`````
+MZ6,I``#'!43D!`@!````QP4,XP0(`````,<%$.,$"`````#I8RD``,<%_.,$
+M"`````#'!>CB!`@!````Z6,I``#'!4#D!`@!````Z6,I``#'!?SC!`@!````
+MZ6,I``#'!?SB!`@!````Z6,I``#'!>SB!`@!````QP4$XP0(`````.EC*0``
+MQP7HXP0(`0```,<%!.0$"`````#'!3CD!`@`````Z6,I``#'!0SD!`@`````
+MQP4DY`0(`````,<%[.,$"`$```#I8RD``,<%".0$"`$```#I8RD``,<%'.,$
+M"`$```#I8RD``,<%..0$"`$```#'!03D!`@`````QP7HBS0(`````.EC*0``
+MQP4@Y`0(`0```.EC*0``Z,@3``"%P`^%#_K__Z'TX@0(A<`/A0+Z___'!?#B
+M!`@!````Z=LI``"+'1CC!`B%VP^%K?O__XL-!.0$"(7)#X1I`0``QP7DX@0(
+M8)<$".FM*P``H1CC!`B%P`^%(OO__Z$$Y`0(A<`/A!\!``#'!>3B!`C0EP0(
+MZ:TK``"A$.,$"(7`="W'!>#B!`B`P`0(Z<`K``#'!>3B!`B`F`0(Z:TK``#'
+M!>3B!`B@F`0(Z:TK``#'!>#B!`A`O00(Z<`K``"-G>3Y__^)7"0$QP0D>MD$
+M".A8%```B5PD!,<$)'W9!`BC\.,$".A8%```B5PD!,<$)(#9!`BC+.0$".A8
+M%```B5PD!,<$)(/9!`BC2.0$".A8%```B5PD!,<$)(;9!`BC*.0$".A8%```
+MA<"C`.0$"`^$TP```*'PXP0(A<`/A"'Y__^+'2SD!`B%VP^$$_G__XL-`.0$
+M"(7)#X0%^?__QP4<Y`0(`0```.DP*@``B00DZ#@0``#'!0SD!`@!````HPS@
+M!`CI7BD``*$XY`0(A<!U2:'HXP0(A<!T3\<%Y.($"+"6!`CIK2L``(L5..0$
+M"(72=1BAZ.,$"(7`=#S'!>3B!`A`E@0(Z:TK``#'!>3B!`C0E@0(Z:TK``#'
+M!>3B!`A`EP0(Z:TK``#'!>3B!`A@F`0(Z:TK``#'!>3B!`CPEP0(Z:TK``")
+M7"0$QP0D[=@$".A8%```HP#D!`CI^#```)"0D)"0D)"0D)"058GE@^P8A<!T
+M/:$`Y`0(QT0D"*"R!`C'1"0$`0```(D$).@X$@``N*"R!`B)1"0(H4CD!`C'
+M1"0$`0```(D$).@X$@``R<.A`.0$",=$)`@`N`0(QT0D!`$```")!"3H.!(`
+M`+@`N`0(Z\&0C70F`%6)Y5.#[!2+70B)V.CP,0``B1PDQT0D!`````#HV!(`
+M`.@(%```B5PD!(D$).B8$```@\046UW#D(VT)@````!5B>6#["B+10C'1"0(
+M`0```,<$)`$```"(1?^-1?^)1"0$Z&@0```QP,G#D(UT)@!5B>575E.#["R+
+M10B%P`^$0`$``(M%"#'_B00DZ!@4``"+%6#<!`AFQT7:``#'1=P`````B57@
+MB474ZSR-="8`#[["@^@P9H-]V@")`P^$K@```&;'1=H!`(/&`8/#!(/^`G5%
+M@\<!@T7<#(-%X`*#_PL/A-0```"+1=S'@&CC!`@`````C00_.474=SF+5>`/
+MM@*(1?(/MD(!B$7SC01_,?:-'(5@XP0(#[94+O*-0M`\!W:+C4*?/`=W)`^^
+MPH/H88D#ZY.+50@/M@1ZB$7R#[9$>@&(1?/KPXVV`````(U"OSP'=RL/OL*#
+MZ$&)`XM%W,>`:.,$"`$```#I*3,``,<$).S;!`CH*!(``.DC,P``#[;*.PW(
+MX@0(?0RAT.($"(N,B#0$``"#^7AT$P^^PHE$)`3'!"0TW`0(Z"@2``#'`___
+M___I*3,``(/$+%M>7UW#QT4(S-L$".GD,@``58GE5E.)PXTT0(/L$(L4M6CC
+M!`B%T@^%E````(L$M6#C!`B#^/]T.(E$)`BA\.,$",=$)`0`````B00DZ+@0
+M``"%P'0;QT0D"`"X!`C'1"0$`0```(D$).@X$@``C78`C01;BP2%9.,$"(/X
+M_W0UB40D"*$LY`0(QT0D!`````")!"3HN!```(7`=!C'1"0(`+@$",=$)`0!
+M````B00DZ#@2``"#Q!!;7EW#D(UT)@"A*.0$",=$)`@`N`0(QT0D!`$```")
+M!"3H.!(``.E,-```C;0F`````(V\)P`````/M\")PE6!X@#P``")Y8/L"('Z
+M`$````^$Q@```'Y1@?H`H```#X1]````@?H`P```=&*!^@!@```/A'P````Q
+MTJA)=%_VQ`@/A>(```#VQ`0/A+<```"X"````(UT)@#H,#0``+H!````ZSB-
+M="8`@?H`$```=%B!^@`@``")]G6]N`8```#H,#0``+H!````R8G0P[@"````
+MZ#`T``"Z`0```,F)T,.X`0```.@P-```N@$```#)B=##N`4```#H,#0``+H!
+M````R8G0PXGVN`,```#H,#0``+H!````R8G0PZ@"=#CVQ`)T$;@)````Z#`T
+M``"Z`0```.NGN`H```#H,#0``+H!````ZY:X!````.@P-```N@$```#KA3'`
+MZ#`T``"Z`0```.FT-0``N`<```#H,#0``+H!````D.FT-0``C70F`(V\)P``
+M``!5B>53@^QTB468H:#B!`B)1?@QP*$LX`0(A<`/B,0```"A1.,$"(7`=':+
+M'?3C!`B%VP^$B````(U%F(D$).BX$0``B5PD"(U=J,=$)`10````B1PDB40D
+M#.AH$0``H<SB!`B)'"2)1"0$Z/@0``"AS.($",<$)"````")1"0$Z'@0``"+
+M1?@S!:#B!`@/A<<```"#Q'1;7<.-M"8`````QP0D`````.A($```BQWTXP0(
+MA=NC1.,$"`^%>?___Y"A(.0$"(7`=#NA+.`$"+LTVP0(A<`/A5W___^[0-L$
+M".F8-@``QP0D.0```.CX$@``@#AD#Y3`#[;`HRS@!`CI@38``(M-F(L51.,$
+M"(V!`/'O`#G0?B:-@@#Q[P`YP7T<H2S@!`B[3-L$"(7`#X4%____NU7;!`CI
+MF#8``(L-+.`$"+M>VP0(A<D/A>C^__^[:-L$".F8-@``Z-@3``"0BQ4DY`0(
+M58GEBT4(A=)U"HL-[.,$"(7)=`F)10A=Z1!1``"+%0SD!`B%TG0)B44(7>D@
+M2P``B44(7>F`3@``D%6)Y8/L"*'`X@0(BTT(A<!U((L5S.($"(M""(/H`87`
+MB4((>"*+`H@(@\`!B0+),<##H<SB!`B)#"2)1"0$Z,@0```QP,G#.T(8?`:`
+M^0J0==.)5"0$B0PDZ$@3``#KSE6)Y8/L"(L-%.0$"(7)=!`E`/```#T`0```
+M='3),<##B<*!X@#P``"!^@"@```/A-\````/AXP```"!^@`0```/A%,!``"!
+M^@!```"-="8`=#ZH273&H<#B!`B%P`^%AP$``(L5S.($"(M""(/H`87`B4((
+M#XAX`@``BP+&`"J#P`&)`K@!````R<.0C70F`(L5P.($"(72#X6J````BQ7,
+MX@0(BT((@^@!A<")0@@/B!4!``"+`L8`+X/``8D"N`$```#)PX'Z`,````^$
+MD@```('Z`.````^%=/___Z'`X@0(A<`/A9<!``"+%<SB!`B+0@B#Z`&%P(E"
+M"`^(8`$``(L"Q@`E@\`!B0*X`0```,G#H<#B!`B%P`^%?@$``(L5S.($"(M"
+M"(/H`87`B4((#XC/````BP+&`$"#P`&)`K@!````R<.AS.($",<$)"\```")
+M1"0$Z,@0``"X`0```,G#H<#B!`B%P`^%90$``(L5S.($"(M""(/H`87`B4((
+M#XBZ````BP+&`#V#P`&)`K@!````R<.AP.($"(7`#X44`0``BQ7,X@0(BT((
+M@^@!A<")0@AX;8L"Q@!\@\`!B0*X`0```,G#.T(8#XWB_O__B50D!,<$)"\`
+M``#H2!,``+@!````R<.AS.($",<$)"H```")1"0$Z,@0``"X`0```,G#.T(8
+M#XTH____B50D!,<$)$````#H2!,``+@!````R<,[0AA]CHE4)`3'!"1\````
+MZ$@3``"X`0```,G#.T(8#XT]____B50D!,<$)#T```#H2!,``+@!````R<,[
+M0A@/C9?^__^)5"0$QP0D)0```.A($P``N`$```#)PZ',X@0(QP0D)0```(E$
+M)`3HR!```+@!````R<.AS.($",<$)$````")1"0$Z,@0``"X`0```,G#H<SB
+M!`C'!"1\````B40D!.C($```N`$```#)PZ',X@0(QP0D/0```(E$)`3HR!``
+M`+@!````R<,[0A@/C7_]__^)5"0$QP0D*@```.A($P``N`$```#)PXVT)@``
+M``"-O"<`````58GE@^PXB5WTB<.)??R)SXEU^(MP3*%`Y`0(QT7L`````(7`
+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
+MJ!(``(M&3(L`.P4HX`0(#X1T!0``C97+^___HRC@!`C'!23@!`@`````QT0D
+M!$````")%"3HJ!$``(/X``^.%P8``,<%(.`$"`0```#'!23@!`@!````H2#@
+M!`B-E<O[__^)%"2)1"0$Z#@4``"%P(G##X3V!0``C87$]___B40D!(D<).@X
+M$0``A<`/A:4%``"+A<3W__^%P`^$>04``(D<).CX$P``BUX4C4W,BY6D]___
+MBT,$B40D'(M"'(E$)!B+`XE$)!2+0BR)1"00#[='"HE$)`R+0B2)3"0$QP0D
+MC-L$"(E$)`CHB!(``*$\Y`0(A<`/A8D"``"A".0$"(7`#X54`@``#[='""4`
+M\```/0`@```/A*@!```]`&````^$G0$``(N-I/?__XM',(M7-(M)*(F-L/?_
+M_XL-_.,$"(7)#X2Z`P``C9V_]___B1PDQT0D&`<```#'1"04(````,=$)!#,
+MVP0(B40D"(E4)`S'1"0$!0```.BH$```B5PD"(N=L/?__\<$)+O;!`B)7"0$
+MZ(@2``"A!.0$"(7`#X6,`0``H3CD!`B%P`^%A0,``*'HXP0(A<`/A&8#``"+
+M1RCH8#8``*$<Y`0(A<`/A7(!``"+1E")!"3HP#<``*$<Y`0(A<!T$8N=J/?_
+M_X7;=`<QP.CP,0``BPTPY`0(A<D/A3L"```/MT<()0#P```]`*````^$-P(`
+M`*'`X@0(A<`/A?H!``"+%<SB!`B+0@B#Z`&%P(E""`^(X0,``(L"Q@`*@\`!
+MB0*+=@B%]@^%_OS__XM=\#,=H.($"`^%E`0``('$?`@``%M>7UW#H43D!`B%
+MP'4*BSWXXP0(A?]T,XN-I/?__XL=$.0$"(M1!,<$)'[;!`B#Z@&-#!HQTHG(
+M]_.)1"0$Z(@2``"+E:3W__^+,H7V#X6+_/__ZY:-="8`BYVD]___BT<4BULH
+MB<(PYH'Z_P```(F=K/?__P^&[@$```^VQ(U=X(E4)!")1"0,QT0D"*;;!`C'
+M1"0$$````(D<).BH$@``BX6L]___B5PD",<$)+O;!`B)1"0$Z(@2``"A!.0$
+M"(7`#X1T_O__BT<8Z&`V``"A'.0$"(7`#X2._O__#[='".@0-0``B86H]___
+MZ8)$``"+0PR+C:3W__^)1"0(BT$8QP0DH-L$"(E$)`3HB!(``.FT0P``C78`
+MBT,(BY6D]___B40D"(M"%,<$)*#;!`B)1"0$Z(@2``#IIT,``(L-$.0$"(U!
+M_XG+B<+!^A\#1S@35SS!^Q^)3"0(B5PD#(D$)(E4)`3HP%8``(E4)`R+E:3W
+M__^)1"0(BT(0QP0D>-L$"(E$)`3HB!(``.DN0@``BT<$BXVD]___B40D"(M!
+M(,<$)'+;!`B)1"0$Z(@2``#I($(``(UV`*',X@0(QP0D"@```(E$)`3HR!``
+M`.GW1```C;8`````#[='".A@.```Z;5$``")]HM6/(72#X4\`0``BT90C97+
+M^___QT0D"/38!`C'1"0$`00``(D4)(E$)`SHJ!(``(V%R_O__XV=RO?__\=$
+M)`@`!```B5PD!(D$).A(%```@_C_#X0U`0``QH0%RO?__P#'!"3-VP0(Z(@2
+M``"-C<KW__^)#"3HP#<``.G)1```C5W@#[;$B50D$(E$)`S'1"0(LML$",=$
+M)`00````B1PDZ*@2``#IN$4``)"-="8`B40D"(N%L/?__XE4)`S'!"1XVP0(
+MB40D!.B($@``Z49$``"+1R#H8#8``)"-="8`Z75$``"+1U#H8#8``(UV`.EU
+M1```BT90B40D$(M&!(M`&,=$)`@6V00(QT0D!`$$``")1"0,C87+^___B00D
+MZ*@2``"+1DR+`#L%*.`$"`^%C/K__Z$DX`0(A<`/A!+[___I`T,``(M&4(V-
+MR_O__XE$)!"+1@2+0!C'1"0(%MD$",=$)`0!!```B0PDB40D#.BH$@``Z3!'
+M``"+%23@!`B%T@^$R_K__^F`0@``Z&@2``"+`(D$).AX$0``C97+^___B50D
+M",=$)`3`VP0(B40D#*'4X@0(B00DZ"@0``#IR40``,9%UBOI3$,``(E4)`3'
+M!"0*````Z$@3``#I]T0``(D<)(V=R_O__^CX$P``B5PD!,<$)/38!`CHN!(`
+M`.E40P``?2V0C;0F`````.AH$@``@S@6=!N-C<O[__^)3"0$QP0D]-@$".BX
+M$@``Z51#``"A).`$"(7`#X7!^?__C9W+^___QT0D!#L```")'"3HJ!$``(/X
+M`'X9QP4@X`0(`@```,<%).`$"`$```#I`T,```^-N?[__^AH$@``@S@6#X2K
+M_O__C87+^___B40D!,<$)/38!`CHN!(``.E40P``Z-@3``"0D)"0D)!5B>6#
+M[!BAU.($",=$)`A*````QT0D!`$```#'!"1DW`0(B40D#.@8$P``QP0D`0``
+M`.A8$P``B?:-O"<`````58GE5U93@>RL````BWT,C95P____BW4(H:#B!`B)
+M1?`QP,=$)`B`````QT0D!`````")%"3H6!(``(7_QX5@____`````'1?C95P
+M____C85L____B50D#(E\)`B)="0$B00DZ%@0``"%P(G#=#F#^_]T;8/[_@^$
+MD0```(N5;/___X'Z_P```'=*H=#B!`B+1)`TJ0``!`!T*8.%8/___P$!WH7_
+M=:&+5?`S%:#B!`B+A6#___]U9H'$K````%M>7UW#BX5@____C028B85@____
+MZ\V)%"3H"!$``.NUB?:-A7#___^#Q@&#A6#___\$@^\!QT0D"(````#'1"0$
+M`````(D$).A8$@``ZY:+E6#___^-%+J)E6#____KB>C8$P``C;8`````C;PG
+M`````%6)Y5=64X'LK````(M%"(L5H.($"(E5\#'2QT0D"(````#'1"0$````
+M`(F%7/___XV%</___XD$).A8$@``QX5@____`````(N57/___XV%</___XE$
+M)`R-A6S____'1"0(!@```(D$)(E4)`3H6!```(7`B<</A`D"``"#__\/A#\!
+M``"#__X/A,$!``"+G6S___^!^_\````/AX0!``"AT.($"(M$F#2I```$``^$
+MSP```#'VA?]_-^MFC70F`(L5S.($"(N%7/___P^V#`:+0@B#Z`&%P(E""`^(
+M@````(L"B`B#P`&)`H/&`3GW="NAP.($"(7`=,:AS.($"(N57/___XE$)`0/
+MM@06@\8!B00DZ,@0```Y]W75BYUL____,<"%VW0H@?O_````#X>=`0``H=#B
+M!`B+1)@TB<*!X@```.`/A'0!``")T,'H'@&]7/___P&%8/___^EH2P``.T(8
+M#[;9?`F`^PH/A6____^)5"0$B1PDZ$@3``#I"DP``(L5P.($"(72#X6D````
+MBQ7,X@0(BT((@^@!A<")0@@/B#8!``"+`L8`/X/``8D"`;U<____@X5@____
+M`>EH2P``BQW`X@0(A=L/A=,```"+%<SB!`B+0@B#Z`&%P(E""`^($P$``(L"
+MQ@`_@\`!B0*-E7#___^#A5S___\!@X5@____`<=$)`B`````QT0D!`````")
+M%"3H6!(``.EH2P``B1PDZ`@1``"-="8`Z<E+``"AS.($",<$)#\```")1"0$
+MZ,@0``#ITDP``(L-P.($"(7)#X6]````BQ7,X@0(BT((@^@!A<")0@@/B,``
+M``"+`L8`/X/``8D"@X5@____`8M5\#,5H.($"(N%8/___P^%N````('$K```
+M`%M>7UW#H<SB!`C'!"0_````B40D!.C($```Z1--```E```$`(/X`1G`@\@!
+MZ7!,``")'"3H"!$``.E=3```.T(8#XW!_O__B50D!,<$)#\```#H2!,``.G2
+M3```.T(8#XWD_O__B50D!,<$)#\```#H2!,``.D330``H<SB!`C'!"0_````
+MB40D!.C($```Z9Y-```[0A@/C3?___^)5"0$QP0D/P```.A($P``Z9Y-``#H
+MV!,``(GVC;PG`````%6)Y5=64X'LK````(M%"(L5H.($"(E5\#'2QT0D"(``
+M``#'1"0$`````(F%7/___XV%</___XD$).A8$@``QX5@____`````(N57/__
+M_XV%</___XE$)`R-A6S____'1"0(!@```(D$)(E4)`3H6!```(7`B<8/A(D!
+M``"#_OX/A&0!``"#_O\/A/0````QVX7V?S/K78L5S.($"(N%7/___P^V#`.+
+M0@B#Z`&%P(E""`^(G0```(L"B`B#P`&)`H/#`3G>="R+/<#B!`B%_W3%H<SB
+M!`B+E5S___^)1"0$#[8$$X/#`8D$).C($```.=YUU(N=;/___P&U7/___X'[
+M_P```'=PH=#B!`B+1)@TJ0``!``/A"W___\QP(7;="B!^_\````/AP8!``"A
+MT.($"(M$F#2)PH'B````X`^$W0```(G0P>@>`85@____Z<A.```[0A@/MOE\
+M"HGX/`H/A5'___^)5"0$B3PDZ$@3``#I0$\``(D<).@($0``D.N.C85P____
+MQT0D"(````#'1"0$`````(D$).A8$@``H<#B!`B%P`^%DP```(L5S.($"(N%
+M7/___P^V"(M""(/H`87`B4((#XB2````BP*("(/``8D"@X5<____`8.%8/__
+M_P'IR$X``(N57/___\<$)/38!`B)5"0$Z(@2```!A6#___^+5?`S%:#B!`B+
+MA6#___]U:X'$K````%M>7UW#)0``!`"#^`$9P(/(`>G)3P``B1PDZ`@1``#I
+MMD\``*',X@0(BY5<____B40D!`^V`HD$).C($```Z590```[0A@/MME\"8#[
+M"@^%7?___XE4)`2)'"3H2!,``.E64```Z-@3``"-=@"-O"<`````58GE5U93
+M@>RL````BT4(BQ6@X@0(B57P,=+'1"0(@````,=$)`0`````B858____C85P
+M____B00DZ%@2``#'A6#___\`````BY58____C85P____B40D#(V%;/___\=$
+M)`@&````B00DB50D!.A8$```A<")A5S___\/A(0#``"+A5S___^#P`*#^`$/
+MAA`!``"+G6S___^!^_\````/A[4#``"AT.($"(M$F#2I```$``^$%P,``(/[
+M(@^$#@,``(/[7`^$!0,``(N]7/___X7_?F\QV^LUBQ7,X@0(BX58____#[8,
+M`XM""(/H`87`B4((#X@]`P``BP*("(/``8D"@\,!.YU<____=#"+-<#B!`B%
+M]G3!H<SB!`B+E5C___^)1"0$#[8$$X/#`8D$).C($```.YU<____=="+G6S_
+M__\QP(7;="B!^_\````/A]L#``"AT.($"(M$F#2)PH'B````X`^$K`,``(G0
+MP>@>`85@____@[U<_____@^$@`(``(.]7/____\/A-4"``"+E5S___\!E5C_
+M___I6%$``(.]7/____\/A74"``"_`0```#'VZ:A3``"0C70F`(L5S.($"(M"
+M"(/H`87`B4((#XB9`0``BP+&`%R#P`&)`J'`X@0(A<`/A>,```"+%<SB!`B)
+MV,#H!@^VP(U(,(M""(/H`87`B4((#XA``0``BP*("(/``8D"H<#B!`B%P`^%
+MV@```(L5S.($"(G8P.@#@^`'C4@PBT((@^@!A<")0@@/B$@!``"+`H@(@\`!
+MB0*AP.($"(7`#X72````BQ7,X@0(B=B#X`>-2#"+0@B#Z`&%P(E""`^(,P$`
+M`(L"B`B#P`&)`H/&`8.%8/___P0Y_@^-W_[__Z'`X@0(BY58____A<`/MAP6
+M#X01____H<SB!`C'!"1<````B40D!.C($```H<#B!`B%P`^$'?___Z',X@0(
+MB40D!(G8P.@&#[;`@\`PB00DZ,@0``"AP.($"(7`#X0L____C;8`````H<SB
+M!`B)1"0$B=C`Z`.#X`>#P#")!"3HR!```*'`X@0(A<`/A#7___^-M"8`````
+MH<SB!`B)1"0$B=B#X`>#P#")!"3HR!```.F64P``B?8[0AA\"8#Y"@^%LO[_
+M_XE4)`2)#"3H2!,``.DI4P``D#M"&`^-7O[__XE4)`3'!"1<````Z$@3``#I
+M\5(``(GV.T(8?`F`^0H/A:K^__^)5"0$B0PDZ$@3``#I85,``)`[0AA\"8#Y
+M"@^%O_[__XE4)`2)#"3H2!,``.F64P``BPWLXP0(A<ET$(7;>`R!^_\````/
+MCJ<```"+O5S___^%_P^/O?W__X.]7/____X/A8#]__^+5?`S%:#B!`B+A6#_
+M__\/A9$!``"!Q*P```!;7E]=PXN%6/___XD$).@8%```B<?KN3M"&`^V\7P*
+MB?`\"@^%L?S__XE4)`2)-"3H2!,``.D24@``B1PDZ`@1``#IO5$``(V%</__
+M_\=$)`B`````QT0D!`````")!"3H6!(``(.%6/___P'I6%$```^^PXE$)`3'
+M!"2OW`0(Z.@1``"%P(G##X0\____BQ7`X@0(A=(/A9D```"+%<SB!`B+0@B#
+MZ`&%P(E""`^(G````(L"Q@!<@\`!B0*AP.($"(7`=5B+#<SB!`@/MD,!BU$(
+M#[[8@^H!A=*)40@/B(D```"+`8@8@\`!B0&#A6#___\"Z8=2```E```$`(/X
+M`1G`@\@!`85@____Z8=2``")'"3H"!$``.EN4@``H<SB!`B)1"0$#[Y#`8D$
+M).C($```Z[BAS.($",<$)%P```")1"0$Z,@0``#I[%4``#M"&`^-6____XE4
+M)`3'!"1<````Z$@3``#I[%4``#M1&'P(/`H/A6K___^)3"0$B1PDZ$@3``#I
+M'%8``.C8$P``D%6)Y5=6@^PPBU4,BT4(BW40BWT4B57<BTW<B478QT70````
+M`(GPQT74`````(GZA<G'1>0`````#XBD````A?\/B+H```")UXG&BU78B<&+
+M1=R%_XE5\(E%['44.<9V08G0BU7L]_:)P3'`ZQ.-=@`[?>QV3S'),<"-M"8`
+M````B4W0BTWDB474BT70BU74A<ET!_?8@](`]]J#Q#!>7UW#A?9U"[@!````
+M,=+W]HG!BT7LB?KW\8G&BT7P]_&)P8GPZ[P/O<>#\!^)1>AU1#E]['<%.77P
+M<IRY`0```#'`ZY[W7=B#5=P`]UW<A?_'1>3_____#XE+____D(UT)@")\(GZ
+M]]B#T@#WVO=5Y.D&5P``N"````")\BM%Z(G!T^H/MDWHB47TB?B)UXM5[-/@
+M"<>+1?#3Y@^V3?33Z`^V3>C3X@^V3?0)T(M5[(E%S-/J]_>)5<R)Q_?F.57,
+MB<9R&SM5S'0)B?DQP.E`5P``BT7P#[9-Z-/@.<9VZHU/_S'`Z4!7``"0D)"0
+MD)"0D)!5B>53@^P$H6#A!`B#^/]T$C';_]"+@USA!`B#ZP2#^/]U\(/$!%M=
+MPY"0D(/L#.@P%0``@\0,PR1&<F5E0E-$.B!S<F,O;&EB+V-S=2]I,S@V+65L
+M9B]C<G1I+E,L=B`Q+C<N,C(N,2`R,#`Y+S`X+S`S(#`X.C$S.C`V(&ME;G-M
+M:71H($5X<"`D`$Q37T-/3%=)1%1(4P!M86QL;V,`)7,Z("5S`"5U`"T`9F9L
+M86=S=&]S='(`34%#(&QA8F5L(&9O<B`E<R\E<P`E;'4`)6IU`&9T<U]O<&5N
+M`"5S.B!D:7)E8W1O<GD@8V%U<V5S(&$@8WEC;&4`.@!F='-?<F5A9`!#3TQ5
+M34Y3`$-,24-/3$]2`$-,24-/3$]27T9/4D-%`%1%4DT`048`04(`;64`;60`
+M;W``3%-#3TQ/4E,````@)6QU(#H@)6QD(#H@)6QU(#H@)74@.B`E=2`Z("5I
+M(#H@)6ID(#H@)6QU(#H@)6QU(```,4%"0T0Z1D=(24Q04E-455=:86)C9&9G
+M:&EK;&UN;W!Q<G-T=7=X`"^E!`@YI00(0Z4$"$VE!`A7I00(8:4$"&NE!`A_
+MI00(B:4$"&>M!`B$J00(A*D$"(2I!`B$J00(A*D$"(2I!`B$J00(A*D$"(2I
+M!`B$J00(A*D$"(2I!`B$J00(A*D$"(2I!`A6K`0(9:P$")>L!`B(K`0(A*D$
+M"$ZM!`@MK00(&ZT$"`RM!`B$J00(A*D$"/>L!`B$J00(A*D$"(2I!`CBK`0(
+MA*D$"-.L!`BZK`0(L*\$"(VO!`B$J00(?J\$"(2I!`B$J00(;Z\$"(2I!`B$
+MJ00(A*D$"(2I!`B$J00(A*D$"%.L!`A,KP0(*:\$"!"O!`B$J00(`:\$"&.I
+M!`CRK@0(XZX$"(2I!`C*K@0(IZX$"(2N!`AUK@0(9JX$"$VN!`@JK@0(&ZX$
+M"`RN!`CSK00(T*T$"(2I!`BMK00(BJT$""5E("5B("54("59`"5B("5E("54
+M("59`"5E("5B("52`"5B("5E("52`"5E("5B("`E60`E8B`E92`@)5D`)2IL
+M=2``)2IJ9"``=&]T86P@)6QU"@`L(``E<R`E*G4@)2TJ<R`@)2TJ<R`@`"4M
+M*G,@`"4S9"P@,'@E,#AX`"4S9"P@)3-D`"4J<R``"FQS.B`E<SH@)7,*`"`M
+M/B``97AF>&-X9'AB>&5G961A8F%G86-A9`````!,4T-/3$]24R!S:&]U;&0@
+M=7-E(&-H87)A8W1E<G,@82UH(&EN<W1E860@;V8@,"TY("AS964@=&AE(&UA
+M;G5A;"!P86=E*0!I;G9A;&ED(&-H87)A8W1E<B`G)6,G(&EN($Q30T],3U)3
+M(&5N=B!V87(``-+;!`AU<V%G93H@;',@6RU!0D-&1TA)3%!24U155UIA8F-D
+M9F=H:6ML;6YO<'%R<W1U=W@Q72!;+40@9F]R;6%T72!;9FEL92`N+BY="@!<
+M7"(B!V$(8@QF"FX-<@ET"W8`)$9R965"4T0Z('-R8R]L:6(O8W-U+VDS.#8M
+M96QF+V-R=&XN4RQV(#$N-BXR,BXQ(#(P,#DO,#@O,#,@,#@Z,3,Z,#8@:V5N
+M<VUI=&@@17AP("0````!&P,[%`,```(```!8M___,`,``*CY__],`P``````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M``````````````````````````````````````````````````#,VP0(````
+M`&SA!`A0````&.`$"``````N````_____P(```#_______________\4````
+M``````%Z4@`!?`@!&PP$!(@!```8````'````""T__\9`````$,.!$*%`@T%
+M````'````#@```!4]O__AP$```!!#@B%`D(-!46&!(<#`````````0````$`
+M```!````70````$```")````#````.2/!`@-````?-@$"`0```!$@00(!0``
+M`$R)!`@&````O(,$"`H```!$`P``"P```!`````5``````````,```!TX00(
+M`@```#`"```4````$0```!<```"TC00($0```'2-!`@2````0````!,````(
+M````_O__;T2-!`C___]O`0```/#__V^0C`0(````````````````````````
+M````````````````````````````````````````_____P````#_____````
+M``````"(X`0(```````````.D`0('I`$""Z0!`@^D`0(3I`$"%Z0!`AND`0(
+M?I`$"(Z0!`B>D`0(KI`$"+Z0!`C.D`0(WI`$".Z0!`C^D`0(#I$$"!Z1!`@N
+MD00(/I$$"$Z1!`A>D00(;I$$"'Z1!`B.D00(GI$$"*Z1!`B^D00(SI$$"-Z1
+M!`CND00(_I$$"`Z2!`@>D@0(+I($"#Z2!`A.D@0(7I($"&Z2!`A^D@0(CI($
+M")Z2!`BND@0(OI($",Z2!`C>D@0([I($"/Z2!`@.DP0('I,$""Z3!`@^DP0(
+M3I,$"%Z3!`ANDP0(?I,$"(Z3!`B>DP0(KI,$"+Z3!`C.DP0(WI,$".Z3!`C^
+MDP0(#I0$"!Z4!`@NE`0(/I0$"$Z4!`A>E`0(````````````)$9R965"4T0Z
+M('-R8R]L:6(O8W-U+VDS.#8M96QF+V-R=#%?<RY3+'8@,2XQ+C(N-"`R,#$Q
+M+S`Q+S$V(#$P.C0Q.C0W(&MI8B!%>'`@)```)$9R965"4T0Z('-R8R]L:6(O
+M8W-U+V-O;6UO;B]C<G1B<F%N9"YC+'8@,2XV+C(N,2`R,#`Y+S`X+S`S(#`X
+M.C$S.C`V(&ME;G-M:71H($5X<"`D`$=#0SH@*$=.52D@-"XR+C(@,C`P-S`X
+M,S$@<')E<F5L96%S92!;1G)E94)31%T``$=#0SH@*$=.52D@-"XR+C(@,C`P
+M-S`X,S$@<')E<F5L96%S92!;1G)E94)31%T``"1&<F5E0E-$.B!S<F,O8FEN
+M+VQS+V-M<"YC+'8@,2XQ."XQ,"XQ(#(P,#DO,#@O,#,@,#@Z,3,Z,#8@:V5N
+M<VUI=&@@17AP("0`1T-#.B`H1TY5*2`T+C(N,B`R,#`W,#@S,2!P<F5R96QE
+M87-E(%M&<F5E0E-$70``)$9R965"4T0Z('-R8R]B:6XO;',O;',N8RQV(#$N
+M.#8N,BXT(#(P,3`O,#(O,C@@,30Z,#0Z,C`@:F@@17AP("0`1T-#.B`H1TY5
+M*2`T+C(N,B`R,#`W,#@S,2!P<F5R96QE87-E(%M&<F5E0E-$70``)$9R965"
+M4T0Z('-R8R]B:6XO;',O<')I;G0N8RQV(#$N-S@N,BXS(#(P,3`O,#(O,C0@
+M,34Z,C<Z,S$@:F@@17AP("0`1T-#.B`H1TY5*2`T+C(N,B`R,#`W,#@S,2!P
+M<F5R96QE87-E(%M&<F5E0E-$70``)$9R965"4T0Z('-R8R]B:6XO;',O=71I
+M;"YC+'8@,2XT,2XR+C$@,C`P.2\P."\P,R`P.#HQ,SHP-B!K96YS;6ET:"!%
+M>'`@)`!'0T,Z("A'3E4I(#0N,BXR(#(P,#<P.#,Q('!R97)E;&5A<V4@6T9R
+M965"4T1=``!'0T,Z("A'3E4I(#0N,BXR(#(P,#<P.#,Q('!R97)E;&5A<V4@
+M6T9R965"4T1=``!'0T,Z("A'3E4I(#0N,BXR(#(P,#<P.#,Q('!R97)E;&5A
+M<V4@6T9R965"4T1=```N<VAS=')T86(`+FEN=&5R<``N;F]T92Y!0DDM=&%G
+M`"YH87-H`"YD>6YS>6T`+F1Y;G-T<@`N9VYU+G9E<G-I;VX`+F=N=2YV97)S
+M:6]N7W(`+G)E;"YD>6X`+G)E;"YP;'0`+FEN:70`+G1E>'0`+F9I;FD`+G)O
+M9&%T80`N96A?9G)A;65?:&1R`"YD871A`"YE:%]F<F%M90`N9'EN86UI8P`N
+M8W1O<G,`+F1T;W)S`"YJ8W(`+F=O=``N8G-S`"YC;VUM96YT````````````
+M```````````````````````````````````````````````+`````0````(`
+M```4@00(%`$``!4```````````````$`````````$P````<````"````+($$
+M""P!```8```````````````$`````````"$````%`````@```$2!!`A$`0``
+M>`(```0`````````!`````0````G````"P````(```"\@P0(O`,``)`%```%
+M`````0````0````0````+P````,````"````3(D$"$P)``!$`P``````````
+M```!`````````#<```#___]O`@```)",!`B0#```L@````0``````````@``
+M``(```!$````_O__;P(```!$C00(1`T``#`````%`````0````0`````````
+M4P````D````"````=(T$"'0-``!`````!``````````$````"````%P````)
+M`````@```+2-!`BT#0``,`(```0````+````!`````@```!E`````0````8`
+M``#DCP0(Y`\``!$```````````````0`````````8`````$````&````^(\$
+M"/@/``!P!``````````````$````!````&L````!````!@```'"4!`AP%```
+M#$0`````````````$`````````!Q`````0````8```!\V`0(?%@```P`````
+M``````````0`````````=P````$````"````B-@$"(A8``".!```````````
+M```$`````````'\````!`````@```!C=!`@870``'```````````````!```
+M``````"-`````0````,`````X`0(`&```#````````````````0`````````
+MDP````$````"````,.`$"#!@``!8```````````````$`````````)T````&
+M`````P```(C@!`B(8```V`````4`````````!`````@```"F`````0````,`
+M``!@X00(8&$```@```````````````0`````````K0````$````#````:.$$
+M"&AA```(```````````````$`````````+0````!`````P```'#A!`AP80``
+M!```````````````!`````````"Y`````0````,```!TX00(=&$``"0!````
+M``````````0````$````O@````@````#````H.($"*!B``"L`0``````````
+M```@`````````,,````!``````````````"@8@``00,``````````````0``
+M```````!`````P``````````````X64``,P```````````````$`````````
+M`00&``$)P,!J``<+`0`"`0`$`P,!`P$`#,#`:L#`:@`("@$]?9*5```%`1$/
+E`'@`.``V`&4`>`!E````%`H!```M0RMQLYT!%08!`"$`````````
+`
+end
diff --git a/libarchive/test/test_read_format_7zip_bcj_deflate.7z.uu b/libarchive/test/test_read_format_7zip_bcj_deflate.7z.uu
new file mode 100644
index 000000000000..8c2ad8e6ea30
--- /dev/null
+++ b/libarchive/test/test_read_format_7zip_bcj_deflate.7z.uu
@@ -0,0 +1,275 @@
+begin 644 test_read_format_7zip_bcj_deflate.7z
+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
+&(0``````
+`
+end
diff --git a/libarchive/test/test_read_format_7zip_bcj_lzma1.7z.uu b/libarchive/test/test_read_format_7zip_bcj_lzma1.7z.uu
new file mode 100644
index 000000000000..fd6b4e067bf4
--- /dev/null
+++ b/libarchive/test/test_read_format_7zip_bcj_lzma1.7z.uu
@@ -0,0 +1,245 @@
+begin 644 test_read_format_7zip_bcj_lzma1.7z
+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
+;`&4````4"@$``"U#*W&SG0$5!@$`(8!M@0``
+`
+end
diff --git a/libarchive/test/test_read_format_7zip_bcj_lzma2.7z.uu b/libarchive/test/test_read_format_7zip_bcj_lzma2.7z.uu
new file mode 100644
index 000000000000..a61aa7033291
--- /dev/null
+++ b/libarchive/test/test_read_format_7zip_bcj_lzma2.7z.uu
@@ -0,0 +1,245 @@
+begin 644 test_read_format_7zip_bcj_lzma2.7z
+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
+<>`!E````%`H!```M0RMQLYT!%08!`"&`;8$`````
+`
+end
diff --git a/libarchive/test/test_read_format_7zip_bzip2.7z.uu b/libarchive/test/test_read_format_7zip_bzip2.7z.uu
new file mode 100644
index 000000000000..07d231ef1e41
--- /dev/null
+++ b/libarchive/test/test_read_format_7zip_bzip2.7z.uu
@@ -0,0 +1,37 @@
+begin 644 test_read_format_7zip_bzip2.7z
+M-WJ\KR<<``.O"&:?B`4```````!&`````````%\J8&Q"6F@Y,4%9)E-9W9C"
+M^0`",E^``!!`]_H]/^__X/__W_!0!>&V6UMJ7NU;KNQ4EW6ZT)32$R9`3*3T
+MFIM-,*>H/)J:/)/4!ZGJ`"43""FC23]2&@-`&@``!ZFT`)3))E,AJF:GM*/4
+M'HFQ(#0`!H`!P``,`````````)$@C4TT94S94TT;4-``````4/DD[A^'IM)O
+M4?;TRQ^=[=^`4PYH41W1A=WR^]==U?7AJZT?W^<KQB@)CD28%A?3\MM_/IWU
+M]NW;X2=_KO0H\I+]X%V7=X5K?\E#JMO<8\,(?'*I.*X^G1O)SGARUM*[1UF]
+MG5^%R@L9]\HQDLO<>$+2+C,Y+0@8D][(7^]64YE]_LI/:HISLZ?Y64ZGYC@P
+MS*=_?2LN-UY*JV%5P0;L##"6UP:G==&QL\DDAK:=U6@2DV*#;7U,M*%L[[XG
+MED];.U`1615GK$ZU;&)0DY.CIX3F4>.3Z=,88NYAOA`BGC+*-U\EMPS.A2K.
+MEGU+H86+IM8H0T:(D98'LKYE*3>>"SC9U<U%8CLSKTG*M],>CCY,<8BN&W=;
+M@J9@5.CB/?6G/Q73=1SS;,-N0XZCUB'NH?O;1=NLIUMX^,BWPF<Q%N:]/A>>
+M)[2>L'[WKK9_:/=]JY3JCFGX'>H7>?:5AV&%5UB1\I^]NJI76^C0HZY!(XT;
+M+Q/HJ22Y6GFO$2JJJH4&@ND.36VTQGP,W[C-QR/;LY#@J&9OG=Z>E9/?PPM%
+MY6C"U%C@82X'(C=;T40TA%@UT65V&A:0,$%,%E$W5Y,:.EQ)5Y!9R%Z$?H.5
+M-V>CCZB?'#'8^93`*&+HSY..MS.;&:PL[0R==&-#V,E-L*0J9W`\E6I57)DH
+M-ECDI8S*"<AWX&>>01&1AIQY5B5-%GHU12>*;9%=022."#&9&+:D\;HNT')3
+M><"$.%[1,";-,`U*&V5L(8\MA:<Y*XJWPDL:\*$6;DL8&N4JALQ:A)%U,\KW
+M1V8X10<+*.J\*;MF%Q)EFV6D#1J1X2)M!1D:21!YTC&)V'9SB.Q<]@@CRRI!
+M+B_/O>Q"3>H'$J'V4O8WH;D=)4QSG(8Z"$JUG93TP'1Y(T_F<RUF(`:-^:<<
+M1!F7@,_:N(49!5C&+^R^-+6QH!GYSTTJ,/X,1JZ*H;<,Y.80DC4DAM,HV*$[
+MM%8=$9IQ'%E"+DHV-5"JSW<FF.Z**G-65!@X43H0FR3;%MI2KB]IV1G[=.)J
+M/%A7*=3%K2L%4OV-0BK@<*]2-.JF7M3SZ6NFO72*"=K\%BC`;(.7%]L@E#-5
+M*-P>5=HH87RNA2B>,\-#E\K`W$M$C-F8P(9.8@EQD(A]&_(&SKWPETM(:8VG
+M.$V)@?(G(S>\1ER":3^\P@4L]2S#_;.%]PBW$?5:%TUZ8&M(%6$F%[CJWB&)
+M>'ZF_-`<KO[_9?UR9FW:!03P+DTHG9%IKC<!`4WKFSMLA-,X37/J^E\]Z<)?
+M&;0&*I,7(.A636)=U6;X-<-*218K*&4R"UM8NEF(<@3CR4DBZ1.9$))),UDX
+MFH(DBYI.:D%"(0$]8M0.Y5*X10B`NUY6M&$/&#);Y+!!V=270*\OO6(#!I.K
+M/,-%2VRE!MW6T1!Q/=+1F4"61=Q8(&ZX;N/8??C$A*$+5#M`35.%"AC*Q#`E
+M0-4WK)07B+2!M0&T3OVQ55L%E''>B.ILR9Z.Z,@[I1F8I.ASC<[L9L<S<]EI
+MHM-C&,+S!HSN*=RU>6CBM\LT@O*$&<"#A/<K<^=7UHYB;(>@0D8X2FI0MI>6
+M3M-W2RD4-Q%U0:-[!&`R&MSG,,:2BKDDD[1<A<P7FE@+&:,W*X%JW0Y0K>U(
+M-B9%;RND4Q&Z_/<&)=.:(5!$FD#4X82S4(D"&3&WV;7\*G*M1-39@QS_\7<D
+M4X4)#=F,+Y`!!`8``0F%B``'"P$``0,$`@(,BQP`"`H!Y1S\W0``!0$1#0!F
+A`&D`;`!E`#$````4"@$`@/>FPNRIS`$5!@$`(("D@0``
+`
+end
diff --git a/libarchive/test/test_read_format_7zip_copy.7z.uu b/libarchive/test/test_read_format_7zip_copy.7z.uu
new file mode 100644
index 000000000000..2429834c26dc
--- /dev/null
+++ b/libarchive/test/test_read_format_7zip_copy.7z.uu
@@ -0,0 +1,7 @@
+begin 644 test_read_format_7zip_none.7z
+M-WJ\KR<<``-!QGV(/`````````!"`````````(/;BV,@("`@("`@("`@("`@
+M("`@("`@("`@("`@(&9I;&4@,2!C;VYT96YT<PIH96QL;PIH96QL;PIH96QL
+M;PH!!`8``0D\``<+`0`!`0`,/``("@&J'=X/```%`1$-`&8`:0!L`&4`,0``
+7`!0*`0"`UD``J+*=`14&`0`@````````
+`
+end
diff --git a/libarchive/test/test_read_format_7zip_copy_2.7z.uu b/libarchive/test/test_read_format_7zip_copy_2.7z.uu
new file mode 100644
index 000000000000..42dda2ddc65b
--- /dev/null
+++ b/libarchive/test/test_read_format_7zip_copy_2.7z.uu
@@ -0,0 +1,11 @@
+begin 644 test_read_format_7zip_copy_2.7z
+M-WJ\KR<<``,UN4V,_``````````B`````````)#)!7AA86%A86%A86%A86$*
+M86%A86%A86%A86%A"F)B8F)B8F)B8F)B8@IA86%A86%A86%A86$*8F)B8F)B
+M8F)B8F)B"F-C8V-C8V-C8V-C8PIA86%A86%A86%A86$*8F)B8F)B8F)B8F)B
+M"F-C8V-C8V-C8V-C8PID9&1D9&1D9&1D9&0*``"!,P>N;;\I7YC.>1<DC8$\
+M>BQN+EC0JP:,/8'I^CO'+,+O1BT_V!J25R+>!(6$RN.N7/`:E<835()Z+\30
+M7HIV[7[>>JA7V-Q4B,BA%R4UM#?HQF-[B9DE>M/_1#ICKKVX_%8F!1KJ*HFC
+M3WIYZ-+^$,6\V``````7!H""`0EZ``<+`0`!(P,!`05=`!````R`R`H!@8KI
+#-P``
+`
+end
diff --git a/libarchive/test/test_read_format_7zip_deflate.7z.uu b/libarchive/test/test_read_format_7zip_deflate.7z.uu
new file mode 100644
index 000000000000..bf4f051cfac7
--- /dev/null
+++ b/libarchive/test/test_read_format_7zip_deflate.7z.uu
@@ -0,0 +1,36 @@
+begin 644 test_read_format_7zip_deflate.7z
+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
+$I($`````
+`
+end
diff --git a/libarchive/test/test_read_format_7zip_delta_lzma1.7z.uu b/libarchive/test/test_read_format_7zip_delta_lzma1.7z.uu
new file mode 100644
index 000000000000..d1e40f6e34e7
--- /dev/null
+++ b/libarchive/test/test_read_format_7zip_delta_lzma1.7z.uu
@@ -0,0 +1,280 @@
+begin 644 test_read_format_7zip_delta_lzma1.7z
+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
+D#0!F`&D`;`!E`#$````4"@$``"U#*W&SG0$5!@$`(("D@0``
+`
+end
diff --git a/libarchive/test/test_read_format_7zip_delta_lzma2.7z.uu b/libarchive/test/test_read_format_7zip_delta_lzma2.7z.uu
new file mode 100644
index 000000000000..c8da4cffe4c0
--- /dev/null
+++ b/libarchive/test/test_read_format_7zip_delta_lzma2.7z.uu
@@ -0,0 +1,280 @@
+begin 644 test_read_format_7zip_delta_lzma2.7z
+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
+E$0T`9@!I`&P`90`Q````%`H!```M0RMQLYT!%08!`""`I($`````
+`
+end
diff --git a/libarchive/test/test_read_format_7zip_empty_archive.7z.uu b/libarchive/test/test_read_format_7zip_empty_archive.7z.uu
new file mode 100644
index 000000000000..88831ca5a1f9
--- /dev/null
+++ b/libarchive/test/test_read_format_7zip_empty_archive.7z.uu
@@ -0,0 +1,4 @@
+begin 644 test_read_format_7zip_empty_archive.7z
+@-WJ\KR<<``.-F]4/````````````````````````````
+`
+end
diff --git a/libarchive/test/test_read_format_7zip_empty_file.7z.uu b/libarchive/test/test_read_format_7zip_empty_file.7z.uu
new file mode 100644
index 000000000000..ab9cf653cfdf
--- /dev/null
+++ b/libarchive/test/test_read_format_7zip_empty_file.7z.uu
@@ -0,0 +1,5 @@
+begin 644 test_read_format_7zip_empty_file.7z
+M-WJ\KR<<``,%;\HA```````````N`````````,Z^!W,!!0$.`8`/`8`1#0!E
+A`&T`<`!T`'D````4"@$`@-9``*BRG0$5!@$`(("D@0``
+`
+end
diff --git a/libarchive/test/test_read_format_7zip_lzma1.7z.uu b/libarchive/test/test_read_format_7zip_lzma1.7z.uu
new file mode 100644
index 000000000000..1ffb08f7112e
--- /dev/null
+++ b/libarchive/test/test_read_format_7zip_lzma1.7z.uu
@@ -0,0 +1,37 @@
+begin 644 test_read_format_7zip_lzma1.7z
+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
+&(("D@0``
+`
+end
diff --git a/libarchive/test/test_read_format_7zip_lzma1_2.7z.uu b/libarchive/test/test_read_format_7zip_lzma1_2.7z.uu
new file mode 100644
index 000000000000..70b03bd3b88b
--- /dev/null
+++ b/libarchive/test/test_read_format_7zip_lzma1_2.7z.uu
@@ -0,0 +1,8 @@
+begin 644 test_read_format_7zip_lzma1_2.7z
+M-WJ\KR<<``-GH*;IF@`````````B`````````--W(LL`,.P]5,<,713`O:V<
+M)`.JE)L$6^G@````@3,'K@_/;NZ,!\A#@(.!6_^L@!U0&A2&3>R/[PWL=[H6
+MI6B>-7,"LEFSPJXL&_5`VI+39=)!5A<B\LC\HNBIA&&!?>VU_MRZJ-'/$T<4
+M$.`BV?:<->IQ$-K,-DX=!*T>*)Q&M+J="/NB=:8'E1X3/?KZT!XEN'99V!2D
+HL??E````%P87`0F`@P`'"P$``2,#`0$%70`0```,@,@*`<_EW0D`````
+`
+end
diff --git a/libarchive/test/test_read_format_7zip_lzma1_lzma2.7z.uu b/libarchive/test/test_read_format_7zip_lzma1_lzma2.7z.uu
new file mode 100644
index 000000000000..4de527e4b726
--- /dev/null
+++ b/libarchive/test/test_read_format_7zip_lzma1_lzma2.7z.uu
@@ -0,0 +1,10 @@
+begin 644 test_read_format_7zip_lzma1_lzma2.7z
+M-WJ\KR<<``.;^9[-V0`````````B``````````(\.`H`,.P]5,<,713`O:V<
+M)`.JE)L$6^G@`.``@0`670`P[#U4QPQ=%,"]K9PD`ZJ4FP1;Z>``````@3,'
+MKC&9Q;Z1",.ZTR=H7?D</%DDB!LX-2ML$Z:8JM^%!8@O`.5,A[\=PZ*`*GB1
+MZ`J5+PF#Q6VZYNX_+&CIC]X'IVM\#IRF6A@O"L4)>(*P-]#*^T-I.U$V\S<>
+MW,KQ]&30$$K2G.A@ZB\TJ2%=E9LVPJES']:2`CL-F<22BZ>*M00K1&/TM<R`
+MS(NWRIW:=%C$SOHE:-:A'S_GP0X`````%P8U`0F`I``'"P$``2,#`0$%70`0
+-```,@5@*`6![G$@`````
+`
+end
diff --git a/libarchive/test/test_read_format_7zip_lzma2.7z.uu b/libarchive/test/test_read_format_7zip_lzma2.7z.uu
new file mode 100644
index 000000000000..ee740fb76f29
--- /dev/null
+++ b/libarchive/test/test_read_format_7zip_lzma2.7z.uu
@@ -0,0 +1,37 @@
+begin 644 test_read_format_7zip_lzma2.7z
+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
+'`""`I($`````
+`
+end
diff --git a/libarchive/test/test_read_format_7zip_ppmd.7z.uu b/libarchive/test/test_read_format_7zip_ppmd.7z.uu
new file mode 100644
index 000000000000..8934e1a33310
--- /dev/null
+++ b/libarchive/test/test_read_format_7zip_ppmd.7z.uu
@@ -0,0 +1,235 @@
+begin 644 test_read_format_7zip_ppmd.7z
+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
+*%08!`"``````````
+`
+end
diff --git a/libarchive/test/test_read_format_7zip_symbolic_name.7z.uu b/libarchive/test/test_read_format_7zip_symbolic_name.7z.uu
new file mode 100644
index 000000000000..2dd8ca1912e1
--- /dev/null
+++ b/libarchive/test/test_read_format_7zip_symbolic_name.7z.uu
@@ -0,0 +1,8 @@
+begin 644 test_read_format_7zip_symbolic_name.7z
+M-WJ\KR<<``/+SQ7U?``````````@`````````%VOQ/0`-!E)[HZ&\R=<V09=
+M3\GO.C@```"!,P>N#\\G\(P'R$.`@X%;_ZR`'5`:`Y&`K7JS*U;!.)J3]3@J
+M?#'*:Z""L7Y*%Z9?L#^PQL3)[(BVML.S<U*&H#A9I>!-[#M+-]`<OQ06*=Y9
+MKX#Z'<1@I<CF#)T]5&`H[O*-#```%P83`0EI``<+`0`!(P,!`05=`!````QV
+("@'AP.\:````
+`
+end
diff --git a/libarchive/test/test_read_format_ar.c b/libarchive/test/test_read_format_ar.c
index efea38d2c532..a7ec62d4928f 100644
--- a/libarchive/test/test_read_format_ar.c
+++ b/libarchive/test/test_read_format_ar.c
@@ -38,7 +38,7 @@ DEFINE_TEST(test_read_format_ar)
extract_reference_file(reffile);
assert((a = archive_read_new()) != NULL);
- assertA(0 == archive_read_support_compression_all(a));
+ assertA(0 == archive_read_support_filter_all(a));
assertA(0 == archive_read_support_format_all(a));
assertA(0 == archive_read_open_file(a, reffile, 7));
@@ -58,7 +58,7 @@ DEFINE_TEST(test_read_format_ar)
assertEqualInt(0, archive_entry_gid(ae));
assert(8 == archive_entry_size(ae));
assertA(8 == archive_read_data(a, buff, 10));
- assert(0 == memcmp(buff, "55667788", 8));
+ assertEqualMem(buff, "55667788", 8);
/* Second Entry */
assertA(0 == archive_read_next_header(a, &ae));
@@ -68,7 +68,7 @@ DEFINE_TEST(test_read_format_ar)
assertEqualInt(0, archive_entry_gid(ae));
assert(4 == archive_entry_size(ae));
assertA(4 == archive_read_data(a, buff, 10));
- assert(0 == memcmp(buff, "3333", 4));
+ assertEqualMem(buff, "3333", 4);
/* Third Entry */
assertA(0 == archive_read_next_header(a, &ae));
@@ -78,10 +78,11 @@ DEFINE_TEST(test_read_format_ar)
assertEqualInt(0, archive_entry_gid(ae));
assert(9 == archive_entry_size(ae));
assertA(9 == archive_read_data(a, buff, 9));
- assert(0 == memcmp(buff, "987654321", 9));
+ assertEqualMem(buff, "987654321", 9);
/* Test EOF */
assertA(1 == archive_read_next_header(a, &ae));
- assert(0 == archive_read_close(a));
- assert(0 == archive_read_finish(a));
+ assertEqualInt(4, archive_file_count(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_read_format_cab.c b/libarchive/test/test_read_format_cab.c
new file mode 100644
index 000000000000..4e8607ec8f70
--- /dev/null
+++ b/libarchive/test/test_read_format_cab.c
@@ -0,0 +1,281 @@
+/*-
+ * Copyright (c) 2010 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD");
+
+#ifdef HAVE_LIBZ
+static const int libz_enabled = 1;
+#else
+static const int libz_enabled = 0;
+#endif
+
+/*
+Execute the following command to rebuild the data for this program:
+ tail -n +44 test_read_format_cab.c | /bin/sh
+And following works are:
+1. Move /tmp/cab/cab.zip to Windows PC
+2. Extract cab.zip
+3. Open command prompt and change current directory where you extracted cab.zip
+4. Execute cab.bat
+5. Then you will see that there is a cabinet file, test.cab
+6. Move test.cab to posix platform
+7. Extract test.cab with this version of bsdtar
+8. Execute the following command to make uuencoded files.
+ uuencode test_read_format_cab_1.cab test_read_format_cab_1.cab > test_read_format_cab_1.cab.uu
+ uuencode test_read_format_cab_2.cab test_read_format_cab_2.cab > test_read_format_cab_2.cab.uu
+ uuencode test_read_format_cab_3.cab test_read_format_cab_3.cab > test_read_format_cab_3.cab.uu
+
+#!/bin/sh
+#
+# How to make test data.
+#
+# Temporary directory.
+base=/tmp/cab
+# Owner id
+owner=1001
+# Group id
+group=1001
+#
+# Make contents of a cabinet file.
+#
+rm -rf ${base}
+mkdir ${base}
+mkdir ${base}/dir1
+mkdir ${base}/dir2
+#
+touch ${base}/empty
+cat > ${base}/dir1/file1 << END
+ file 1 contents
+hello
+hello
+hello
+END
+#
+cat > ${base}/dir2/file2 << END
+ file 2 contents
+hello
+hello
+hello
+hello
+hello
+hello
+END
+#
+dd if=/dev/zero of=${base}/zero bs=1 count=33000 > /dev/null 2>&1
+#
+cab1=test_read_format_cab_1.cab
+cab2=test_read_format_cab_2.cab
+cab3=test_read_format_cab_3.cab
+#
+#
+cat > ${base}/mkcab1 << END
+.Set Compress=OFF
+.Set DiskDirectory1=.
+.Set InfDate=1980-01-02
+.Set InfTime=00:00:00
+.Set CabinetName1=${cab1}
+empty
+.Set DestinationDir=dir1
+dir1/file1
+.Set DestinationDir=dir2
+dir2/file2
+END
+#
+cat > ${base}/mkcab2 << END
+.Set CompressionType=MSZIP
+.Set DiskDirectory1=.
+.Set InfDate=1980-01-02
+.Set InfTime=00:00:00
+.Set CabinetName1=${cab2}
+empty
+zero
+.Set DestinationDir=dir1
+dir1/file1
+.Set DestinationDir=dir2
+dir2/file2
+END
+#
+cat > ${base}/mkcab3 << END
+.Set CompressionType=LZX
+.Set DiskDirectory1=.
+.Set InfDate=1980-01-02
+.Set InfTime=00:00:00
+.Set CabinetName1=${cab3}
+empty
+zero
+.Set DestinationDir=dir1
+dir1/file1
+.Set DestinationDir=dir2
+dir2/file2
+END
+#
+cat > ${base}/mkcab4 << END
+.Set CompressionType=MSZIP
+.Set DiskDirectory1=.
+.Set CabinetName1=test.cab
+${cab1}
+${cab2}
+${cab3}
+END
+#
+cat > ${base}/cab.bat << END
+makecab.exe /F mkcab1
+makecab.exe /F mkcab2
+makecab.exe /F mkcab3
+makecab.exe /F mkcab4
+del setup.inf setup.rpt
+del empty zero dir1\file1 dir2\file2 mkcab1 mkcab2 mkcab3 mkcab4
+del ${cab1} ${cab2} ${cab3}
+rmdir dir1 dir2
+END
+#
+f=cab.zip
+(cd ${base}; zip -q -c $f empty zero dir1/file1 dir2/file2 mkcab1 mkcab2 mkcab3 mkcab4 cab.bat)
+#
+exit 1
+*/
+
+static const char file1[] = {
+" file 1 contents\n"
+"hello\n"
+"hello\n"
+"hello\n"
+};
+#define file1_size (sizeof(file1)-1)
+static const char file2[] = {
+" file 2 contents\n"
+"hello\n"
+"hello\n"
+"hello\n"
+"hello\n"
+"hello\n"
+"hello\n"
+};
+#define file2_size (sizeof(file2)-1)
+
+enum comp_type {
+ STORE = 0,
+ MSZIP,
+ LZX
+};
+static void
+verify(const char *refname, enum comp_type comp)
+{
+ struct archive_entry *ae;
+ struct archive *a;
+ char buff[128];
+ char zero[128];
+ size_t s;
+
+ memset(zero, 0, sizeof(zero));
+ extract_reference_file(refname);
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular empty. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0777), archive_entry_mode(ae));
+ assertEqualString("empty", archive_entry_pathname(ae));
+ assertEqualInt(0, archive_entry_uid(ae));
+ assertEqualInt(0, archive_entry_gid(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+
+ if (comp != STORE) {
+ /* Verify regular zero.
+ * Maximum CFDATA size is 32768, so we need over 32768 bytes
+ * file to check if we properly handle multiple CFDATA.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0777), archive_entry_mode(ae));
+ assertEqualString("zero", archive_entry_pathname(ae));
+ assertEqualInt(0, archive_entry_uid(ae));
+ assertEqualInt(0, archive_entry_gid(ae));
+ assertEqualInt(33000, archive_entry_size(ae));
+ for (s = 0; s + sizeof(buff) < 33000; s+= sizeof(buff)) {
+ ssize_t rsize = archive_read_data(a, buff, sizeof(buff));
+ if (comp == MSZIP && rsize == ARCHIVE_FATAL && !libz_enabled) {
+ skipping("Skipping CAB format(MSZIP) check: %s",
+ archive_error_string(a));
+ goto finish;
+ }
+ assertEqualInt(sizeof(buff), rsize);
+ assertEqualMem(buff, zero, sizeof(buff));
+ }
+ assertEqualInt(33000 - s, archive_read_data(a, buff, 33000 - s));
+ assertEqualMem(buff, zero, 33000 - s);
+ }
+
+ /* Verify regular file1. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0777), archive_entry_mode(ae));
+ assertEqualString("dir1/file1", archive_entry_pathname(ae));
+ assertEqualInt(0, archive_entry_uid(ae));
+ assertEqualInt(0, archive_entry_gid(ae));
+ assertEqualInt(file1_size, archive_entry_size(ae));
+ assertEqualInt(file1_size, archive_read_data(a, buff, file1_size));
+ assertEqualMem(buff, file1, file1_size);
+
+ /* Verify regular file2. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0777), archive_entry_mode(ae));
+ assertEqualString("dir2/file2", archive_entry_pathname(ae));
+ assertEqualInt(0, archive_entry_uid(ae));
+ assertEqualInt(0, archive_entry_gid(ae));
+ assertEqualInt(file2_size, archive_entry_size(ae));
+ assertEqualInt(file2_size, archive_read_data(a, buff, file2_size));
+ assertEqualMem(buff, file2, file2_size);
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ if (comp != STORE) {
+ assertEqualInt(4, archive_file_count(a));
+ } else {
+ assertEqualInt(3, archive_file_count(a));
+ }
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_CAB, archive_format(a));
+
+ /* Close the archive. */
+finish:
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+DEFINE_TEST(test_read_format_cab)
+{
+ /* Verify Cabinet file in no compression. */
+ verify("test_read_format_cab_1.cab", STORE);
+ /* Verify Cabinet file in MSZIP. */
+ verify("test_read_format_cab_2.cab", MSZIP);
+ /* Verify Cabinet file in LZX. */
+ verify("test_read_format_cab_3.cab", LZX);
+}
+
diff --git a/libarchive/test/test_read_format_cab_1.cab.uu b/libarchive/test/test_read_format_cab_1.cab.uu
new file mode 100644
index 000000000000..bc6ab41ee745
--- /dev/null
+++ b/libarchive/test/test_read_format_cab_1.cab.uu
@@ -0,0 +1,9 @@
+begin 644 test_read_format_cab_1.cab
+M35-#1@`````*`0```````"P``````````P$!``,```!K"0``>`````$`````
+M````````````D3U&I2``96UP='D`/````````````)$]1J4@`&1I<C%<9FEL
+M93$`3@```#P``````)$]1J4@`&1I<C)<9FEL93(`@PF-;(H`B@`@("`@("`@
+M("`@("`@("`@("`@("`@("`@(&9I;&4@,2!C;VYT96YT<PIH96QL;PIH96QL
+M;PIH96QL;PH@("`@("`@("`@("`@("`@("`@("`@("`@(&9I;&4@,B!C;VYT
+I96YT<PIH96QL;PIH96QL;PIH96QL;PIH96QL;PIH96QL;PIH96QL;PH`
+`
+end
diff --git a/libarchive/test/test_read_format_cab_2.cab.uu b/libarchive/test/test_read_format_cab_2.cab.uu
new file mode 100644
index 000000000000..00a6eb55e18c
--- /dev/null
+++ b/libarchive/test/test_read_format_cab_2.cab.uu
@@ -0,0 +1,9 @@
+begin 644 test_read_format_cab_2.cab
+M35-#1@````#U`````````"P``````````P$!``0````K"P``C0````(``0``
+M````````````D3U&I2``96UP='D`Z(```````````)$]1J4@`'IE<F\`/```
+M`.B``````)$]1J4@`&1I<C%<9FEL93$`3@```"2!`````)$]1J4@`&1I<C)<
+M9FEL93(`W21UIS```(!#2^W!`0$```"`D/ZO[@@"````````````````````
+M`````````````````````!H[L#%?*`!R`4-+&RDAH(`3I&7FI"H8*B3GYY6D
+4YI44<V6DYN3DHY`$]!KATXM)`@``
+`
+end
diff --git a/libarchive/test/test_read_format_cab_3.cab.uu b/libarchive/test/test_read_format_cab_3.cab.uu
new file mode 100644
index 000000000000..9eff3384ec8c
--- /dev/null
+++ b/libarchive/test/test_read_format_cab_3.cab.uu
@@ -0,0 +1,10 @@
+begin 755 test_read_format_cab_3.cab
+M35-#1@`````A`0```````"P``````````P$!``0````K"P``C0````(``Q(`
+M````````````(@```"``96UP='D`Z(```````````"(````@`'IE<F\`/```
+M`.B``````"(````@`&1I<C%<9FEL93$`3@```"2!`````"(````@`&1I<C)<
+M9FEL93(`CH]5G'```(!;@("-""`B%P```($`````0#-#`.@+#IA)^XZV#HDL
+M6M_?$-````````$9`'*0(3<P]I!&O]^0?@`@`````&`&8(@]$<$7]7=_TYA\
+ML&X````````````````````````````````````````.``"PPU!^C10`<@$G
+3?%0=L<8OOOO<G,Y6S<,^[/LHWP``
+`
+end
diff --git a/libarchive/test/test_read_format_cab_filename.c b/libarchive/test/test_read_format_cab_filename.c
new file mode 100644
index 000000000000..54374deb9b37
--- /dev/null
+++ b/libarchive/test/test_read_format_cab_filename.c
@@ -0,0 +1,164 @@
+/*-
+ * Copyright (c) 2011 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD");
+
+#include <locale.h>
+
+static void
+test_read_format_cab_filename_CP932_eucJP(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read CAB filename in ja_JP.eucJP with "hdrcharset=CP932" option.
+ */
+ if (NULL == setlocale(LC_ALL, "ja_JP.eucJP")) {
+ skipping("ja_JP.eucJP locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP932")) {
+ skipping("This system cannot convert character-set"
+ " from CP932 to eucJP.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(
+ "\xc9\xbd\xa4\xc0\xa4\xe8\x2f\xb4\xc1\xbb\xfa\x2e\x74\x78\x74",
+ archive_entry_pathname(ae));
+ assertEqualInt(5, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(
+ "\xc9\xbd\xa4\xc0\xa4\xe8\x2f\xb0\xec\xcd\xf7\xc9\xbd\x2e\x74\x78\x74",
+ archive_entry_pathname(ae));
+ assertEqualInt(5, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_CAB, archive_format(a));
+
+ /* Close the archive. */
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_cab_filename_CP932_UTF8(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read CAB filename in en_US.UTF-8 with "hdrcharset=CP932" option.
+ */
+ if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
+ skipping("en_US.UTF-8 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP932")) {
+ skipping("This system cannot convert character-set"
+ " from CP932 to UTF-8.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+#if defined(__APPLE__)
+ /* Compare NFD string. */
+ assertEqualUTF8String(
+ "\xe8\xa1\xa8\xe3\x81\x9f\xe3\x82\x99\xe3\x82\x88\x2f"
+ "\xe6\xbc\xa2\xe5\xad\x97\x2e\x74\x78\x74",
+ archive_entry_pathname(ae));
+ assertEqualInt(5, archive_entry_size(ae));
+#else
+ /* Compare NFC string. */
+ assertEqualUTF8String(
+ "\xe8\xa1\xa8\xe3\x81\xa0\xe3\x82\x88\x2f"
+ "\xe6\xbc\xa2\xe5\xad\x97\x2e\x74\x78\x74",
+ archive_entry_pathname(ae));
+ assertEqualInt(5, archive_entry_size(ae));
+#endif
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+#if defined(__APPLE__)
+ /* Compare NFD string. */
+ assertEqualUTF8String(
+ "\xe8\xa1\xa8\xe3\x81\x9f\xe3\x82\x99\xe3\x82\x88\x2f"
+ "\xe4\xb8\x80\xe8\xa6\xa7\xe8\xa1\xa8\x2e\x74\x78\x74",
+ archive_entry_pathname(ae));
+#else
+ /* Compare NFC string. */
+ assertEqualUTF8String(
+ "\xe8\xa1\xa8\xe3\x81\xa0\xe3\x82\x88\x2f"
+ "\xe4\xb8\x80\xe8\xa6\xa7\xe8\xa1\xa8\x2e\x74\x78\x74",
+ archive_entry_pathname(ae));
+#endif
+ assertEqualInt(5, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_CAB, archive_format(a));
+
+ /* Close the archive. */
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+DEFINE_TEST(test_read_format_cab_filename)
+{
+ const char *refname = "test_read_format_cab_filename_cp932.cab";
+
+ extract_reference_file(refname);
+ test_read_format_cab_filename_CP932_eucJP(refname);
+ test_read_format_cab_filename_CP932_UTF8(refname);
+}
diff --git a/libarchive/test/test_read_format_cab_filename_cp932.cab.uu b/libarchive/test/test_read_format_cab_filename_cp932.cab.uu
new file mode 100644
index 000000000000..0d51f10c418a
--- /dev/null
+++ b/libarchive/test/test_read_format_cab_filename_cp932.cab.uu
@@ -0,0 +1,7 @@
+begin 644 test_read_format_cab_cp932.cab
+M35-#1@````"4`````````"P``````````P$!``(````(_@``;@````$``Q(%
+M````````````=#ZO5"``E5R"OH+F7(J_CIHN='AT``4````%``````!T/KM4
+M(`"57(*^@N9<B.J7EY5<+G1X=``I]2&+'@`*`%N`@(T`,*```0````$````!
+-````:V%N:FE(96QL;P``
+`
+end
diff --git a/libarchive/test/test_read_format_cpio_afio.c b/libarchive/test/test_read_format_cpio_afio.c
new file mode 100644
index 000000000000..7aec833c2302
--- /dev/null
+++ b/libarchive/test/test_read_format_cpio_afio.c
@@ -0,0 +1,115 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2010 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+/*
+ecute the following to rebuild the data for this program:
+ tail -n +33 test_read_format_cpio_afio.c | /bin/sh
+
+# How to make a sample data.
+echo "0123456789abcdef" > file1
+echo "0123456789abcdef" > file2
+# make afio use a large ASCII header
+sudo chown 65536 file2
+find . -name "file[12]" | afio -o sample
+od -c sample | sed -E -e "s/^0[0-9]+//;s/^ //;s/( +)([^ ]{1,2})/'\2',/g;s/'\\0'/0/g;/^[*]/d" > test_read_format_cpio_afio.sample.txt
+rm -f file1 file2 sample
+exit1
+*/
+
+static unsigned char archive[] = {
+'0','7','0','7','0','7','0','0','0','1','4','3','1','2','5','3',
+'2','1','1','0','0','6','4','4','0','0','1','7','5','1','0','0',
+'1','7','5','1','0','0','0','0','0','1','0','0','0','0','0','0',
+'1','1','3','3','2','2','4','5','0','2','0','0','0','0','0','0',
+'6','0','0','0','0','0','0','0','0','0','2','1','f','i','l','e',
+'1',0,'0','1','2','3','4','5','6','7','8','9','a','b','c','d',
+'e','f','\n','0','7','0','7','2','7','0','0','0','0','0','0','6',
+'3','0','0','0','0','0','0','0','0','0','0','0','D','A','A','E',
+'6','m','1','0','0','6','4','4','0','0','0','1','0','0','0','0',
+'0','0','0','0','0','3','E','9','0','0','0','0','0','0','0','1',
+'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0',
+'4','B','6','9','4','A','1','0','n','0','0','0','6','0','0','0',
+'0','0','0','0','0','s','0','0','0','0','0','0','0','0','0','0',
+'0','0','0','0','1','1',':','f','i','l','e','2',0,'0','1','2',
+'3','4','5','6','7','8','9','a','b','c','d','e','f','\n','0','7',
+'0','7','0','7','0','0','0','0','0','0','0','0','0','0','0','0',
+'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0',
+'0','0','0','0','0','0','0','1','0','0','0','0','0','0','0','0',
+'0','0','0','0','0','0','0','0','0','0','0','0','0','1','3','0',
+'0','0','0','0','0','1','1','2','7','3','T','R','A','I','L','E',
+'R','!','!','!',0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+};
+
+/*
+ * XXX This must be removed when we use int64_t for uid.
+ */
+static int
+uid_size(void)
+{
+ return (sizeof(uid_t));
+}
+
+DEFINE_TEST(test_read_format_cpio_afio)
+{
+ unsigned char *p;
+ size_t size;
+ struct archive_entry *ae;
+ struct archive *a;
+
+ /* The default block size of afio is 5120. we simulate it */
+ size = (sizeof(archive) + 5120 -1 / 5120) * 5120;
+ if (!assert((p = malloc(size)) != NULL))
+ return;
+ memset(p, 0, size);
+ memcpy(p, archive, sizeof(archive));
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, p, size));
+ /*
+ * First entry is odc format.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(17, archive_entry_size(ae));
+ assertA(archive_compression(a) == ARCHIVE_COMPRESSION_NONE);
+ assertA(archive_format(a) == ARCHIVE_FORMAT_CPIO_POSIX);
+ /*
+ * Second entry is afio large ASCII format.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(17, archive_entry_size(ae));
+ if (uid_size() > 4)
+ assertEqualInt(65536, archive_entry_uid(ae));
+ assertA(archive_compression(a) == ARCHIVE_COMPRESSION_NONE);
+ assertA(archive_format(a) == ARCHIVE_FORMAT_CPIO_AFIO_LARGE);
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+ free(p);
+}
diff --git a/libarchive/test/test_read_format_cpio_bin.c b/libarchive/test/test_read_format_cpio_bin.c
index fecc0ab4834f..42ec4214f91f 100644
--- a/libarchive/test/test_read_format_cpio_bin.c
+++ b/libarchive/test/test_read_format_cpio_bin.c
@@ -47,18 +47,15 @@ DEFINE_TEST(test_read_format_cpio_bin)
struct archive_entry *ae;
struct archive *a;
assert((a = archive_read_new()) != NULL);
- assertA(0 == archive_read_support_compression_all(a));
- assertA(0 == archive_read_support_format_all(a));
- assertA(0 == archive_read_open_memory(a, archive, sizeof(archive)));
- assertA(0 == archive_read_next_header(a, &ae));
- assertA(archive_compression(a) == ARCHIVE_COMPRESSION_NONE);
- assertA(archive_format(a) == ARCHIVE_FORMAT_CPIO_BIN_LE);
- assert(0 == archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assert(0 == archive_read_finish(a));
-#endif
+ assertEqualIntA(a, 0, archive_read_support_filter_all(a));
+ assertEqualIntA(a, 0, archive_read_support_format_all(a));
+ assertEqualIntA(a, 0, archive_read_open_memory(a, archive, sizeof(archive)));
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(1, archive_file_count(a));
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_CPIO_BIN_LE, archive_format(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_read_format_cpio_bin_Z.c b/libarchive/test/test_read_format_cpio_bin_Z.c
index bae370b17176..e818a01ac1a2 100644
--- a/libarchive/test/test_read_format_cpio_bin_Z.c
+++ b/libarchive/test/test_read_format_cpio_bin_Z.c
@@ -37,12 +37,13 @@ DEFINE_TEST(test_read_format_cpio_bin_Z)
struct archive *a;
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK,
- archive_read_support_compression_all(a));
+ archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_open_memory(a, archive, sizeof(archive)));
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(1, archive_file_count(a));
failure("archive_compression_name(a)=\"%s\"",
archive_compression_name(a));
assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_COMPRESS);
@@ -51,11 +52,7 @@ DEFINE_TEST(test_read_format_cpio_bin_Z)
archive_format_name(a));
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_CPIO_BIN_LE);
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
-#endif
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_read_format_cpio_bin_be.c b/libarchive/test/test_read_format_cpio_bin_be.c
index 8cd59dc5d01e..534471a1ca8a 100644
--- a/libarchive/test/test_read_format_cpio_bin_be.c
+++ b/libarchive/test/test_read_format_cpio_bin_be.c
@@ -33,7 +33,7 @@ DEFINE_TEST(test_read_format_cpio_bin_be)
extract_reference_file(reference);
assert((a = archive_read_new()) != NULL);
- assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_open_filename(a, reference, 10));
@@ -49,7 +49,7 @@ DEFINE_TEST(test_read_format_cpio_bin_be)
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_CPIO_BIN_BE);
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_read_format_cpio_bin_bz2.c b/libarchive/test/test_read_format_cpio_bin_bz2.c
index 598c6256ad14..c19efed88db2 100644
--- a/libarchive/test/test_read_format_cpio_bin_bz2.c
+++ b/libarchive/test/test_read_format_cpio_bin_bz2.c
@@ -39,7 +39,7 @@ DEFINE_TEST(test_read_format_cpio_bin_bz2)
int r;
assert((a = archive_read_new()) != NULL);
- r = archive_read_support_compression_bzip2(a);
+ r = archive_read_support_filter_bzip2(a);
if (r != ARCHIVE_OK) {
skipping("bzip2 support unavailable");
archive_read_close(a);
@@ -51,8 +51,8 @@ DEFINE_TEST(test_read_format_cpio_bin_bz2)
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assert(archive_compression(a) == ARCHIVE_COMPRESSION_BZIP2);
assert(archive_format(a) == ARCHIVE_FORMAT_CPIO_BIN_LE);
- assert(0 == archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_read_format_cpio_bin_gz.c b/libarchive/test/test_read_format_cpio_bin_gz.c
index 4457fb3c6fff..a807b5b190ae 100644
--- a/libarchive/test/test_read_format_cpio_bin_gz.c
+++ b/libarchive/test/test_read_format_cpio_bin_gz.c
@@ -38,14 +38,14 @@ DEFINE_TEST(test_read_format_cpio_bin_gz)
int r;
assert((a = archive_read_new()) != NULL);
- assertEqualInt(ARCHIVE_OK, archive_read_support_compression_all(a));
- r = archive_read_support_compression_gzip(a);
+ assertEqualInt(ARCHIVE_OK, archive_read_support_filter_all(a));
+ r = archive_read_support_filter_gzip(a);
if (r == ARCHIVE_WARN) {
skipping("gzip reading not fully supported on this platform");
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
return;
}
- failure("archive_read_support_compression_gzip");
+ failure("archive_read_support_filter_gzip");
assertEqualInt(ARCHIVE_OK, r);
assertEqualInt(ARCHIVE_OK, archive_read_support_format_all(a));
assertEqualInt(ARCHIVE_OK,
@@ -55,7 +55,7 @@ DEFINE_TEST(test_read_format_cpio_bin_gz)
ARCHIVE_COMPRESSION_GZIP);
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_CPIO_BIN_LE);
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_read_format_cpio_bin_lzip.c b/libarchive/test/test_read_format_cpio_bin_lzip.c
new file mode 100644
index 000000000000..16effb91652b
--- /dev/null
+++ b/libarchive/test/test_read_format_cpio_bin_lzip.c
@@ -0,0 +1,61 @@
+/*-
+ * Copyright (c) 2010 Michihiro NAKAJIMA
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+static unsigned char archive[] = {
+ 76, 90, 73, 80, 1, 12, 0, 99,156, 62,160, 67,124,230, 93,220,
+235,118, 29, 75, 27,226,158, 67,149,151, 96, 22, 54,198,209, 63,
+104,209,148,249,238, 71,187,201,243,162, 1, 42, 47, 43,178, 35,
+ 90, 6,156,208, 74,107, 91,229,126, 5, 85,255,136,255, 64, 0,
+170,199,228,195, 0, 2, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0,
+ 0, 0, 0, 0
+};
+
+DEFINE_TEST(test_read_format_cpio_bin_lzip)
+{
+ struct archive_entry *ae;
+ struct archive *a;
+ int r;
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ r = archive_read_support_filter_lzip(a);
+ if (r == ARCHIVE_WARN) {
+ skipping("lzip reading not fully supported on this platform");
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+ return;
+ }
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_memory(a, archive, sizeof(archive)));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_LZIP);
+ assertEqualInt(archive_format(a), ARCHIVE_FORMAT_CPIO_BIN_LE);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
diff --git a/libarchive/test/test_read_format_cpio_bin_lzma.c b/libarchive/test/test_read_format_cpio_bin_lzma.c
index 035b38856d58..e168e2f9c55a 100644
--- a/libarchive/test/test_read_format_cpio_bin_lzma.c
+++ b/libarchive/test/test_read_format_cpio_bin_lzma.c
@@ -41,11 +41,11 @@ DEFINE_TEST(test_read_format_cpio_bin_lzma)
int r;
assert((a = archive_read_new()) != NULL);
- assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a));
- r = archive_read_support_compression_lzma(a);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ r = archive_read_support_filter_lzma(a);
if (r == ARCHIVE_WARN) {
skipping("lzma reading not fully supported on this platform");
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
return;
}
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
@@ -55,6 +55,6 @@ DEFINE_TEST(test_read_format_cpio_bin_lzma)
assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_LZMA);
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_CPIO_BIN_LE);
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_read_format_cpio_bin_xz.c b/libarchive/test/test_read_format_cpio_bin_xz.c
index 813b343fda08..7c65da67751d 100644
--- a/libarchive/test/test_read_format_cpio_bin_xz.c
+++ b/libarchive/test/test_read_format_cpio_bin_xz.c
@@ -51,11 +51,11 @@ DEFINE_TEST(test_read_format_cpio_bin_xz)
int r;
assert((a = archive_read_new()) != NULL);
- assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a));
- r = archive_read_support_compression_xz(a);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ r = archive_read_support_filter_xz(a);
if (r == ARCHIVE_WARN) {
skipping("xz reading not fully supported on this platform");
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
return;
}
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
@@ -65,6 +65,6 @@ DEFINE_TEST(test_read_format_cpio_bin_xz)
assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_XZ);
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_CPIO_BIN_LE);
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_read_format_cpio_filename.c b/libarchive/test/test_read_format_cpio_filename.c
new file mode 100644
index 000000000000..e347b506844b
--- /dev/null
+++ b/libarchive/test/test_read_format_cpio_filename.c
@@ -0,0 +1,874 @@
+/*-
+ * Copyright (c) 2011 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD");
+
+#include <locale.h>
+
+static void
+test_read_format_cpio_filename_eucJP_UTF8(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read eucJP filename in en_US.UTF-8 with "hdrcharset=eucJP" option.
+ */
+ if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
+ skipping("en_US.UTF-8 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=eucJP")) {
+ skipping("This system cannot convert character-set"
+ " from eucJP to UTF-8.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xe6\xbc\xa2\xe5\xad\x97.txt",
+ archive_entry_pathname(ae));
+ assertEqualInt(8, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xe8\xa1\xa8.txt", archive_entry_pathname(ae));
+ assertEqualInt(4, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_CPIO_POSIX, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_cpio_filename_UTF8_eucJP(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read UTF-8 filename in ja_JP.eucJP with "hdrcharset=UTF-8" option.
+ */
+ if (NULL == setlocale(LC_ALL, "ja_JP.eucJP")) {
+ skipping("ja_JP.eucJP locale not available on this system.");
+ return;
+ }
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=UTF-8")) {
+ skipping("This system cannot convert character-set"
+ " from UTF-8 to eucJP.");
+ goto cleanup;
+ }
+
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualString("\xb4\xc1\xbb\xfa.txt", archive_entry_pathname(ae));
+ assertEqualInt(8, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualString("\xc9\xbd.txt", archive_entry_pathname(ae));
+ assertEqualInt(4, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_CPIO_POSIX, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_cpio_filename_UTF8_UTF8_jp(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read UTF-8 filename in en_US.UTF-8 without "hdrcharset=UTF-8" option.
+ */
+ if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
+ skipping("en_US.UTF-8 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualString("\xe6\xbc\xa2\xe5\xad\x97.txt",
+ archive_entry_pathname(ae));
+ assertEqualInt(8, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualString("\xe8\xa1\xa8.txt", archive_entry_pathname(ae));
+ assertEqualInt(4, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_CPIO_POSIX, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_cpio_filename_CP866_KOI8R(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read CP866 filename in ru_RU.KOI8-R with "hdrcharset=CP866" option.
+ */
+ if (NULL == setlocale(LC_ALL, "Russian_Russia.20866") &&
+ NULL == setlocale(LC_ALL, "ru_RU.KOI8-R")) {
+ skipping("ru_RU.KOI8-R locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP866")) {
+ skipping("This system cannot convert character-set"
+ " from CP866 to KOI8-R.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xf0\xf2\xe9\xf7\xe5\xf4",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xd0\xd2\xc9\xd7\xc5\xd4",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_CPIO_POSIX, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_cpio_filename_CP866_UTF8(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read CP866 filename in en_US.UTF-8 with "hdrcharset=CP866" option.
+ */
+ if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
+ skipping("en_US.UTF-8 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP866")) {
+ skipping("This system cannot convert character-set"
+ " from CP866 to UTF-8.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xd0\x9f\xd0\xa0\xd0\x98\xd0\x92\xd0\x95\xd0\xa2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_CPIO_POSIX, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_cpio_filename_KOI8R_CP866(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read KOI8-R filename in ru_RU.CP866 with "hdrcharset=KOI8-R" option.
+ */
+ if (NULL == setlocale(LC_ALL, "Russian_Russia.866") &&
+ NULL == setlocale(LC_ALL, "ru_RU.CP866")) {
+ skipping("ru_RU.CP866 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) {
+ skipping("This system cannot convert character-set"
+ " from KOI8-R to CP866.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\x8f\x90\x88\x82\x85\x92",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xaf\xe0\xa8\xa2\xa5\xe2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_CPIO_POSIX, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_cpio_filename_KOI8R_UTF8(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read KOI8-R filename in en_US.UTF-8 with "hdrcharset=KOI8-R" option.
+ */
+ if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
+ skipping("en_US.UTF-8 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) {
+ skipping("This system cannot convert character-set"
+ " from KOI8-R to UTF-8.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xd0\x9f\xd0\xa0\xd0\x98\xd0\x92\xd0\x95\xd0\xa2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_CPIO_POSIX, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_cpio_filename_UTF8_KOI8R(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read UTF-8 filename in ru_RU.KOI8-R with "hdrcharset=UTF-8" option.
+ */
+ if (NULL == setlocale(LC_ALL, "Russian_Russia.20866") &&
+ NULL == setlocale(LC_ALL, "ru_RU.KOI8-R")) {
+ skipping("ru_RU.KOI8-R locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=UTF-8")) {
+ skipping("This system cannot convert character-set"
+ " from UTF-8 to KOI8-R.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xf0\xf2\xe9\xf7\xe5\xf4",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xd0\xd2\xc9\xd7\xc5\xd4",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_CPIO_POSIX, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_cpio_filename_UTF8_CP866(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read UTF-8 filename in ru_RU.CP866 with "hdrcharset=UTF-8" option.
+ */
+ if (NULL == setlocale(LC_ALL, "Russian_Russia.866") &&
+ NULL == setlocale(LC_ALL, "ru_RU.CP866")) {
+ skipping("ru_RU.CP866 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=UTF-8")) {
+ skipping("This system cannot convert character-set"
+ " from UTF-8 to CP866.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\x8f\x90\x88\x82\x85\x92",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xaf\xe0\xa8\xa2\xa5\xe2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_CPIO_POSIX, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_cpio_filename_UTF8_UTF8_ru(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read UTF-8 filename in en_US.UTF-8 without "hdrcharset=UTF-8" option.
+ */
+ if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
+ skipping("en_US.UTF-8 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xd0\x9f\xd0\xa0\xd0\x98\xd0\x92\xd0\x95\xd0\xa2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_CPIO_POSIX, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_cpio_filename_eucJP_CP932(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read eucJP filename in CP932/SJIS with "hdrcharset=eucJP" option.
+ */
+ if (NULL == setlocale(LC_ALL, "Japanese_Japan") &&
+ NULL == setlocale(LC_ALL, "ja_JP.SJIS")) {
+ skipping("CP932 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=eucJP")) {
+ skipping("This system cannot convert character-set"
+ " from eucJP.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\x8a\xbf\x8e\x9a.txt", archive_entry_pathname(ae));
+ assertEqualInt(8, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\x95\x5c.txt", archive_entry_pathname(ae));
+ assertEqualInt(4, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_CPIO_POSIX, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_cpio_filename_UTF8_CP932(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read UTF-8 filename in CP932/SJIS with "hdrcharset=UTF-8" option.
+ */
+ if (NULL == setlocale(LC_ALL, "Japanese_Japan") &&
+ NULL == setlocale(LC_ALL, "ja_JP.SJIS")) {
+ skipping("CP932 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=UTF-8")) {
+ skipping("This system cannot convert character-set"
+ " from UTF-8 to CP932.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualString("\x8a\xbf\x8e\x9a.txt", archive_entry_pathname(ae));
+ assertEqualInt(8, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualString("\x95\x5c.txt", archive_entry_pathname(ae));
+ assertEqualInt(4, archive_entry_size(ae));
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_CPIO_POSIX, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_cpio_filename_CP866_CP1251(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read CP866 filename in CP1251 with "hdrcharset=CP866" option.
+ */
+ if (NULL == setlocale(LC_ALL, "Russian_Russia") &&
+ NULL == setlocale(LC_ALL, "ru_RU.CP1251")) {
+ skipping("CP1251 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP866")) {
+ skipping("This system cannot convert character-set"
+ " from CP866 to CP1251.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xcf\xd0\xc8\xc2\xc5\xd2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_CPIO_POSIX, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+/*
+ * This test only for Windows platform because other archiver
+ * applications on Windows translate CP1251 filenames into CP866
+ * filenames and store it in the cpio file and so we should read
+ * it by default on Windows.
+ */
+static void
+test_read_format_cpio_filename_CP866_CP1251_win(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read CP866 filename in CP1251 without "hdrcharset=CP866" option.
+ */
+ if (NULL == setlocale(LC_ALL, "Russian_Russia")) {
+ skipping("Russian_Russia locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xcf\xd0\xc8\xc2\xc5\xd2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_CPIO_POSIX, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_cpio_filename_KOI8R_CP1251(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read KOI8-R filename in CP1251 with "hdrcharset=KOI8-R" option.
+ */
+ if (NULL == setlocale(LC_ALL, "Russian_Russia") &&
+ NULL == setlocale(LC_ALL, "ru_RU.CP1251")) {
+ skipping("CP1251 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) {
+ skipping("This system cannot convert character-set"
+ " from KOI8-R to CP1251.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xcf\xd0\xc8\xc2\xc5\xd2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_CPIO_POSIX, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_cpio_filename_UTF8_CP1251(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read KOI8-R filename in CP1251 with "hdrcharset=KOI8-R" option.
+ */
+ if (NULL == setlocale(LC_ALL, "Russian_Russia") &&
+ NULL == setlocale(LC_ALL, "ru_RU.CP1251")) {
+ skipping("CP1251 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=UTF-8")) {
+ skipping("This system cannot convert character-set"
+ " from UTF-8 to CP1251.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xcf\xd0\xc8\xc2\xc5\xd2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_CPIO_POSIX, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+
+DEFINE_TEST(test_read_format_cpio_filename)
+{
+ const char *refname1 = "test_read_format_cpio_filename_eucjp.cpio";
+ const char *refname2 = "test_read_format_cpio_filename_utf8_jp.cpio";
+ const char *refname3 = "test_read_format_cpio_filename_cp866.cpio";
+ const char *refname4 = "test_read_format_cpio_filename_koi8r.cpio";
+ const char *refname5 = "test_read_format_cpio_filename_utf8_ru.cpio";
+
+ extract_reference_file(refname1);
+ test_read_format_cpio_filename_eucJP_UTF8(refname1);
+ test_read_format_cpio_filename_eucJP_CP932(refname1);
+
+ extract_reference_file(refname2);
+ test_read_format_cpio_filename_UTF8_eucJP(refname2);
+ test_read_format_cpio_filename_UTF8_UTF8_jp(refname2);
+ test_read_format_cpio_filename_UTF8_CP932(refname2);
+
+ extract_reference_file(refname3);
+ test_read_format_cpio_filename_CP866_KOI8R(refname3);
+ test_read_format_cpio_filename_CP866_UTF8(refname3);
+ test_read_format_cpio_filename_CP866_CP1251(refname3);
+ test_read_format_cpio_filename_CP866_CP1251_win(refname3);
+
+ extract_reference_file(refname4);
+ test_read_format_cpio_filename_KOI8R_CP866(refname4);
+ test_read_format_cpio_filename_KOI8R_UTF8(refname4);
+ test_read_format_cpio_filename_KOI8R_CP1251(refname4);
+
+ extract_reference_file(refname5);
+ test_read_format_cpio_filename_UTF8_KOI8R(refname5);
+ test_read_format_cpio_filename_UTF8_CP866(refname5);
+ test_read_format_cpio_filename_UTF8_UTF8_ru(refname5);
+ test_read_format_cpio_filename_UTF8_CP1251(refname5);
+}
diff --git a/libarchive/test/test_read_format_cpio_filename_cp866.cpio.uu b/libarchive/test/test_read_format_cpio_filename_cp866.cpio.uu
new file mode 100644
index 000000000000..5f0658504039
--- /dev/null
+++ b/libarchive/test/test_read_format_cpio_filename_cp866.cpio.uu
@@ -0,0 +1,15 @@
+begin 644 test_read_format_cpio_cp866.cpio
+M,#<P-S`W,#`P,3,W,#`P,#`Q,3`P-S4U,#`Q-S4Q,#`Q-S4Q,#`P,#`Q,#`P
+M,#`P,3$U-#<S,C$U,#$P,#`P,#<P,#`P,#`P,#`P-H^0B(*%D@#P\NGWY?0P
+M-S`W,#<P,#`Q,S<P,#`P,#(Q,#`W-34P,#$W-3$P,#$W-3$P,#`P,#$P,#`P
+M,#`Q,34T-S,R,34P,3`P,#`P-S`P,#`P,#`P,#`VK^"HHJ7B`/#RZ??E]#`W
+M,#<P-S`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,3`P,#`P
+M,#`P,#`P,#`P,#`P,#`P,#$S,#`P,#`P,#`P,#!44D%)3$52(2$A````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+1````````````````````````
+`
+end
diff --git a/libarchive/test/test_read_format_cpio_filename_eucjp.cpio.uu b/libarchive/test/test_read_format_cpio_filename_eucjp.cpio.uu
new file mode 100644
index 000000000000..9aa7666bc4a8
--- /dev/null
+++ b/libarchive/test/test_read_format_cpio_filename_eucjp.cpio.uu
@@ -0,0 +1,15 @@
+begin 644 test_read_format_cpio_eucjp.cpio
+M,#<P-S`W,#`P,3,W,#`P,#`Q,3`P-C0T,#`Q-S4Q,#`Q-S4Q,#`P,#`Q,#`P
+M,#`P,3$U-3$U,C(U,C`P,#`P,3$P,#`P,#`P,#`Q,+3!N_HN='AT`(J_CIJ"
+MJ8+(,#<P-S`W,#`P,3,W,#`P,#`R,3`P-C0T,#`Q-S4Q,#`Q-S4Q,#`P,#`Q
+M,#`P,#`P,3$U-3$U,C(U,C`P,#`P,#<P,#`P,#`P,#`P-,F]+G1X=`!L:7-T
+M,#<P-S`W,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`Q,#`P
+M,#`P,#`P,#`P,#`P,#`P,#`P,3,P,#`P,#`P,#`P,%1204E,15(A(2$`````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+1````````````````````````
+`
+end
diff --git a/libarchive/test/test_read_format_cpio_filename_koi8r.cpio.uu b/libarchive/test/test_read_format_cpio_filename_koi8r.cpio.uu
new file mode 100644
index 000000000000..dcdfd0ed63d8
--- /dev/null
+++ b/libarchive/test/test_read_format_cpio_filename_koi8r.cpio.uu
@@ -0,0 +1,15 @@
+begin 644 test_read_format_cpio_koi8r.cpio
+M,#<P-S`W,#`P,3,W,#`P,#`Q,3`P-S4U,#`Q-S4Q,#`Q-S4Q,#`P,#`Q,#`P
+M,#`P,3$U-#<S,C`P,S8P,#`P,#<P,#`P,#`P,#`P-O#RZ??E]`#P\NGWY?0P
+M-S`W,#<P,#`Q,S<P,#`P,#(Q,#`W-34P,#$W-3$P,#$W-3$P,#`P,#$P,#`P
+M,#`Q,34T-S,R,#`S-C`P,#`P-S`P,#`P,#`P,#`VT-+)U\74`/#RZ??E]#`W
+M,#<P-S`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,3`P,#`P
+M,#`P,#`P,#`P,#`P,#`P,#$S,#`P,#`P,#`P,#!44D%)3$52(2$A````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+1````````````````````````
+`
+end
diff --git a/libarchive/test/test_read_format_cpio_filename_utf8_jp.cpio.uu b/libarchive/test/test_read_format_cpio_filename_utf8_jp.cpio.uu
new file mode 100644
index 000000000000..8f9a6f652c28
--- /dev/null
+++ b/libarchive/test/test_read_format_cpio_filename_utf8_jp.cpio.uu
@@ -0,0 +1,15 @@
+begin 644 test_read_format_cpio_utf8_jp.cpio
+M,#<P-S`W,#`P,3,W,#`P,#`Q,3`P-C0T,#`Q-S4Q,#`Q-S4Q,#`P,#`Q,#`P
+M,#`P,3$U-3$U,C(S-C8P,#`P,3,P,#`P,#`P,#`Q,.:\HN6MERYT>'0`BK^.
+MFH*I@L@P-S`W,#<P,#`Q,S<P,#`P,#(Q,#`V-#0P,#$W-3$P,#$W-3$P,#`P
+M,#$P,#`P,#`Q,34U,34R,C,V-C`P,#`Q,#`P,#`P,#`P,#`TZ*&H+G1X=`!L
+M:7-T,#<P-S`W,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`Q
+M,#`P,#`P,#`P,#`P,#`P,#`P,#`P,3,P,#`P,#`P,#`P,%1204E,15(A(2$`
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+1````````````````````````
+`
+end
diff --git a/libarchive/test/test_read_format_cpio_filename_utf8_ru.cpio.uu b/libarchive/test/test_read_format_cpio_filename_utf8_ru.cpio.uu
new file mode 100644
index 000000000000..9ed52f87c44c
--- /dev/null
+++ b/libarchive/test/test_read_format_cpio_filename_utf8_ru.cpio.uu
@@ -0,0 +1,15 @@
+begin 644 test_read_format_cpio_utf8_ru.cpio
+M,#<P-S`W,#`P,3,W,#`P,#`Q,3`P-S4U,#`Q-S4Q,#`Q-S4Q,#`P,#`Q,#`P
+M,#`P,3$U,C$U,38U,38P,#`P,34P,#`P,#`P,#`P-M"?T*#0F-"2T)70H@#P
+M\NGWY?0P-S`W,#<P,#`Q,S<P,#`P,#(Q,#`W-34P,#$W-3$P,#$W-3$P,#`P
+M,#$P,#`P,#`Q,34R,34R,#$S,C`P,#`Q-3`P,#`P,#`P,#`VT+_1@-"XT++0
+MM=&"`/#RZ??E]#`W,#<P-S`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P
+M,#`P,#`P,3`P,#`P,#`P,#`P,#`P,#`P,#`P,#$S,#`P,#`P,#`P,#!44D%)
+M3$52(2$A````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+1````````````````````````
+`
+end
diff --git a/libarchive/test/test_read_format_cpio_odc.c b/libarchive/test/test_read_format_cpio_odc.c
index 6563fcd7e9ef..cdcf0b5aff31 100644
--- a/libarchive/test/test_read_format_cpio_odc.c
+++ b/libarchive/test/test_read_format_cpio_odc.c
@@ -51,18 +51,14 @@ DEFINE_TEST(test_read_format_cpio_odc)
struct archive_entry *ae;
struct archive *a;
assert((a = archive_read_new()) != NULL);
- assertA(0 == archive_read_support_compression_all(a));
+ assertA(0 == archive_read_support_filter_all(a));
assertA(0 == archive_read_support_format_all(a));
assertA(0 == archive_read_open_memory(a, archive, sizeof(archive)));
assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
assertA(archive_compression(a) == ARCHIVE_COMPRESSION_NONE);
assertA(archive_format(a) == ARCHIVE_FORMAT_CPIO_POSIX);
- assert(0 == archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assert(0 == archive_read_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.c b/libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.c
index 3b4170cb787c..f0d27a3d0c0f 100644
--- a/libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.c
+++ b/libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.c
@@ -90,15 +90,15 @@ DEFINE_TEST(test_read_format_cpio_svr4_bzip2_rpm)
int r;
assert((a = archive_read_new()) != NULL);
- r = archive_read_support_compression_bzip2(a);
+ r = archive_read_support_filter_bzip2(a);
if (r == ARCHIVE_WARN) {
skipping("bzip2 reading not fully supported on this platform");
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
return;
}
assertEqualIntA(a, ARCHIVE_OK, r);
assertEqualIntA(a, ARCHIVE_OK,
- archive_read_support_compression_rpm(a));
+ archive_read_support_filter_rpm(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
extract_reference_file(name);
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 2));
@@ -122,6 +122,6 @@ DEFINE_TEST(test_read_format_cpio_svr4_bzip2_rpm)
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_CPIO_SVR4_NOCRC);
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_read_format_cpio_svr4_gzip.c b/libarchive/test/test_read_format_cpio_svr4_gzip.c
index 8b19a021b0d0..88d54d172c18 100644
--- a/libarchive/test/test_read_format_cpio_svr4_gzip.c
+++ b/libarchive/test/test_read_format_cpio_svr4_gzip.c
@@ -39,11 +39,11 @@ DEFINE_TEST(test_read_format_cpio_svr4_gzip)
int r;
assert((a = archive_read_new()) != NULL);
- assertEqualInt(ARCHIVE_OK, archive_read_support_compression_all(a));
- r = archive_read_support_compression_gzip(a);
+ assertEqualInt(ARCHIVE_OK, archive_read_support_filter_all(a));
+ r = archive_read_support_filter_gzip(a);
if (r == ARCHIVE_WARN) {
skipping("gzip reading not fully supported on this platform");
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
return;
}
assertEqualInt(ARCHIVE_OK, archive_read_support_format_all(a));
@@ -55,7 +55,7 @@ DEFINE_TEST(test_read_format_cpio_svr4_gzip)
assertEqualInt(archive_format(a),
ARCHIVE_FORMAT_CPIO_SVR4_NOCRC);
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_read_format_cpio_svr4_gzip_rpm.c b/libarchive/test/test_read_format_cpio_svr4_gzip_rpm.c
index eb8a38d9df35..338a088a6135 100644
--- a/libarchive/test/test_read_format_cpio_svr4_gzip_rpm.c
+++ b/libarchive/test/test_read_format_cpio_svr4_gzip_rpm.c
@@ -90,15 +90,15 @@ DEFINE_TEST(test_read_format_cpio_svr4_gzip_rpm)
int r;
assert((a = archive_read_new()) != NULL);
- r = archive_read_support_compression_gzip(a);
+ r = archive_read_support_filter_gzip(a);
if (r == ARCHIVE_WARN) {
skipping("gzip reading not fully supported on this platform");
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
return;
}
assertEqualIntA(a, ARCHIVE_OK, r);
assertEqualIntA(a, ARCHIVE_OK,
- archive_read_support_compression_rpm(a));
+ archive_read_support_filter_rpm(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
extract_reference_file(name);
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 2));
@@ -122,6 +122,6 @@ DEFINE_TEST(test_read_format_cpio_svr4_gzip_rpm)
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_CPIO_SVR4_NOCRC);
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_read_format_cpio_svr4c_Z.c b/libarchive/test/test_read_format_cpio_svr4c_Z.c
index d3f086bbd51a..ca3d5ce07668 100644
--- a/libarchive/test/test_read_format_cpio_svr4c_Z.c
+++ b/libarchive/test/test_read_format_cpio_svr4c_Z.c
@@ -40,7 +40,7 @@ DEFINE_TEST(test_read_format_cpio_svr4c_Z)
/* printf("Archive address: start=%X, end=%X\n", archive, archive+sizeof(archive)); */
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK,
- archive_read_support_compression_all(a));
+ archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK,
@@ -52,11 +52,7 @@ DEFINE_TEST(test_read_format_cpio_svr4c_Z)
failure("archive_format_name(a)=\"%s\"", archive_format_name(a));
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_CPIO_SVR4_CRC);
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
-#endif
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_read_format_empty.c b/libarchive/test/test_read_format_empty.c
index 98cfdfa26f5d..0dafe9f6c958 100644
--- a/libarchive/test/test_read_format_empty.c
+++ b/libarchive/test/test_read_format_empty.c
@@ -32,16 +32,12 @@ DEFINE_TEST(test_read_format_empty)
struct archive_entry *ae;
struct archive *a;
assert((a = archive_read_new()) != NULL);
- assertA(0 == archive_read_support_compression_all(a));
+ assertA(0 == archive_read_support_filter_all(a));
assertA(0 == archive_read_support_format_all(a));
assertA(0 == archive_read_open_memory(a, archive, 0));
assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
assertA(archive_compression(a) == ARCHIVE_COMPRESSION_NONE);
assertA(archive_format(a) == ARCHIVE_FORMAT_EMPTY);
- assert(0 == archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assert(0 == archive_read_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_read_format_gtar_filename.c b/libarchive/test/test_read_format_gtar_filename.c
new file mode 100644
index 000000000000..4b2a88c1ee0b
--- /dev/null
+++ b/libarchive/test/test_read_format_gtar_filename.c
@@ -0,0 +1,512 @@
+/*-
+ * Copyright (c) 2011 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD");
+
+#include <locale.h>
+
+static void
+test_read_format_gtar_filename_eucJP_UTF8(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read eucJP filename in en_US.UTF-8 with "hdrcharset=eucJP" option.
+ */
+ if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
+ skipping("en_US.UTF-8 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=eucJP")) {
+ skipping("This system cannot convert character-set"
+ " from eucJP to UTF-8.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xe6\xbc\xa2\xe5\xad\x97.txt",
+ archive_entry_pathname(ae));
+ assertEqualInt(8, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xe8\xa1\xa8.txt", archive_entry_pathname(ae));
+ assertEqualInt(4, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
+ assertEqualIntA(a, ARCHIVE_FORMAT_TAR_GNUTAR, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_gtar_filename_CP866_KOI8R(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read CP866 filename in ru_RU.KOI8-R with "hdrcharset=CP866" option.
+ */
+ if (NULL == setlocale(LC_ALL, "Russian_Russia.20866") &&
+ NULL == setlocale(LC_ALL, "ru_RU.KOI8-R")) {
+ skipping("ru_RU.KOI8-R locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP866")) {
+ skipping("This system cannot convert character-set"
+ " from CP866 to KOI8-R.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xf0\xf2\xe9\xf7\xe5\xf4",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xd0\xd2\xc9\xd7\xc5\xd4",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
+ assertEqualIntA(a, ARCHIVE_FORMAT_TAR_GNUTAR, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_gtar_filename_CP866_UTF8(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read CP866 filename in en_US.UTF-8 with "hdrcharset=CP866" option.
+ */
+ if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
+ skipping("en_US.UTF-8 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP866")) {
+ skipping("This system cannot convert character-set"
+ " from CP866 to UTF-8.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xd0\x9f\xd0\xa0\xd0\x98\xd0\x92\xd0\x95\xd0\xa2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
+ assertEqualIntA(a, ARCHIVE_FORMAT_TAR_GNUTAR, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_gtar_filename_KOI8R_CP866(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read KOI8-R filename in ru_RU.CP866 with "hdrcharset=KOI8-R" option.
+ */
+ if (NULL == setlocale(LC_ALL, "Russian_Russia.866") &&
+ NULL == setlocale(LC_ALL, "ru_RU.CP866")) {
+ skipping("ru_RU.CP866 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) {
+ skipping("This system cannot convert character-set"
+ " from KOI8-R to CP866.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xaf\xe0\xa8\xa2\xa5\xe2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\x8f\x90\x88\x82\x85\x92",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
+ assertEqualIntA(a, ARCHIVE_FORMAT_TAR_GNUTAR, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_gtar_filename_KOI8R_UTF8(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read KOI8-R filename in en_US.UTF-8 with "hdrcharset=KOI8-R" option.
+ */
+ if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
+ skipping("en_US.UTF-8 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) {
+ skipping("This system cannot convert character-set"
+ " from KOI8-R to UTF-8.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xd0\x9f\xd0\xa0\xd0\x98\xd0\x92\xd0\x95\xd0\xa2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
+ assertEqualIntA(a, ARCHIVE_FORMAT_TAR_GNUTAR, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_gtar_filename_eucJP_CP932(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read eucJP filename in CP932/SJIS with "hdrcharset=eucJP" option.
+ */
+ if (NULL == setlocale(LC_ALL, "Japanese_Japan") &&
+ NULL == setlocale(LC_ALL, "ja_JP.SJIS")) {
+ skipping("CP932 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=eucJP")) {
+ skipping("This system cannot convert character-set"
+ " from eucJP.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\x8a\xbf\x8e\x9a.txt", archive_entry_pathname(ae));
+ assertEqualInt(8, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\x95\x5c.txt", archive_entry_pathname(ae));
+ assertEqualInt(4, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
+ assertEqualIntA(a, ARCHIVE_FORMAT_TAR_GNUTAR, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_gtar_filename_CP866_CP1251(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read CP866 filename in CP1251 with "hdrcharset=CP866" option.
+ */
+ if (NULL == setlocale(LC_ALL, "Russian_Russia") &&
+ NULL == setlocale(LC_ALL, "ru_RU.CP1251")) {
+ skipping("CP1251 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP866")) {
+ skipping("This system cannot convert character-set"
+ " from CP866 to CP1251.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xcf\xd0\xc8\xc2\xc5\xd2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
+ assertEqualIntA(a, ARCHIVE_FORMAT_TAR_GNUTAR, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+/*
+ * This test only for Windows platform because other archiver
+ * applications on Windows translate CP1251 filenames into CP866
+ * filenames and store it in the gtar file and so we should read
+ * it by default on Windows.
+ */
+static void
+test_read_format_gtar_filename_CP866_CP1251_win(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read CP866 filename in CP1251 without "hdrcharset=CP866" option.
+ */
+ if (NULL == setlocale(LC_ALL, "Russian_Russia")) {
+ skipping("Russian_Russia locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xcf\xd0\xc8\xc2\xc5\xd2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
+ assertEqualIntA(a, ARCHIVE_FORMAT_TAR_GNUTAR, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_gtar_filename_KOI8R_CP1251(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read KOI8-R filename in CP1251 with "hdrcharset=KOI8-R" option.
+ */
+ if (NULL == setlocale(LC_ALL, "Russian_Russia") &&
+ NULL == setlocale(LC_ALL, "ru_RU.CP1251")) {
+ skipping("CP1251 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) {
+ skipping("This system cannot convert character-set"
+ " from KOI8-R to CP1251.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xcf\xd0\xc8\xc2\xc5\xd2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
+ assertEqualIntA(a, ARCHIVE_FORMAT_TAR_GNUTAR, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+
+DEFINE_TEST(test_read_format_gtar_filename)
+{
+ const char *refname1 = "test_read_format_gtar_filename_eucjp.tar.Z";
+ const char *refname2 = "test_read_format_gtar_filename_cp866.tar.Z";
+ const char *refname3 = "test_read_format_gtar_filename_koi8r.tar.Z";
+
+ extract_reference_file(refname1);
+ test_read_format_gtar_filename_eucJP_UTF8(refname1);
+ test_read_format_gtar_filename_eucJP_CP932(refname1);
+
+ extract_reference_file(refname2);
+ test_read_format_gtar_filename_CP866_KOI8R(refname2);
+ test_read_format_gtar_filename_CP866_UTF8(refname2);
+ test_read_format_gtar_filename_CP866_CP1251(refname2);
+ test_read_format_gtar_filename_CP866_CP1251_win(refname2);
+
+ extract_reference_file(refname3);
+ test_read_format_gtar_filename_KOI8R_CP866(refname3);
+ test_read_format_gtar_filename_KOI8R_UTF8(refname3);
+ test_read_format_gtar_filename_KOI8R_CP1251(refname3);
+}
diff --git a/libarchive/test/test_read_format_gtar_filename_cp866.tar.Z.uu b/libarchive/test/test_read_format_gtar_filename_cp866.tar.Z.uu
new file mode 100644
index 000000000000..a6fd80c24695
--- /dev/null
+++ b/libarchive/test/test_read_format_gtar_filename_cp866.tar.Z.uu
@@ -0,0 +1,10 @@
+begin 644 test_read_format_gtar_cp866.tar.Z
+M'YV0CR`A$E1($H"#"!,J7,BPH<.'$"-*1`BC(HP;-6H`L!@#8XR-%3O6^&BQ
+MI$4;`&+$J$'CQ@P9*V&0C`'#Q@T9`$#`F,BSI\^?0`'4F4,GC!P0(`",J5,F
+MJ,.E39U*G4JUJM6K6'G"DY?N7CEZ6<.*'4NVK-FS:-.J7<NVK<-7X%")*B7.
+MK5V&)3%JY.@1I,R^)DVB5,G2)<P:,C>JG/$RY\Z[D!L.+7HT*=2LER-KWLS9
+MY]:N7SN+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\
+MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^
+1O?OW\./+GT^_OOW[^//KKPX`
+`
+end
diff --git a/libarchive/test/test_read_format_gtar_filename_eucjp.tar.Z.uu b/libarchive/test/test_read_format_gtar_filename_eucjp.tar.Z.uu
new file mode 100644
index 000000000000..87fa582f6809
--- /dev/null
+++ b/libarchive/test/test_read_format_gtar_filename_eucjp.tar.Z.uu
@@ -0,0 +1,10 @@
+begin 644 test_read_format_gtar_eucjp.tar.Z
+M'YV0M(+MTN>"#AXZ`!(J7,BPH<.'$"-*G$@1`(R+,&S0H&'Q8HP;-6)TA/$Q
+MY$B,&&/``!`C1HV0-63(B+F29`P:)D&LK,BSI\^?0.O,H1-&#@@0`,;4*0,T
+MHE*F3:-*G4JUJM6K4Q7]<J1)4"I!R+"*'4NVK-FS:-.J7<NVK=NHR7H5//BV
+M+D24&CFF!"ERKTF4@&%P;/G2I4R:%E7:4`E`I]W'$H42-8KTJ5C+D#-KWAR5
+M39JAG$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\
+MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^
+1O?OW\./+GT^_OOW[^//K+PT`
+`
+end
diff --git a/libarchive/test/test_read_format_gtar_filename_koi8r.tar.Z.uu b/libarchive/test/test_read_format_gtar_filename_koi8r.tar.Z.uu
new file mode 100644
index 000000000000..bf4ce01708cc
--- /dev/null
+++ b/libarchive/test/test_read_format_gtar_filename_koi8r.tar.Z.uu
@@ -0,0 +1,10 @@
+begin 644 test_read_format_gtar_koi8r.tar.Z
+M'YV0T*0ENU:,&H"#"!,J7,BPH<.'$"-*1`BC(HP;-6H`L!@#8XR-%3O6^&BQ
+MI$4;`&+$J$'CQ@P9%6>@A*&RAHP;`$#`F,BSI\^?0`'4F4,GC!P0(`",J5,F
+MJ,.E39U*G4JUJM6K6'G"DY?N7CEZ6<.*'4NVK-FS:-.J7<NVK<.M7;^ZG<NP
+M)$:-'#V"I*G7I$F4-5N^C#DS!LR;.7?27=QP:-&C2:%FE<RXLN7+/N%Z!8NY
+ML^?/H$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\
+MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^
++O?OW\./+GT^__G,`
+`
+end
diff --git a/libarchive/test/test_read_format_gtar_gz.c b/libarchive/test/test_read_format_gtar_gz.c
index 3071b1d0b497..d688f08fec21 100644
--- a/libarchive/test/test_read_format_gtar_gz.c
+++ b/libarchive/test/test_read_format_gtar_gz.c
@@ -39,22 +39,23 @@ DEFINE_TEST(test_read_format_gtar_gz)
int r;
assert((a = archive_read_new()) != NULL);
- assertEqualInt(ARCHIVE_OK, archive_read_support_compression_all(a));
- r = archive_read_support_compression_gzip(a);
+ assertEqualInt(ARCHIVE_OK, archive_read_support_filter_all(a));
+ r = archive_read_support_filter_gzip(a);
if (r == ARCHIVE_WARN) {
skipping("gzip reading not fully supported on this platform");
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
return;
}
assertEqualInt(ARCHIVE_OK, archive_read_support_format_all(a));
assertEqualInt(ARCHIVE_OK,
archive_read_open_memory(a, archive, sizeof(archive)));
assertEqualInt(ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(1, archive_file_count(a));
assertEqualInt(archive_compression(a),
ARCHIVE_COMPRESSION_GZIP);
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_GNUTAR);
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_read_format_gtar_lzma.c b/libarchive/test/test_read_format_gtar_lzma.c
index 0e8ff32e57a0..29ffae12fcf7 100644
--- a/libarchive/test/test_read_format_gtar_lzma.c
+++ b/libarchive/test/test_read_format_gtar_lzma.c
@@ -45,11 +45,11 @@ DEFINE_TEST(test_read_format_gtar_lzma)
struct archive *a;
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK,
- archive_read_support_compression_all(a));
- r = archive_read_support_compression_lzma(a);
+ archive_read_support_filter_all(a));
+ r = archive_read_support_filter_lzma(a);
if (r == ARCHIVE_WARN) {
skipping("lzma reading not fully supported on this platform");
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
return;
}
@@ -68,11 +68,7 @@ DEFINE_TEST(test_read_format_gtar_lzma)
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_GNUTAR);
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
finish:
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
-#endif
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_read_format_gtar_sparse.c b/libarchive/test/test_read_format_gtar_sparse.c
index d055fc249a74..9a3511e9cc6a 100644
--- a/libarchive/test/test_read_format_gtar_sparse.c
+++ b/libarchive/test/test_read_format_gtar_sparse.c
@@ -27,7 +27,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_gtar_sparse.c 1893
struct contents {
- off_t o;
+ int64_t o;
size_t s;
const char *d;
};
@@ -186,7 +186,7 @@ verify_archive_file(const char *name, struct archive_contents *ac)
extract_reference_file(name);
assert((a = archive_read_new()) != NULL);
- assert(0 == archive_read_support_compression_all(a));
+ assert(0 == archive_read_support_filter_all(a));
assert(0 == archive_read_support_format_tar(a));
failure("Can't open %s", name);
assert(0 == archive_read_open_filename(a, name, 3));
@@ -195,7 +195,7 @@ verify_archive_file(const char *name, struct archive_contents *ac)
struct contents *cts = ac->contents;
if (!assertEqualIntA(a, 0, archive_read_next_header(a, &ae))) {
- assert(0 == archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
return;
}
failure("Name mismatch in archive %s", name);
@@ -233,7 +233,7 @@ verify_archive_file(const char *name, struct archive_contents *ac)
failure("%s: Unexpected trailing data",
name);
assert(actual.o <= expect.o);
- archive_read_finish(a);
+ archive_read_free(a);
return;
}
actual.d++;
@@ -245,13 +245,8 @@ verify_archive_file(const char *name, struct archive_contents *ac)
assertEqualIntA(a, err, ARCHIVE_EOF);
failure("%s: Size returned at EOF must be zero", name);
assertEqualInt((int)actual.s, 0);
-#if ARCHIVE_VERSION_NUMBER < 1009000
- /* libarchive < 1.9 doesn't get this right */
- skipping("offset of final sparse chunk");
-#else
failure("%s: Offset of final empty chunk must be same as file size", name);
assertEqualInt(actual.o, expect.o);
-#endif
/* Step to next file description. */
++ac;
}
@@ -259,12 +254,8 @@ verify_archive_file(const char *name, struct archive_contents *ac)
err = archive_read_next_header(a, &ae);
assertEqualIntA(a, ARCHIVE_EOF, err);
- assert(0 == archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assert(0 == archive_read_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
@@ -278,9 +269,7 @@ DEFINE_TEST(test_read_format_gtar_sparse)
* libarchive < 1.9 doesn't support the newer --posix sparse formats
* from GNU tar 1.15 and later.
*/
-#if ARCHIVE_VERSION_NUMBER < 1009000
- skipping("read support for GNUtar --posix sparse formats");
-#else
+
/*
* An archive created by GNU tar 1.17 using --posix --sparse-format=0.1
*/
@@ -312,7 +301,6 @@ DEFINE_TEST(test_read_format_gtar_sparse)
verify_archive_file(
"test_read_format_gtar_sparse_1_17_posix10_modified.tar",
files);
-#endif
}
diff --git a/libarchive/test/test_read_format_iso_Z.c b/libarchive/test/test_read_format_iso_Z.c
index 3037527a3625..61b2abdc16c2 100644
--- a/libarchive/test/test_read_format_iso_Z.c
+++ b/libarchive/test/test_read_format_iso_Z.c
@@ -36,22 +36,23 @@ test1(void)
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK,
- archive_read_support_compression_all(a));
+ archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_open_filename(a, name, 512));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_next_header(a, &ae));
+ assertEqualInt(1, archive_file_count(a));
assertEqualInt(archive_compression(a),
ARCHIVE_COMPRESSION_COMPRESS);
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660);
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
-static
-void test2(void)
+static void
+test2(void)
{
struct archive_entry *ae;
struct archive *a;
@@ -61,7 +62,7 @@ void test2(void)
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK,
- archive_read_support_compression_all(a));
+ archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK,
@@ -83,11 +84,12 @@ void test2(void)
assertEqualString("C/D", archive_entry_pathname(ae));
assertEqualIntA(a, ARCHIVE_EOF,
archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_file_count(a));
assertEqualInt(archive_compression(a),
ARCHIVE_COMPRESSION_COMPRESS);
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660);
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
DEFINE_TEST(test_read_format_iso_Z)
@@ -95,5 +97,3 @@ DEFINE_TEST(test_read_format_iso_Z)
test1();
test2();
}
-
-
diff --git a/libarchive/test/test_read_format_iso_joliet_by_nero.iso.Z.uu b/libarchive/test/test_read_format_iso_joliet_by_nero.iso.Z.uu
new file mode 100644
index 000000000000..8a5a26332ae5
--- /dev/null
+++ b/libarchive/test/test_read_format_iso_joliet_by_nero.iso.Z.uu
@@ -0,0 +1,64 @@
+begin 600 test_read_format_iso_joliet_by_nero.iso.Z
+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
+F&(_R.(_T6(_V>(_XF(_ZN(_\V(_^^(\`&9`".9`$69`&>9`(V6X`
+`
+end
diff --git a/libarchive/test/test_read_format_iso_multi_extent.c b/libarchive/test/test_read_format_iso_multi_extent.c
index 3ec472dab2bb..2230d8e2089c 100644
--- a/libarchive/test/test_read_format_iso_multi_extent.c
+++ b/libarchive/test/test_read_format_iso_multi_extent.c
@@ -33,12 +33,12 @@ DEFINE_TEST(test_read_format_iso_multi_extent)
struct archive *a;
const void *p;
size_t size;
- off_t offset;
+ int64_t offset;
int i;
extract_reference_file(refname);
assert((a = archive_read_new()) != NULL);
- assertEqualInt(0, archive_read_support_compression_all(a));
+ assertEqualInt(0, archive_read_support_filter_all(a));
assertEqualInt(0, archive_read_support_format_all(a));
assertEqualInt(ARCHIVE_OK,
archive_read_open_filename(a, refname, 10240));
@@ -87,8 +87,8 @@ DEFINE_TEST(test_read_format_iso_multi_extent)
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660_ROCKRIDGE);
/* Close the archive. */
- assertEqualInt(0, archive_read_close(a));
- assertEqualInt(0, archive_read_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_read_format_iso_xorriso.c b/libarchive/test/test_read_format_iso_xorriso.c
new file mode 100644
index 000000000000..bb53e3b67537
--- /dev/null
+++ b/libarchive/test/test_read_format_iso_xorriso.c
@@ -0,0 +1,213 @@
+/*-
+ * Copyright (c) 2011 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+
+/*
+Execute the following command to rebuild the data for this program:
+ tail -n +32 test_read_format_iso_xorriso.c | /bin/sh
+#
+rm -rf /tmp/iso
+mkdir /tmp/iso
+mkdir /tmp/iso/dir
+mkdir /tmp/iso/dir2
+echo "hello" >/tmp/iso/file
+ln /tmp/iso/file /tmp/iso/hardlink
+(cd /tmp/iso; ln -s file symlink)
+TZ=utc touch -afm -t 197001020000.01 /tmp/iso/empty
+echo "hello2" >/tmp/iso/dir/file2
+echo "hello3" >/tmp/iso/dir/file3
+echo "hello4" >/tmp/iso/dir2/file4
+
+TZ=utc touch -afhm -t 197001020000.01 /tmp/iso/dir/file2 /tmp/iso/dir/file3
+TZ=utc touch -afhm -t 197001020000.01 /tmp/iso/dir2/file4
+TZ=utc touch -afhm -t 197001020000.01 /tmp/iso /tmp/iso/file /tmp/iso/dir
+TZ=utc touch -afhm -t 197001020000.01 /tmp/iso/dir2
+TZ=utc touch -afhm -t 197001030000.02 /tmp/iso/symlink
+F=test_read_format_iso_xorriso.iso
+xorriso -outdev - -map /tmp/iso / > $F
+compress $F
+uuencode $F.Z $F.Z > $F.Z.uu
+rm $F.Z
+exit 1
+ */
+
+/*
+ * A test for the iso images made by xorriso which versions are
+ * from 0.6.5 to 1.0.1.
+ * The xorriso set 0 to the location of empty files(include symlink
+ * files) that caused our iso reader could not read following directory
+ * entries at all.
+ *
+ */
+
+DEFINE_TEST(test_read_format_iso_xorriso)
+{
+ const char *refname = "test_read_format_iso_xorriso.iso.Z";
+ struct archive_entry *ae;
+ struct archive *a;
+ const void *p;
+ size_t size;
+ int64_t offset;
+ int i;
+
+ extract_reference_file(refname);
+ assert((a = archive_read_new()) != NULL);
+ assertEqualInt(0, archive_read_support_filter_all(a));
+ assertEqualInt(0, archive_read_support_format_all(a));
+ assertEqualInt(ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Retrieve each of the 10 files on the ISO image and
+ * verify that each one is what we expect. */
+ for (i = 0; i < 10; ++i) {
+ assertEqualInt(0, archive_read_next_header(a, &ae));
+
+ if (strcmp(".", archive_entry_pathname(ae)) == 0) {
+ /* '.' root directory. */
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+ /* Now, we read timestamp recorded by RRIP "TF". */
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_mtime_nsec(ae));
+ /* Now, we read links recorded by RRIP "PX". */
+ assertEqualInt(4, archive_entry_nlink(ae));
+ assertEqualIntA(a, ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ } else if (strcmp("./dir", archive_entry_pathname(ae)) == 0) {
+ /* A directory. */
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+ assertEqualInt(2, archive_entry_nlink(ae));
+ } else if (strcmp("./dir2", archive_entry_pathname(ae)) == 0) {
+ /* A directory. */
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+ assertEqualInt(2, archive_entry_nlink(ae));
+ } else if (strcmp("./file",
+ archive_entry_pathname(ae)) == 0) {
+ /* A regular file. */
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+ assertEqualInt(0,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt(0, offset);
+ assertEqualMem(p, "hello\n", 6);
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+ assertEqualInt(2, archive_entry_nlink(ae));
+ } else if (strcmp("./hardlink",
+ archive_entry_pathname(ae)) == 0) {
+ /* A hardlink to the regular file. */
+ /* Note: If "hardlink" gets returned before "file",
+ * then "hardlink" will get returned as a regular file
+ * and "file" will get returned as the hardlink.
+ * This test should tolerate that, since it's a
+ * perfectly permissible thing for libarchive to do. */
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualString("./file", archive_entry_hardlink(ae));
+ assertEqualInt(0, archive_entry_size_is_set(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+ assertEqualInt(2, archive_entry_stat(ae)->st_nlink);
+ } else if (strcmp("./symlink",
+ archive_entry_pathname(ae)) == 0) {
+ /* A symlink to the regular file. */
+ assertEqualInt(AE_IFLNK, archive_entry_filetype(ae));
+ assertEqualString("file", archive_entry_symlink(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(172802, archive_entry_mtime(ae));
+ assertEqualInt(172802, archive_entry_atime(ae));
+ assertEqualInt(1, archive_entry_stat(ae)->st_nlink);
+ } else if (strcmp("./empty",
+ archive_entry_pathname(ae)) == 0) {
+ /* A empty file. */
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+ assertEqualInt(1, archive_entry_nlink(ae));
+ } else if (strcmp("./dir/file2",
+ archive_entry_pathname(ae)) == 0) {
+ /* A regular file. */
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualInt(7, archive_entry_size(ae));
+ assertEqualInt(0,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt(0, offset);
+ assertEqualMem(p, "hello2\n", 7);
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+ assertEqualInt(1, archive_entry_nlink(ae));
+ } else if (strcmp("./dir/file3",
+ archive_entry_pathname(ae)) == 0) {
+ /* A regular file. */
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualInt(7, archive_entry_size(ae));
+ assertEqualInt(0,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt(0, offset);
+ assertEqualMem(p, "hello3\n", 7);
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+ assertEqualInt(1, archive_entry_nlink(ae));
+ } else if (strcmp("./dir2/file4",
+ archive_entry_pathname(ae)) == 0) {
+ /* A regular file. */
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualInt(7, archive_entry_size(ae));
+ assertEqualInt(0,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt(0, offset);
+ assertEqualMem(p, "hello4\n", 7);
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+ assertEqualInt(1, archive_entry_nlink(ae));
+ } else {
+ failure("Saw a file that shouldn't have been there");
+ assertEqualString(archive_entry_pathname(ae), "");
+ }
+ }
+
+ /* End of archive. */
+ assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_COMPRESS);
+ assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660_ROCKRIDGE);
+
+ /* Close the archive. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+
diff --git a/libarchive/test/test_read_format_iso_xorriso.iso.Z.uu b/libarchive/test/test_read_format_iso_xorriso.iso.Z.uu
new file mode 100644
index 000000000000..b69a945017b4
--- /dev/null
+++ b/libarchive/test/test_read_format_iso_xorriso.iso.Z.uu
@@ -0,0 +1,61 @@
+begin 644 test_read_format_iso_xorriso.iso.Z
+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
+3>(F8F(F:N(F<V(F>^(F@&(HZ`0``
+`
+end
diff --git a/libarchive/test/test_read_format_isojoliet_bz2.c b/libarchive/test/test_read_format_isojoliet_bz2.c
index 80c4da20d75b..f42372675af2 100644
--- a/libarchive/test/test_read_format_isojoliet_bz2.c
+++ b/libarchive/test/test_read_format_isojoliet_bz2.c
@@ -59,14 +59,14 @@ DEFINE_TEST(test_read_format_isojoliet_bz2)
struct archive *a;
const void *p;
size_t size;
- off_t offset;
+ int64_t offset;
extract_reference_file(refname);
assert((a = archive_read_new()) != NULL);
- assertEqualInt(0, archive_read_support_compression_all(a));
+ assertEqualInt(0, archive_read_support_filter_all(a));
assertEqualInt(0, archive_read_support_format_all(a));
assertEqualInt(ARCHIVE_OK,
- archive_read_set_options(a, "iso9660:!rockridge"));
+ archive_read_set_option(a, "iso9660", "rockridge", NULL));
assertEqualInt(ARCHIVE_OK,
archive_read_open_filename(a, refname, 10240));
@@ -103,7 +103,7 @@ DEFINE_TEST(test_read_format_isojoliet_bz2)
assertEqualInt(0, archive_read_data_block(a, &p, &size, &offset));
assertEqualInt(6, (int)size);
assertEqualInt(0, offset);
- assertEqualInt(0, memcmp(p, "hello\n", 6));
+ assertEqualMem(p, "hello\n", 6);
/* Second name for the same regular file (this happens to be
* returned second, so does get marked as a hardlink). */
@@ -129,7 +129,7 @@ DEFINE_TEST(test_read_format_isojoliet_bz2)
assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_COMPRESS);
/* Close the archive. */
- assertEqualInt(0, archive_read_close(a));
- assertEqualInt(0, archive_read_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_read_format_isojoliet_long.c b/libarchive/test/test_read_format_isojoliet_long.c
index e2c986fb9077..d15face79bd5 100644
--- a/libarchive/test/test_read_format_isojoliet_long.c
+++ b/libarchive/test/test_read_format_isojoliet_long.c
@@ -64,14 +64,14 @@ DEFINE_TEST(test_read_format_isojoliet_long)
struct archive *a;
const void *p;
size_t size;
- off_t offset;
+ int64_t offset;
int i;
for (i = 0; i < 100; i++)
pathname[i] = '0' + ((i+1) % 10);
extract_reference_file(refname);
assert((a = archive_read_new()) != NULL);
- assertEqualInt(0, archive_read_support_compression_all(a));
+ assertEqualInt(0, archive_read_support_filter_all(a));
assertEqualInt(0, archive_read_support_format_all(a));
assertEqualInt(ARCHIVE_OK,
archive_read_set_options(a, "iso9660:!rockridge"));
@@ -118,7 +118,7 @@ DEFINE_TEST(test_read_format_isojoliet_long)
assertEqualInt(0, archive_read_data_block(a, &p, &size, &offset));
assertEqualInt(6, (int)size);
assertEqualInt(0, offset);
- assertEqualInt(0, memcmp(p, "hello\n", 6));
+ assertEqualMem(p, "hello\n", 6);
/* Second name for the same regular file (this happens to be
* returned second, so does get marked as a hardlink). */
@@ -135,7 +135,7 @@ DEFINE_TEST(test_read_format_isojoliet_long)
assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_COMPRESS);
/* Close the archive. */
- assertEqualInt(0, archive_read_close(a));
- assertEqualInt(0, archive_read_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_read_format_isojoliet_rr.c b/libarchive/test/test_read_format_isojoliet_rr.c
index c1806c7fcb4c..f2e0ea35f649 100644
--- a/libarchive/test/test_read_format_isojoliet_rr.c
+++ b/libarchive/test/test_read_format_isojoliet_rr.c
@@ -62,11 +62,11 @@ DEFINE_TEST(test_read_format_isojoliet_rr)
struct archive *a;
const void *p;
size_t size;
- off_t offset;
+ int64_t offset;
extract_reference_file(refname);
assert((a = archive_read_new()) != NULL);
- assertEqualInt(0, archive_read_support_compression_all(a));
+ assertEqualInt(0, archive_read_support_filter_all(a));
assertEqualInt(0, archive_read_support_format_all(a));
assertEqualInt(ARCHIVE_OK,
archive_read_open_filename(a, refname, 10240));
@@ -106,7 +106,7 @@ DEFINE_TEST(test_read_format_isojoliet_rr)
assertEqualInt(0, archive_read_data_block(a, &p, &size, &offset));
assertEqualInt(6, (int)size);
assertEqualInt(0, offset);
- assertEqualInt(0, memcmp(p, "hello\n", 6));
+ assertEqualMem(p, "hello\n", 6);
assertEqualInt(86401, archive_entry_mtime(ae));
/* mkisofs records their access time. */
/*assertEqualInt(86401, archive_entry_atime(ae));*/
@@ -154,7 +154,7 @@ DEFINE_TEST(test_read_format_isojoliet_rr)
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660_ROCKRIDGE);
/* Close the archive. */
- assertEqualInt(0, archive_read_close(a));
- assertEqualInt(0, archive_read_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_read_format_isojoliet_versioned.c b/libarchive/test/test_read_format_isojoliet_versioned.c
new file mode 100644
index 000000000000..82c5ab1f3b7b
--- /dev/null
+++ b/libarchive/test/test_read_format_isojoliet_versioned.c
@@ -0,0 +1,83 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * All rights reserved.
+ *
+ * Based on libarchive/test/test_read_format_isojoliet_bz2.c with
+ * bugs introduced by Andreas Henriksson <andreas@fatal.se> for
+ * testing ISO9660 image with Joliet extension and versioned files.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_isojoliet_bz2.c 201247 2009-12-30 05:59:21Z kientzle $");
+
+/*
+ * The data for this testcase was provided by Mike Qin <mikeandmore@gmail.com>
+ * and created with Nero.
+ */
+
+DEFINE_TEST(test_read_format_isojoliet_versioned)
+{
+ const char *refname = "test_read_format_iso_joliet_by_nero.iso.Z";
+ struct archive_entry *ae;
+ struct archive *a;
+
+ extract_reference_file(refname);
+ assert((a = archive_read_new()) != NULL);
+ assertEqualInt(0, archive_read_support_filter_all(a));
+ assertEqualInt(0, archive_read_support_format_all(a));
+ assertEqualInt(ARCHIVE_OK,
+ archive_read_set_option(a, "iso9660", "rockridge", NULL));
+ assertEqualInt(ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* First entry is '.' root directory. */
+ assertEqualInt(0, archive_read_next_header(a, &ae));
+ assertEqualString(".", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
+
+ /* A directory. */
+ assertEqualInt(0, archive_read_next_header(a, &ae));
+ assertEqualString("test", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
+
+ /* A regular file which is called test.txt and has
+ * ;1 appended to it because apparently Nero always
+ * appends versions to all files in the joliet extension.
+ *
+ * We test to make sure the version has been stripped.
+ */
+ assertEqualInt(0, archive_read_next_header(a, &ae));
+ assertEqualString("test/test.txt",
+ archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+
+ /* End of archive. */
+ assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_COMPRESS);
+
+ /* Close the archive. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
diff --git a/libarchive/test/test_read_format_isorr_bz2.c b/libarchive/test/test_read_format_isorr_bz2.c
index 45fe5f883c40..bc502e270645 100644
--- a/libarchive/test/test_read_format_isorr_bz2.c
+++ b/libarchive/test/test_read_format_isorr_bz2.c
@@ -59,12 +59,12 @@ DEFINE_TEST(test_read_format_isorr_bz2)
struct archive *a;
const void *p;
size_t size;
- off_t offset;
+ int64_t offset;
int i;
extract_reference_file(refname);
assert((a = archive_read_new()) != NULL);
- assertEqualInt(0, archive_read_support_compression_all(a));
+ assertEqualInt(0, archive_read_support_filter_all(a));
assertEqualInt(0, archive_read_support_format_all(a));
assertEqualInt(ARCHIVE_OK,
archive_read_open_filename(a, refname, 10240));
@@ -196,8 +196,8 @@ DEFINE_TEST(test_read_format_isorr_bz2)
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660_ROCKRIDGE);
/* Close the archive. */
- assertEqualInt(0, archive_read_close(a));
- assertEqualInt(0, archive_read_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_read_format_isorr_ce.c b/libarchive/test/test_read_format_isorr_ce.c
index 71bce93dfe91..d4ca160243aa 100644
--- a/libarchive/test/test_read_format_isorr_ce.c
+++ b/libarchive/test/test_read_format_isorr_ce.c
@@ -92,7 +92,7 @@ DEFINE_TEST(test_read_format_isorr_ce)
struct archive *a;
const void *p;
size_t size;
- off_t offset;
+ int64_t offset;
int i;
mkpath(path1, 151);
@@ -100,7 +100,7 @@ DEFINE_TEST(test_read_format_isorr_ce)
mkpath(path3, 153);
extract_reference_file(refname);
assert((a = archive_read_new()) != NULL);
- assertEqualInt(0, archive_read_support_compression_all(a));
+ assertEqualInt(0, archive_read_support_filter_all(a));
assertEqualInt(0, archive_read_support_format_all(a));
assertEqualInt(ARCHIVE_OK,
archive_read_open_filename(a, refname, 10240));
@@ -216,8 +216,8 @@ DEFINE_TEST(test_read_format_isorr_ce)
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660_ROCKRIDGE);
/* Close the archive. */
- assertEqualInt(0, archive_read_close(a));
- assertEqualInt(0, archive_read_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_read_format_isorr_new_bz2.c b/libarchive/test/test_read_format_isorr_new_bz2.c
index ca8a74ee8bda..997b63746335 100644
--- a/libarchive/test/test_read_format_isorr_new_bz2.c
+++ b/libarchive/test/test_read_format_isorr_new_bz2.c
@@ -60,12 +60,12 @@ DEFINE_TEST(test_read_format_isorr_new_bz2)
struct archive *a;
const void *p;
size_t size;
- off_t offset;
+ int64_t offset;
int i;
extract_reference_file(refname);
assert((a = archive_read_new()) != NULL);
- assertEqualInt(0, archive_read_support_compression_all(a));
+ assertEqualInt(0, archive_read_support_filter_all(a));
assertEqualInt(0, archive_read_support_format_all(a));
assertEqualInt(ARCHIVE_OK,
archive_read_open_filename(a, refname, 10240));
@@ -197,8 +197,8 @@ DEFINE_TEST(test_read_format_isorr_new_bz2)
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660_ROCKRIDGE);
/* Close the archive. */
- assertEqualInt(0, archive_read_close(a));
- assertEqualInt(0, archive_read_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_read_format_isorr_rr_moved.c b/libarchive/test/test_read_format_isorr_rr_moved.c
index d59b3464030d..05aa97e62df7 100644
--- a/libarchive/test/test_read_format_isorr_rr_moved.c
+++ b/libarchive/test/test_read_format_isorr_rr_moved.c
@@ -65,12 +65,12 @@ DEFINE_TEST(test_read_format_isorr_rr_moved)
struct archive *a;
const void *p;
size_t size;
- off_t offset;
+ int64_t offset;
int i;
extract_reference_file(refname);
assert((a = archive_read_new()) != NULL);
- assertEqualInt(0, archive_read_support_compression_all(a));
+ assertEqualInt(0, archive_read_support_filter_all(a));
assertEqualInt(0, archive_read_support_format_all(a));
assertEqualInt(ARCHIVE_OK,
archive_read_open_filename(a, refname, 10240));
@@ -263,8 +263,8 @@ DEFINE_TEST(test_read_format_isorr_rr_moved)
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660_ROCKRIDGE);
/* Close the archive. */
- assertEqualInt(0, archive_read_close(a));
- assertEqualInt(0, archive_read_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_read_format_isozisofs_bz2.c b/libarchive/test/test_read_format_isozisofs_bz2.c
index d4e8483bd328..60204258926b 100644
--- a/libarchive/test/test_read_format_isozisofs_bz2.c
+++ b/libarchive/test/test_read_format_isozisofs_bz2.c
@@ -58,12 +58,12 @@ DEFINE_TEST(test_read_format_isozisofs_bz2)
struct archive *a;
const void *p;
size_t size;
- off_t offset;
+ int64_t offset;
int i;
extract_reference_file(refname);
assert((a = archive_read_new()) != NULL);
- assertEqualInt(0, archive_read_support_compression_all(a));
+ assertEqualInt(0, archive_read_support_filter_all(a));
assertEqualInt(0, archive_read_support_format_all(a));
assertEqualInt(ARCHIVE_OK,
archive_read_open_filename(a, refname, 10240));
@@ -180,8 +180,8 @@ DEFINE_TEST(test_read_format_isozisofs_bz2)
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660_ROCKRIDGE);
/* Close the archive. */
- assertEqualInt(0, archive_read_close(a));
- assertEqualInt(0, archive_read_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_read_format_lha.c b/libarchive/test/test_read_format_lha.c
new file mode 100644
index 000000000000..a01386eafd0a
--- /dev/null
+++ b/libarchive/test/test_read_format_lha.c
@@ -0,0 +1,278 @@
+/*-
+ * Copyright (c) 2008, 2010 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD");
+
+/*
+Execute the following command to rebuild the data for this program:
+ tail -n +32 test_read_format_lha.c | /bin/sh
+
+#/bin/sh
+#
+# How to make test data.
+#
+# Temporary directory.
+base=/tmp/lha
+# Owner id
+owner=1001
+# Group id
+group=1001
+#
+# Make contents of a lha archive.
+#
+rm -rf ${base}
+mkdir ${base}
+mkdir ${base}/dir
+cat > ${base}/file1 << END
+ file 1 contents
+hello
+hello
+hello
+END
+cat > ${base}/file2 << END
+ file 2 contents
+hello
+hello
+hello
+hello
+hello
+hello
+END
+mkdir ${base}/dir2
+#
+# Set up a file mode, owner and group.
+#
+(cd ${base}/dir2; ln -s ../file1 symlink1)
+(cd ${base}/dir2; ln -s ../file2 symlink2)
+(cd ${base}; chown ${owner}:${group} dir file1 file2)
+(cd ${base}; chown -h ${owner}:${group} dir2 dir2/symlink1 dir2/symlink2)
+(cd ${base}; chmod 0750 dir)
+(cd ${base}; chmod 0755 dir2)
+(cd ${base}; chmod 0755 dir2/symlink1 dir2/symlink2)
+(cd ${base}; chmod 0644 file1)
+(cd ${base}; chmod 0666 file2)
+TZ=utc touch -afhm -t 197001030000.02 ${base}/dir2/symlink1 ${base}/dir2/symlink2
+TZ=utc touch -afhm -t 197001020000.01 ${base}/dir ${base}/dir2
+TZ=utc touch -afhm -t 197001020000.01 ${base}/file1 ${base}/file2
+#
+# Make several lha archives.
+#
+# Make a lha archive with header level 0
+lha0=test_read_format_lha_header0.lzh
+(cd ${base}; lha c0q ${lha0} dir file1 file2 dir2)
+# Make a lha archive with header level 1
+lha1=test_read_format_lha_header1.lzh
+(cd ${base}; lha c1q ${lha1} dir file1 file2 dir2)
+# Make a lha archive with header level 2
+lha2=test_read_format_lha_header2.lzh
+(cd ${base}; lha c2q ${lha2} dir file1 file2 dir2)
+# Make a lha archive with -lh6- compression mode
+lha3=test_read_format_lha_lh6.lzh
+(cd ${base}; lha co6q ${lha3} dir file1 file2 dir2)
+# Make a lha archive with -lh7- compression mode
+lha4=test_read_format_lha_lh7.lzh
+(cd ${base}; lha co7q ${lha4} dir file1 file2 dir2)
+# Make a lha archive with -lh0- no compression
+lha5=test_read_format_lha_lh0.lzh
+(cd ${base}; lha czq ${lha5} dir file1 file2 dir2)
+# make a lha archive with junk data
+lha6=test_read_format_lha_withjunk.lzh
+(cd ${base}; cp ${lha2} ${lha6}; echo "junk data!!!!" >> ${lha6})
+#
+uuencode ${base}/${lha0} ${lha0} > ${lha0}.uu
+uuencode ${base}/${lha1} ${lha1} > ${lha1}.uu
+uuencode ${base}/${lha2} ${lha2} > ${lha2}.uu
+uuencode ${base}/${lha3} ${lha3} > ${lha3}.uu
+uuencode ${base}/${lha4} ${lha4} > ${lha4}.uu
+uuencode ${base}/${lha5} ${lha5} > ${lha5}.uu
+uuencode ${base}/${lha6} ${lha5} > ${lha5}.uu
+uuencode ${base}/${lha6} ${lha6} > ${lha6}.uu
+#
+# Finish making test data.
+exit 1
+*/
+
+static const char file1[] = {
+" file 1 contents\n"
+"hello\n"
+"hello\n"
+"hello\n"
+};
+#define file1_size (sizeof(file1)-1)
+static const char file2[] = {
+" file 2 contents\n"
+"hello\n"
+"hello\n"
+"hello\n"
+"hello\n"
+"hello\n"
+"hello\n"
+};
+#define file2_size (sizeof(file2)-1)
+
+static void
+verify(const char *refname, int posix)
+{
+ struct archive_entry *ae;
+ struct archive *a;
+ char buff[128];
+ const void *pv;
+ size_t s;
+ int64_t o;
+ int uid, gid;
+
+ if (posix)
+ uid = gid = 1001;
+ else
+ uid = gid = 0;
+
+ extract_reference_file(refname);
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify directory1. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ if (posix)
+ assertEqualInt((AE_IFDIR | 0750), archive_entry_mode(ae));
+ else
+ assertEqualInt((AE_IFDIR | 0755), archive_entry_mode(ae));
+ assertEqualString("dir/", archive_entry_pathname(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(uid, archive_entry_uid(ae));
+ assertEqualInt(gid, archive_entry_gid(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualIntA(a, ARCHIVE_EOF,
+ archive_read_data_block(a, &pv, &s, &o));
+ assertEqualInt(s, 0);
+
+ /* Verify directory2. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFDIR | 0755), archive_entry_mode(ae));
+ assertEqualString("dir2/", archive_entry_pathname(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(uid, archive_entry_uid(ae));
+ assertEqualInt(gid, archive_entry_gid(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualIntA(a, ARCHIVE_EOF,
+ archive_read_data_block(a, &pv, &s, &o));
+ assertEqualInt(s, 0);
+
+ if (posix) {
+ /* Verify symbolic link file1. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFLNK | 0755), archive_entry_mode(ae));
+ assertEqualString("dir2/symlink1", archive_entry_pathname(ae));
+ assertEqualString("../file1", archive_entry_symlink(ae));
+ assertEqualInt(172802, archive_entry_mtime(ae));
+ assertEqualInt(uid, archive_entry_uid(ae));
+ assertEqualInt(gid, archive_entry_gid(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+
+ /* Verify symbolic link file2. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFLNK | 0755), archive_entry_mode(ae));
+ assertEqualString("dir2/symlink2", archive_entry_pathname(ae));
+ assertEqualString("../file2", archive_entry_symlink(ae));
+ assertEqualInt(172802, archive_entry_mtime(ae));
+ assertEqualInt(uid, archive_entry_uid(ae));
+ assertEqualInt(gid, archive_entry_gid(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ }
+
+ /* Verify regular file1. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
+ assertEqualString("file1", archive_entry_pathname(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(uid, archive_entry_uid(ae));
+ assertEqualInt(gid, archive_entry_gid(ae));
+ assertEqualInt(file1_size, archive_entry_size(ae));
+ assertEqualInt(file1_size, archive_read_data(a, buff, file1_size));
+ assertEqualMem(buff, file1, file1_size);
+
+ /* Verify regular file2. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ if (posix)
+ assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae));
+ else
+ assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
+ assertEqualString("file2", archive_entry_pathname(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(uid, archive_entry_uid(ae));
+ assertEqualInt(gid, archive_entry_gid(ae));
+ assertEqualInt(file2_size, archive_entry_size(ae));
+ assertEqualInt(file2_size, archive_read_data(a, buff, file2_size));
+ assertEqualMem(buff, file2, file2_size);
+
+ /* Verify the number of files read. */
+ if (posix) {
+ assertEqualInt(6, archive_file_count(a));
+ } else {
+ assertEqualInt(4, archive_file_count(a));
+ }
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify the number of files read. */
+ if (posix) {
+ assertEqualInt(6, archive_file_count(a));
+ } else {
+ assertEqualInt(4, archive_file_count(a));
+ }
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_LHA, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+DEFINE_TEST(test_read_format_lha)
+{
+ /* Verify Header level 0 */
+ verify("test_read_format_lha_header0.lzh", 1);
+ /* Verify Header level 1 */
+ verify("test_read_format_lha_header1.lzh", 1);
+ /* Verify Header level 2 */
+ verify("test_read_format_lha_header2.lzh", 1);
+ /* Verify Header level 3
+ * This test data can be made in Windows only. */
+ verify("test_read_format_lha_header3.lzh", 0);
+ /* Verify compression mode -lh6- */
+ verify("test_read_format_lha_lh6.lzh", 1);
+ /* Verify compression mode -lh7- */
+ verify("test_read_format_lha_lh7.lzh", 1);
+ /* Verify no compression -lh0- */
+ verify("test_read_format_lha_lh0.lzh", 1);
+ /* Verify an lha file with junk data. */
+ verify("test_read_format_lha_withjunk.lzh", 1);
+}
+
diff --git a/libarchive/test/test_read_format_lha_filename.c b/libarchive/test/test_read_format_lha_filename.c
new file mode 100644
index 000000000000..e39dfac41ac1
--- /dev/null
+++ b/libarchive/test/test_read_format_lha_filename.c
@@ -0,0 +1,218 @@
+/*-
+ * Copyright (c) 2011 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD");
+
+#include <locale.h>
+
+static void
+test_read_format_lha_filename_CP932_eucJP(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read LHA filename in ja_JP.eucJP.
+ */
+ if (NULL == setlocale(LC_ALL, "ja_JP.eucJP")) {
+ skipping("ja_JP.eucJP locale not available on this system.");
+ return;
+ }
+
+ /*
+ * Create a read object only for a test that platform support
+ * a character-set conversion because we can read a character-set
+ * of filenames from the header of an lha archive file and so we
+ * want to test that it works well.
+ */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP932")) {
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+ skipping("This system cannot convert character-set"
+ " from CP932 to eucJP.");
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xB4\xC1\xBB\xFA\x2E\x74\x78\x74",
+ archive_entry_pathname(ae));
+ assertEqualInt(8, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xC9\xBD\x2E\x74\x78\x74", archive_entry_pathname(ae));
+ assertEqualInt(4, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_LHA, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_lha_filename_CP932_UTF8(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read LHA filename in en_US.UTF-8.
+ */
+ if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
+ skipping("en_US.UTF-8 locale not available on this system.");
+ return;
+ }
+ /*
+ * Create a read object only for a test that platform support
+ * a character-set conversion because we can read a character-set
+ * of filenames from the header of an lha archive file and so we
+ * want to test that it works well.
+ */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP932")) {
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+ skipping("This system cannot convert character-set"
+ " from CP932 to UTF-8.");
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xE6\xBC\xA2\xE5\xAD\x97\x2E\x74\x78\x74",
+ archive_entry_pathname(ae));
+ assertEqualInt(8, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xE8\xA1\xA8\x2E\x74\x78\x74",
+ archive_entry_pathname(ae));
+ assertEqualInt(4, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_LHA, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+static void
+test_read_format_lha_filename_CP932_Windows(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read LHA filename in jpn on Windows.
+ */
+ if (NULL == setlocale(LC_ALL, "jpn")) {
+ skipping("jpn locale not available on this system.");
+ return;
+ }
+ /*
+ * Create a read object only for a test that platform support
+ * a character-set conversion because we can read a character-set
+ * of filenames from the header of an lha archive file and so we
+ * want to test that it works well.
+ */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\x8A\xBF\x8E\x9A\x2E\x74\x78\x74",
+ archive_entry_pathname(ae));
+ assertEqualInt(8, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\x95\x5C\x2E\x74\x78\x74", archive_entry_pathname(ae));
+ assertEqualInt(4, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_LHA, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+#else
+/* Stub */
+static void
+test_read_format_lha_filename_CP932_Windows(const char *refname)
+{
+ (void)refname; /* UNUSED */
+}
+#endif
+
+DEFINE_TEST(test_read_format_lha_filename)
+{
+ /* A sample file was created with LHA32.EXE through UNLHA.DLL. */
+ const char *refname = "test_read_format_lha_filename_cp932.lzh";
+
+ extract_reference_file(refname);
+
+ test_read_format_lha_filename_CP932_eucJP(refname);
+ test_read_format_lha_filename_CP932_UTF8(refname);
+ test_read_format_lha_filename_CP932_Windows(refname);
+}
diff --git a/libarchive/test/test_read_format_lha_filename_cp932.lzh.uu b/libarchive/test/test_read_format_lha_filename_cp932.lzh.uu
new file mode 100644
index 000000000000..15170146083e
--- /dev/null
+++ b/libarchive/test/test_read_format_lha_filename_cp932.lzh.uu
@@ -0,0 +1,7 @@
+begin 644 test_read_format_lha_cp932.lzh
+M30`M;&@P+0@````(````*:2#32`"&4A-!P!&I`,```L``8J_CIHN='AT&P!!
+M-'"`))KERP%TJNDQFN7+`72JZ3&:Y<L!!@``T2,'``"*OXZ:@JF"R$L`+6QH
+M,"T$````!````#RD@TT@`NA;30<`1J0#```)``&57"YT>'0;`$&:91,VFN7+
+>`:#K$3V:Y<L!H.L1/9KERP$&``#L+0<``&QI<W0`
+`
+end
diff --git a/libarchive/test/test_read_format_lha_header0.lzh.uu b/libarchive/test/test_read_format_lha_header0.lzh.uu
new file mode 100644
index 000000000000..8fa8b92480d1
--- /dev/null
+++ b/libarchive/test/test_read_format_lha_header0.lzh.uu
@@ -0,0 +1,11 @@
+begin 644 test_read_format_lha_header0.lzh
+M)L`M;&AD+0```````````$@B[!``!&1I<EP``%4`@5$!`.A!Z0/I`R?X+6QH
+M9"T```````````!((NP0``5D:7(R7```50"!40$`[4'I`^D#.'PM;&AD+0``
+M`````````4@C[!``%F1I<C)<<WEM;&EN:S%\+BY<9FEL93$``%4``J,"`.VA
+MZ0/I`SA^+6QH9"T```````````%((^P0`!9D:7(R7'-Y;6QI;FLR?"XN7&9I
+M;&4R``!5``*C`@#MH>D#Z0,GO2UL:#4M(@```#P`````2"+L(``%9FEL93&D
+MYU4`@5$!`*2!Z0/I`P`80FYIQ>/Z`=-:'>9%#"P%J!\CH0"/GE$,.W6FMSD%
+M*_4G02UL:#4M(@```$X`````2"+L(``%9FEL93+5%54`@5$!`+:!Z0/I`P`8
+A0FYIQV/Z`=.:'.9%#"P%J-\+H0"/'E$,.W6FMSD%*_T`
+`
+end
diff --git a/libarchive/test/test_read_format_lha_header1.lzh.uu b/libarchive/test/test_read_format_lha_header1.lzh.uu
new file mode 100644
index 000000000000..303c9bbb24ae
--- /dev/null
+++ b/libarchive/test/test_read_format_lha_header1.lzh.uu
@@ -0,0 +1,13 @@
+begin 644 test_read_format_lha_header1.lzh
+M&7\M;&AD+1H``````````$@B["`!````50<``F1I<O\%`%#H00<`4>D#Z0,'
+M`%2!40$````9@2UL:&0M&P``````````2"+L(`$```!5"``"9&ER,O\%`%#M
+M00<`4>D#Z0,'`%2!40$````><2UL:&0M)P`````````!2"/L(`$%9FEL93$`
+M`%44``)D:7(R_W-Y;6QI;FLQ?"XN_P4`4.VA!P!1Z0/I`P<`5`*C`@```!YR
+M+6QH9"TG``````````%((^P@`05F:6QE,@``510``F1I<C+_<WEM;&EN:S)\
+M+B[_!0!0[:$'`%'I`^D#!P!4`J,"````'@8M;&@U+34````\`````$@B["`!
+M!69I;&4QI.=5!0!0I($'`%'I`^D#!P!4@5$!`````!A";FG%X_H!TUH=YD4,
+M+`6H'R.A`(^>40P[=::W.04K]1YX+6QH-2TU````3@````!((NP@`05F:6QE
+M,M45504`4+:!!P!1Z0/I`P<`5(%1`0`````80FYIQV/Z`=.:'.9%#"P%J-\+
+/H0"/'E$,.W6FMSD%*_T`
+`
+end
diff --git a/libarchive/test/test_read_format_lha_header2.lzh.uu b/libarchive/test/test_read_format_lha_header2.lzh.uu
new file mode 100644
index 000000000000..d5d7591f1c58
--- /dev/null
+++ b/libarchive/test/test_read_format_lha_header2.lzh.uu
@@ -0,0 +1,13 @@
+begin 644 test_read_format_lha_header2.lzh
+M-0`M;&AD+0``````````@5$!`"`"``!5!0``!=X#``$'``)D:7+_!0!0Z$$'
+M`%'I`^D#```V`"UL:&0M``````````"!40$`(`(``%4%```(F0,``0@``F1I
+M<C+_!0!0[4$'`%'I`^D#``!'`"UL:&0M```````````"HP(`(`(``%4%``"T
+MJ0@``69I;&4Q%``"9&ER,O]S>6UL:6YK,7PN+O\%`%#MH0<`4>D#Z0,``$<`
+M+6QH9"T```````````*C`@`@`@``504``(?M"``!9FEL93(4``)D:7(R_W-Y
+M;6QI;FLR?"XN_P4`4.VA!P!1Z0/I`P``,P`M;&@U+2(````\````@5$!`"`"
+MI.=5!0``_0$(``%F:6QE,04`4*2!!P!1Z0/I`P```!A";FG%X_H!TUH=YD4,
+M+`6H'R.A`(^>40P[=::W.04K]3,`+6QH-2TB````3@```(%1`0`@`M45504`
+M`"_&"``!9FEL93(%`%"V@0<`4>D#Z0,````80FYIQV/Z`=.:'.9%#"P%J-\+
+/H0"/'E$,.W6FMSD%*_T`
+`
+end
diff --git a/libarchive/test/test_read_format_lha_header3.lzh.uu b/libarchive/test/test_read_format_lha_header3.lzh.uu
new file mode 100644
index 000000000000..e6128264a715
--- /dev/null
+++ b/libarchive/test/test_read_format_lha_header3.lzh.uu
@@ -0,0 +1,16 @@
+begin 644 test_read_format_lha_header3.lzh
+M!``M;&AD+0``````````@5$!`"`#``!-?`````D```!&I`,```4````!"0``
+M``)D:7+_!P```$`0`!D```#_[4$`````````````#!7^3$0:_DP=````0<S?
+M4;3^E<L!@-9``*BRG0$`>@_0`9;+`0@`````+J\'``````0`+6QH9"T`````
+M`````(%1`0`@`P``37T````)````1J0#```%`````0H````"9&ER,O\'````
+M0!``&0```/_M00`````````````A&OY,1!K^3!T```!!2H%NNP&6RP&`UD``
+MJ+*=`0!Z#]`!ELL!"`````!]%P<`````!``M;&@U+20````\````@5$!`"`#
+MI.=-<0````D```!&I`,```H````!9FEL93$9````_Z2!`````````````,<4
+M_DPC&OY,'0```$$T0J**_I7+`8#60`"HLIT!_G*DO`&6RP$(``````KQ!P``
+M````&4)MD:BT=H!Z:T.IZ9#S:`ZH%CJ$`A]OC1DU4VION(3=>H`$`"UL:#4M
+M)````$X```"!40$`(`/5%4UQ````"0```$:D`P``"@````%F:6QE,AD```#_
+MI($`````````````(1K^3",:_DP=````0?Y%<[L!ELL!@-9``*BRG0%8U::\
+M`9;+`0@`````0=X'```````90FV1J.QV@'IS0XGID/-H#JC&&H0"'F^-&353
+(:F^XA-U^@```
+`
+end
diff --git a/libarchive/test/test_read_format_lha_lh0.lzh.uu b/libarchive/test/test_read_format_lha_lh0.lzh.uu
new file mode 100644
index 000000000000..fff88c7ad7e9
--- /dev/null
+++ b/libarchive/test/test_read_format_lha_lh0.lzh.uu
@@ -0,0 +1,13 @@
+begin 644 test_read_format_lha_lh0.lzh
+M-0`M;&AD+0``````````@5$!`"`"``!5!0``!=X#``$'``)D:7+_!0!0Z$$'
+M`%'I`^D#```V`"UL:&0M``````````"!40$`(`(``%4%```(F0,``0@``F1I
+M<C+_!0!0[4$'`%'I`^D#``!'`"UL:&0M```````````"HP(`(`(``%4%``"T
+MJ0@``69I;&4Q%``"9&ER,O]S>6UL:6YK,7PN+O\%`%#MH0<`4>D#Z0,``$<`
+M+6QH9"T```````````*C`@`@`@``504``(?M"``!9FEL93(4``)D:7(R_W-Y
+M;6QI;FLR?"XN_P4`4.VA!P!1Z0/I`P``,P`M;&@U+2(````\````@5$!`"`"
+MI.=5!0``_0$(``%F:6QE,04`4*2!!P!1Z0/I`P```!A";FG%X_H!TUH=YD4,
+M+`6H'R.A`(^>40P[=::W.04K]3,`+6QH-2TB````3@```(%1`0`@`M45504`
+M`"_&"``!9FEL93(%`%"V@0<`4>D#Z0,````80FYIQV/Z`=.:'.9%#"P%J-\+
+=H0"/'E$,.W6FMSD%*_T`:G5N:R!D871A(2$A(0H`
+`
+end
diff --git a/libarchive/test/test_read_format_lha_lh6.lzh.uu b/libarchive/test/test_read_format_lha_lh6.lzh.uu
new file mode 100644
index 000000000000..22ad4ac70bc9
--- /dev/null
+++ b/libarchive/test/test_read_format_lha_lh6.lzh.uu
@@ -0,0 +1,13 @@
+begin 644 test_read_format_lha_lh6.lzh
+M-0`M;&AD+0``````````@5$!`"`"``!5!0``!=X#``$'``)D:7+_!0!0Z$$'
+M`%'I`^D#```V`"UL:&0M``````````"!40$`(`(``%4%```(F0,``0@``F1I
+M<C+_!0!0[4$'`%'I`^D#``!'`"UL:&0M```````````"HP(`(`(``%4%``"T
+MJ0@``69I;&4Q%``"9&ER,O]S>6UL:6YK,7PN+O\%`%#MH0<`4>D#Z0,``$<`
+M+6QH9"T```````````*C`@`@`@``504``(?M"``!9FEL93(4``)D:7(R_W-Y
+M;6QI;FLR?"XN_P4`4.VA!P!1Z0/I`P``,P`M;&@V+2,````\````@5$!`"`"
+MI.=5!0``C24(``%F:6QE,04`4*2!!P!1Z0/I`P```!A";FG%X_H!TUH=YD4,
+M+`6H'R.0@$?/*(8=NM-;G(*5^H`S`"UL:#8M(P```$X```"!40$`(`+5%54%
+M``!?X@@``69I;&4R!0!0MH$'`%'I`^D#````&$)N:<=C^@'3FASF10PL!:C?
+1"Y"`1X\HAAVZTUN<@I7^@```
+`
+end
diff --git a/libarchive/test/test_read_format_lha_lh7.lzh.uu b/libarchive/test/test_read_format_lha_lh7.lzh.uu
new file mode 100644
index 000000000000..1eaf55cb13bc
--- /dev/null
+++ b/libarchive/test/test_read_format_lha_lh7.lzh.uu
@@ -0,0 +1,13 @@
+begin 644 test_read_format_lha_lh7.lzh
+M-0`M;&AD+0``````````@5$!`"`"``!5!0``!=X#``$'``)D:7+_!0!0Z$$'
+M`%'I`^D#```V`"UL:&0M``````````"!40$`(`(``%4%```(F0,``0@``F1I
+M<C+_!0!0[4$'`%'I`^D#``!'`"UL:&0M```````````"HP(`(`(``%4%``"T
+MJ0@``69I;&4Q%``"9&ER,O]S>6UL:6YK,7PN+O\%`%#MH0<`4>D#Z0,``$<`
+M+6QH9"T```````````*C`@`@`@``504``(?M"``!9FEL93(4``)D:7(R_W-Y
+M;6QI;FLR?"XN_P4`4.VA!P!1Z0/I`P``,P`M;&@W+2,````\````@5$!`"`"
+MI.=5!0``'(D(``%F:6QE,04`4*2!!P!1Z0/I`P```!A";FG%X_H!TUH=YD4,
+M+`6H'R.0@$?/*(8=NM-;G(*5^H`S`"UL:#<M(P```$X```"!40$`(`+5%54%
+M``#.3@@``69I;&4R!0!0MH$'`%'I`^D#````&$)N:<=C^@'3FASF10PL!:C?
+1"Y"`1X\HAAVZTUN<@I7^@```
+`
+end
diff --git a/libarchive/test/test_read_format_lha_withjunk.lzh.uu b/libarchive/test/test_read_format_lha_withjunk.lzh.uu
new file mode 100644
index 000000000000..5e7c6179f963
--- /dev/null
+++ b/libarchive/test/test_read_format_lha_withjunk.lzh.uu
@@ -0,0 +1,13 @@
+begin 644 test_read_format_lha_withjunk.lzh
+M-0`M;&AD+0``````````@5$!`"`"``!5!0``!=X#``$'``)D:7+_!0!0Z$$'
+M`%'I`^D#```V`"UL:&0M``````````"!40$`(`(``%4%```(F0,``0@``F1I
+M<C+_!0!0[4$'`%'I`^D#``!'`"UL:&0M```````````"HP(`(`(``%4%``"T
+MJ0@``69I;&4Q%``"9&ER,O]S>6UL:6YK,7PN+O\%`%#MH0<`4>D#Z0,``$<`
+M+6QH9"T```````````*C`@`@`@``504``(?M"``!9FEL93(4``)D:7(R_W-Y
+M;6QI;FLR?"XN_P4`4.VA!P!1Z0/I`P``,P`M;&@U+2(````\````@5$!`"`"
+MI.=5!0``_0$(``%F:6QE,04`4*2!!P!1Z0/I`P```!A";FG%X_H!TUH=YD4,
+M+`6H'R.A`(^>40P[=::W.04K]3,`+6QH-2TB````3@```(%1`0`@`M45504`
+M`"_&"``!9FEL93(%`%"V@0<`4>D#Z0,````80FYIQV/Z`=.:'.9%#"P%J-\+
+=H0"/'E$,.W6FMSD%*_T`:G5N:R!D871A(2$A(0H`
+`
+end
diff --git a/libarchive/test/test_read_format_mtree.c b/libarchive/test/test_read_format_mtree.c
index e6462819134d..1e5e585e742e 100644
--- a/libarchive/test/test_read_format_mtree.c
+++ b/libarchive/test/test_read_format_mtree.c
@@ -33,6 +33,11 @@ test_read_format_mtree1(void)
struct archive_entry *ae;
struct archive *a;
FILE *f;
+ /* Compute max 64-bit signed twos-complement value
+ * without relying on overflow. This assumes that long long
+ * is at least 64 bits. */
+ const static long long max_int64 = ((((long long)1) << 62) - 1) + (((long long)1) << 62);
+ time_t min_time, t;
extract_reference_file(reffile);
@@ -47,7 +52,7 @@ test_read_format_mtree1(void)
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK,
- archive_read_support_compression_all(a));
+ archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_file(a, reffile, 11));
@@ -104,9 +109,48 @@ test_read_format_mtree1(void)
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualString(archive_entry_pathname(ae), "notindir");
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(archive_entry_pathname(ae), "dir2/emptyfile");
+ assertEqualInt(archive_entry_size(ae), 0);
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(archive_entry_pathname(ae), "dir2/smallfile");
+ assertEqualInt(archive_entry_size(ae), 1);
+
+ /* TODO: Mtree reader should probably return ARCHIVE_WARN for this. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(archive_entry_pathname(ae), "dir2/toosmallfile");
+ assertEqualInt(archive_entry_size(ae), -1);
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(archive_entry_pathname(ae), "dir2/bigfile");
+ assertEqualInt(archive_entry_size(ae), max_int64);
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(archive_entry_pathname(ae), "dir2/toobigfile");
+ /* Size in mtree is max_int64 + 1; should return max_int64. */
+ assertEqualInt(archive_entry_size(ae), max_int64);
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(archive_entry_pathname(ae), "dir2/veryoldfile");
+ /* The value in the file is MIN_INT64_T, but time_t may be narrower. */
+ /* Verify min_time is the smallest possible time_t. */
+ min_time = archive_entry_mtime(ae);
+ assert(min_time <= 0);
+ /* Simply asserting min_time - 1 > 0 breaks with some compiler optimizations. */
+ t = min_time - 1;
+ assert(t > 0);
+
+ /* toooldfile is 1 sec older, which should overflow and get returned
+ * with the same value. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(archive_entry_pathname(ae), "dir2/toooldfile");
+ assertEqualInt(archive_entry_mtime(ae), min_time);
+
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+ assertEqualInt(19, archive_file_count(a));
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
static void
@@ -120,7 +164,7 @@ test_read_format_mtree2(void)
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK,
- archive_read_support_compression_all(a));
+ archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK,
@@ -130,8 +174,9 @@ test_read_format_mtree2(void)
assertEqualString(archive_entry_pathname(ae), "d");
assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+ assertEqualInt(1, archive_file_count(a));
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
/*
@@ -154,7 +199,7 @@ test_read_format_mtree3(void)
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK,
- archive_read_support_compression_all(a));
+ archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK,
@@ -170,17 +215,135 @@ test_read_format_mtree3(void)
assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+ assertEqualInt(3, archive_file_count(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+ assertChdir("..");
+}
+
+
+static void
+test_read_format_mtree4(void)
+{
+ const char reffile[] = "test_read_format_mtree_nomagic.mtree";
+ char buff[16];
+ struct archive_entry *ae;
+ struct archive *a;
+ FILE *f;
+
+ assertMakeDir("mtree4", 0777);
+ assertChdir("mtree4");
+
+ extract_reference_file(reffile);
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_file(a, reffile, 11));
+
+ /*
+ * Read "file", whose data is available on disk.
+ */
+ f = fopen("file", "wb");
+ assert(f != NULL);
+ assertEqualInt(3, fwrite("hi\n", 1, 3, f));
+ fclose(f);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(archive_format(a), ARCHIVE_FORMAT_MTREE);
+ assertEqualString(archive_entry_pathname(ae), "file");
+ assertEqualInt(archive_entry_uid(ae), 18);
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0123);
+ assertEqualInt(archive_entry_size(ae), 3);
+ assertEqualInt(3, archive_read_data(a, buff, 3));
+ assertEqualMem(buff, "hi\n", 3);
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(archive_entry_pathname(ae), "dir");
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(archive_entry_pathname(ae), "dir/file with space");
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(archive_entry_pathname(ae), "file with space");
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(archive_entry_pathname(ae), "dir2");
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(archive_entry_pathname(ae), "dir2/dir3a");
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(archive_entry_pathname(ae), "dir2/dir3a/indir3a");
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(archive_entry_pathname(ae), "dir2/fullindir2");
+ assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(archive_entry_pathname(ae), "dir2/indir2");
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(archive_entry_pathname(ae), "dir2/dir3b");
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(archive_entry_pathname(ae), "dir2/dir3b/indir3b");
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(archive_entry_pathname(ae), "notindir");
+
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+ assertEqualInt(12, archive_file_count(a));
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
assertChdir("..");
}
+/*
+ * We should get a warning if the contents file doesn't exist.
+ */
+static void
+test_read_format_mtree5(void)
+{
+ static char archive[] =
+ "#mtree\n"
+ "a type=file contents=nonexistent_file\n";
+ struct archive_entry *ae;
+ struct archive *a;
+
+ assertMakeDir("mtree5", 0777);
+ assertChdir("mtree5");
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_memory(a, archive, sizeof(archive)));
+ assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae));
+ assert(strlen(archive_error_string(a)) > 0);
+ assertEqualString(archive_entry_pathname(ae), "a");
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+ assertEqualInt(1, archive_file_count(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+ assertChdir("..");
+}
DEFINE_TEST(test_read_format_mtree)
{
test_read_format_mtree1();
test_read_format_mtree2();
test_read_format_mtree3();
+ test_read_format_mtree4();
+ test_read_format_mtree5();
}
diff --git a/libarchive/test/test_read_format_mtree.mtree.uu b/libarchive/test/test_read_format_mtree.mtree.uu
index 1634d0015f51..a0dff18e442e 100644
--- a/libarchive/test/test_read_format_mtree.mtree.uu
+++ b/libarchive/test/test_read_format_mtree.mtree.uu
@@ -1,5 +1,3 @@
-$FreeBSD: head/lib/libarchive/test/test_read_format_mtree.mtree.uu 201247 2009-12-30 05:59:21Z kientzle $
-
begin 644 test_read_format_mtree.mtree
M(VUT<F5E"F9I;&4@='EP93UF:6QE('5I9#TQ."!M;V1E/3`Q,C,@<VEZ93TS
M"F1I<B!T>7!E/61I<@H@9FEL95PP-#!W:71H7#`T,'-P86-E('1Y<&4]9FEL
@@ -8,6 +6,13 @@ M9&ER,B!T>7!E/61I<@H@9&ER,V$@='EP93UD:7(*("!I;F1I<C-A('1Y<&4]
M9FEL90ID:7(R+V9U;&QI;F1I<C(@='EP93UF:6QE(&UO9&4],#<W-PH@("XN
M"B!I;F1I<C(@='EP93UF:6QE"B!D:7(S8B!T>7!E/61I<@H@(&EN9&ER,V(@
M='EP93UF:6QE"B`@+BX*("XN"FYO=&EN9&ER('1Y<&4]9FEL90ID:7(R+V9U
-3;&QI;F1I<C(@;6]D93TP-C0T"@``
+M;&QI;F1I<C(@;6]D93TP-C0T"F1I<C(O96UP='EF:6QE('1Y<&4]9FEL92!S
+M:7IE/3!X,`ID:7(R+W-M86QL9FEL92!T>7!E/69I;&4@<VEZ93TP,#`P,#`P
+M,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#$*9&ER,B]T;V]S;6%L;&9I;&4@='EP
+M93UF:6QE('-I>F4]+3$*9&ER,B]B:6=F:6QE('1Y<&4]9FEL92!S:7IE/3DR
+M,C,S-S(P,S8X-30W-S4X,#<*9&ER,B]T;V]B:6=F:6QE('1Y<&4]9FEL92!S
+M:7IE/3DR,C,S-S(P,S8X-30W-S4X,#@*9&ER,B]V97)Y;VQD9FEL92!T>7!E
+M/69I;&4@=&EM93TM.3(R,S,W,C`S-C@U-#<W-3@P.`ID:7(R+W1O;V]L9&9I
+H;&4@='EP93UF:6QE('1I;64]+3DR,C,S-S(P,S8X-30W-S4X,#D*"@``
`
end
diff --git a/libarchive/test/test_read_format_mtree_nomagic.mtree.uu b/libarchive/test/test_read_format_mtree_nomagic.mtree.uu
new file mode 100644
index 000000000000..be089103dae1
--- /dev/null
+++ b/libarchive/test/test_read_format_mtree_nomagic.mtree.uu
@@ -0,0 +1,11 @@
+begin 644 test_read_format_mtree_nomagic.mtree
+M9FEL92!T>7!E/69I;&4@=6ED/3$X(&UO9&4],#$R,R!S:7IE/3,*9&ER('1Y
+M<&4]9&ER"B!F:6QE7#`T,'=I=&A<,#0P<W!A8V4@='EP93UF:6QE('5I9#TQ
+M.`H@+BX*9FEL95PP-#!W:71H7#`T,'-P86-E('1Y<&4]9FEL90ID:7(R('1Y
+M<&4]9&ER"B!D:7(S82!T>7!E/61I<@H@(&EN9&ER,V$@='EP93UF:6QE"F1I
+M<C(O9G5L;&EN9&ER,B!T>7!E/69I;&4@;6]D93TP-S<W"B`@+BX*(&EN9&ER
+M,B!T>7!E/69I;&4*(&1I<C-B('1Y<&4]9&ER"B`@:6YD:7(S8B!T>7!E/69I
+M;&4*("`N+@H@+BX*;F]T:6YD:7(@='EP93UF:6QE"F1I<C(O9G5L;&EN9&ER
+,,B!M;V1E/3`V-#0*
+`
+end
diff --git a/libarchive/test/test_read_format_pax_bz2.c b/libarchive/test/test_read_format_pax_bz2.c
index af70b3663085..826f878dbb40 100644
--- a/libarchive/test/test_read_format_pax_bz2.c
+++ b/libarchive/test/test_read_format_pax_bz2.c
@@ -47,7 +47,7 @@ DEFINE_TEST(test_read_format_pax_bz2)
int r;
assert((a = archive_read_new()) != NULL);
- r = archive_read_support_compression_bzip2(a);
+ r = archive_read_support_filter_bzip2(a);
if (r != ARCHIVE_OK) {
archive_read_close(a);
skipping("Bzip2 unavailable");
@@ -57,10 +57,11 @@ DEFINE_TEST(test_read_format_pax_bz2)
assertEqualIntA(a,ARCHIVE_OK,
archive_read_open_memory(a, archive, sizeof(archive)));
assertEqualIntA(a,ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(1, archive_file_count(a));
assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_BZIP2);
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE);
assertEqualIntA(a,ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_read_format_rar.c b/libarchive/test/test_read_format_rar.c
new file mode 100644
index 000000000000..8a73a78e5a09
--- /dev/null
+++ b/libarchive/test/test_read_format_rar.c
@@ -0,0 +1,867 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2011 Andres Mejia
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+
+#include <locale.h>
+
+static void
+test_basic(void)
+{
+ char buff[64];
+ const char reffile[] = "test_read_format_rar.rar";
+ const char test_txt[] = "test text document\r\n";
+ int size = sizeof(test_txt)-1;
+ struct archive_entry *ae;
+ struct archive *a;
+
+ extract_reference_file(reffile);
+ assert((a = archive_read_new()) != NULL);
+ assertA(0 == archive_read_support_filter_all(a));
+ assertA(0 == archive_read_support_format_all(a));
+ assertA(0 == archive_read_open_file(a, reffile, 10240));
+
+ /* First header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("test.txt", archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertA((int)archive_entry_ctime(ae));
+ assertA((int)archive_entry_atime(ae));
+ assertEqualInt(20, archive_entry_size(ae));
+ assertEqualInt(33188, archive_entry_mode(ae));
+ assertA(size == archive_read_data(a, buff, size));
+ assertEqualMem(buff, test_txt, size);
+
+ /* Second header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("testlink", archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertA((int)archive_entry_ctime(ae));
+ assertA((int)archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(41471, archive_entry_mode(ae));
+ assertEqualString("test.txt", archive_entry_symlink(ae));
+ assertEqualIntA(a, 0, archive_read_data(a, buff, sizeof(buff)));
+
+ /* Third header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("testdir/test.txt", archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertA((int)archive_entry_ctime(ae));
+ assertA((int)archive_entry_atime(ae));
+ assertEqualInt(20, archive_entry_size(ae));
+ assertEqualInt(33188, archive_entry_mode(ae));
+ assertA(size == archive_read_data(a, buff, size));
+ assertEqualMem(buff, test_txt, size);
+
+ /* Fourth header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("testdir", archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertA((int)archive_entry_ctime(ae));
+ assertA((int)archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(16877, archive_entry_mode(ae));
+
+ /* Fifth header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("testemptydir", archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertA((int)archive_entry_ctime(ae));
+ assertA((int)archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(16877, archive_entry_mode(ae));
+
+ /* Test EOF */
+ assertA(1 == archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_file_count(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_subblock(void)
+{
+ char buff[64];
+ const char reffile[] = "test_read_format_rar_subblock.rar";
+ const char test_txt[] = "test text document\r\n";
+ int size = sizeof(test_txt)-1;
+ struct archive_entry *ae;
+ struct archive *a;
+
+ extract_reference_file(reffile);
+ assert((a = archive_read_new()) != NULL);
+ assertA(0 == archive_read_support_filter_all(a));
+ assertA(0 == archive_read_support_format_all(a));
+ assertA(0 == archive_read_open_file(a, reffile, 10240));
+
+ /* First header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("test.txt", archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertA((int)archive_entry_ctime(ae));
+ assertA((int)archive_entry_atime(ae));
+ assertEqualInt(20, archive_entry_size(ae));
+ assertEqualInt(33188, archive_entry_mode(ae));
+ assertA(size == archive_read_data(a, buff, size));
+ assertEqualMem(buff, test_txt, size);
+
+ /* Test EOF */
+ assertA(1 == archive_read_next_header(a, &ae));
+ assertEqualInt(1, archive_file_count(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_noeof(void)
+{
+ char buff[64];
+ const char reffile[] = "test_read_format_rar_noeof.rar";
+ const char test_txt[] = "test text document\r\n";
+ int size = sizeof(test_txt)-1;
+ struct archive_entry *ae;
+ struct archive *a;
+
+ extract_reference_file(reffile);
+ assert((a = archive_read_new()) != NULL);
+ assertA(0 == archive_read_support_filter_all(a));
+ assertA(0 == archive_read_support_format_all(a));
+ assertA(0 == archive_read_open_file(a, reffile, 10240));
+
+ /* First header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("test.txt", archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertA((int)archive_entry_ctime(ae));
+ assertA((int)archive_entry_atime(ae));
+ assertEqualInt(20, archive_entry_size(ae));
+ assertEqualInt(33188, archive_entry_mode(ae));
+ assertA(size == archive_read_data(a, buff, size));
+ assertEqualMem(buff, test_txt, size);
+
+ /* Test EOF */
+ assertA(1 == archive_read_next_header(a, &ae));
+ assertEqualInt(1, archive_file_count(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_unicode_UTF8(void)
+{
+ char buff[30];
+ const char reffile[] = "test_read_format_rar_unicode.rar";
+ const char test_txt[] = "kanji";
+ struct archive_entry *ae;
+ struct archive *a;
+
+ if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
+ skipping("en_US.UTF-8 locale not available on this system.");
+ return;
+ }
+
+ extract_reference_file(reffile);
+ assert((a = archive_read_new()) != NULL);
+ assertA(0 == archive_read_support_filter_all(a));
+ assertA(0 == archive_read_support_format_all(a));
+ assertA(0 == archive_read_open_file(a, reffile, 10240));
+
+ /* First header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+#if defined(__APPLE__)
+#define f1name "\xE8\xA1\xA8\xE3\x81\x9F\xE3\x82\x99\xE3\x82\x88/"\
+ "\xE6\x96\xB0\xE3\x81\x97\xE3\x81\x84\xE3\x83\x95\xE3\x82\xA9"\
+ "\xE3\x83\xAB\xE3\x82\xBF\xE3\x82\x99/\xE6\x96\xB0\xE8\xA6\x8F"\
+ "\xE3\x83\x86\xE3\x82\xAD\xE3\x82\xB9\xE3\x83\x88 "\
+ "\xE3\x83\x88\xE3\x82\x99\xE3\x82\xAD\xE3\x83\xA5\xE3\x83\xA1"\
+ "\xE3\x83\xB3\xE3\x83\x88.txt" /* NFD */
+#else
+#define f1name "\xE8\xA1\xA8\xE3\x81\xA0\xE3\x82\x88/"\
+ "\xE6\x96\xB0\xE3\x81\x97\xE3\x81\x84\xE3\x83\x95\xE3\x82\xA9"\
+ "\xE3\x83\xAB\xE3\x83\x80/\xE6\x96\xB0\xE8\xA6\x8F"\
+ "\xE3\x83\x86\xE3\x82\xAD\xE3\x82\xB9\xE3\x83\x88 "\
+ "\xE3\x83\x89\xE3\x82\xAD\xE3\x83\xA5\xE3\x83\xA1"\
+ "\xE3\x83\xB3\xE3\x83\x88.txt" /* NFC */
+#endif
+ assertEqualUTF8String(f1name, archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(33188, archive_entry_mode(ae));
+
+ /* Second header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+#if defined(__APPLE__)
+#define f2name "\xE8\xA1\xA8\xE3\x81\x9F\xE3\x82\x99\xE3\x82\x88/"\
+ "\xE6\xBC\xA2\xE5\xAD\x97\xE9\x95\xB7\xE3\x81\x84\xE3\x83\x95"\
+ "\xE3\x82\xA1\xE3\x82\xA4\xE3\x83\xAB\xE5\x90\x8Dlong-filename-in-"\
+ "\xE6\xBC\xA2\xE5\xAD\x97.txt" /* NFD */
+#else
+#define f2name "\xE8\xA1\xA8\xE3\x81\xA0\xE3\x82\x88/"\
+ "\xE6\xBC\xA2\xE5\xAD\x97\xE9\x95\xB7\xE3\x81\x84\xE3\x83\x95"\
+ "\xE3\x82\xA1\xE3\x82\xA4\xE3\x83\xAB\xE5\x90\x8Dlong-filename-in-"\
+ "\xE6\xBC\xA2\xE5\xAD\x97.txt" /* NFC */
+#endif
+ assertEqualUTF8String(f2name, archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertEqualInt(5, archive_entry_size(ae));
+ assertEqualInt(33188, archive_entry_mode(ae));
+ assertEqualIntA(a, 5, archive_read_data(a, buff, 5));
+ assertEqualMem(buff, test_txt, 5);
+
+ /* Third header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+#if defined(__APPLE__)
+#define f3name "\xE8\xA1\xA8\xE3\x81\x9F\xE3\x82\x99\xE3\x82\x88/"\
+ "\xE6\x96\xB0\xE3\x81\x97\xE3\x81\x84\xE3\x83\x95\xE3\x82"\
+ "\xA9\xE3\x83\xAB\xE3\x82\xBF\xE3\x82\x99" /* NFD */
+#else
+#define f3name "\xE8\xA1\xA8\xE3\x81\xA0\xE3\x82\x88/"\
+ "\xE6\x96\xB0\xE3\x81\x97\xE3\x81\x84\xE3\x83\x95\xE3\x82"\
+ "\xA9\xE3\x83\xAB\xE3\x83\x80" /* NFC */
+#endif
+ assertEqualUTF8String(f3name, archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(16877, archive_entry_mode(ae));
+
+ /* Fourth header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+#if defined(__APPLE__)
+#define f4name "\xE8\xA1\xA8\xE3\x81\x9F\xE3\x82\x99\xE3\x82\x88" /* NFD */
+#else
+#define f4name "\xE8\xA1\xA8\xE3\x81\xA0\xE3\x82\x88" /* NFC */
+#endif
+ assertEqualUTF8String(f4name, archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(16877, archive_entry_mode(ae));
+
+ /* Fifth header, which has a symbolic-link name in multi-byte characters. */
+ assertA(0 == archive_read_next_header(a, &ae));
+#if defined(__APPLE__)
+#define f5name "\xE8\xA1\xA8\xE3\x81\x9F\xE3\x82\x99\xE3\x82\x88/"\
+ "\xE3\x83\x95\xE3\x82\xA1\xE3\x82\xA4\xE3\x83\xAB" /* NFD */
+#else
+#define f5name "\xE8\xA1\xA8\xE3\x81\xA0\xE3\x82\x88/"\
+ "\xE3\x83\x95\xE3\x82\xA1\xE3\x82\xA4\xE3\x83\xAB" /* NFC */
+#endif
+ assertEqualUTF8String(f5name, archive_entry_pathname(ae));
+ assertEqualUTF8String(
+ "\xE6\xBC\xA2\xE5\xAD\x97\xE9\x95\xB7\xE3\x81\x84\xE3\x83\x95"
+ "\xE3\x82\xA1\xE3\x82\xA4\xE3\x83\xAB\xE5\x90\x8Dlong-filename-in-"
+ "\xE6\xBC\xA2\xE5\xAD\x97.txt", archive_entry_symlink(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(41453, archive_entry_mode(ae));
+ assertEqualIntA(a, 0, archive_read_data(a, buff, sizeof(buff)));
+
+ /* Test EOF */
+ assertA(1 == archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_file_count(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_unicode_CP932(void)
+{
+ char buff[30];
+ const char reffile[] = "test_read_format_rar_unicode.rar";
+ const char test_txt[] = "kanji";
+ struct archive_entry *ae;
+ struct archive *a;
+
+ if (NULL == setlocale(LC_ALL, "Japanese_Japan") &&
+ NULL == setlocale(LC_ALL, "ja_JP.SJIS")) {
+ skipping("CP932 locale not available on this system.");
+ return;
+ }
+
+ extract_reference_file(reffile);
+ assert((a = archive_read_new()) != NULL);
+ assertA(0 == archive_read_support_filter_all(a));
+ assertA(0 == archive_read_support_format_all(a));
+ /* Specify the charset of symbolic-link file name. */
+ if (ARCHIVE_OK != archive_read_set_options(a, "rar:hdrcharset=UTF-8")) {
+ skipping("This system cannot convert character-set"
+ " from UTF-8 to CP932.");
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+ return;
+ }
+ assertA(0 == archive_read_open_file(a, reffile, 10240));
+
+ /* First header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("\x95\x5c\x82\xbe\x82\xe6/\x90\x56\x82\xb5\x82\xa2"
+ "\x83\x74\x83\x48\x83\x8b\x83\x5f/\x90\x56\x8b\x4b\x83\x65\x83\x4c"
+ "\x83\x58\x83\x67 \x83\x68\x83\x4c\x83\x85\x83\x81\x83\x93\x83\x67.txt",
+ archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(33188, archive_entry_mode(ae));
+
+ /* Second header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("\x95\x5c\x82\xbe\x82\xe6/\x8a\xbf\x8e\x9a"
+ "\x92\xb7\x82\xa2\x83\x74\x83\x40\x83\x43\x83\x8b\x96\xbc\x6c"
+ "\x6f\x6e\x67\x2d\x66\x69\x6c\x65\x6e\x61\x6d\x65\x2d\x69\x6e"
+ "\x2d\x8a\xbf\x8e\x9a.txt", archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertEqualInt(5, archive_entry_size(ae));
+ assertEqualInt(33188, archive_entry_mode(ae));
+ assertA(5 == archive_read_data(a, buff, 5));
+ assertEqualMem(buff, test_txt, 5);
+
+ /* Third header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("\x95\x5c\x82\xbe\x82\xe6/"
+ "\x90\x56\x82\xb5\x82\xa2\x83\x74\x83\x48\x83\x8b\x83\x5f",
+ archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(16877, archive_entry_mode(ae));
+
+ /* Fourth header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("\x95\x5c\x82\xbe\x82\xe6", archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(16877, archive_entry_mode(ae));
+
+ /* Fifth header, which has a symbolic-link name in multi-byte characters. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("\x95\x5c\x82\xbe\x82\xe6/"
+ "\x83\x74\x83\x40\x83\x43\x83\x8B", archive_entry_pathname(ae));
+ assertEqualString("\x8a\xbf\x8e\x9a"
+ "\x92\xb7\x82\xa2\x83\x74\x83\x40\x83\x43\x83\x8b\x96\xbc\x6c"
+ "\x6f\x6e\x67\x2d\x66\x69\x6c\x65\x6e\x61\x6d\x65\x2d\x69\x6e"
+ "\x2d\x8a\xbf\x8e\x9a.txt", archive_entry_symlink(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(41453, archive_entry_mode(ae));
+ assertEqualIntA(a, 0, archive_read_data(a, buff, sizeof(buff)));
+
+ /* Test EOF */
+ assertA(1 == archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_file_count(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_compress_normal(void)
+{
+ const char reffile[] = "test_read_format_rar_compress_normal.rar";
+ char file1_buff[20111];
+ int file1_size = sizeof(file1_buff);
+ const char file1_test_txt[] = "<P STYLE=\"margin-bottom: 0in\"><BR>\n"
+ "</P>\n"
+ "</BODY>\n"
+ "</HTML>";
+ char file2_buff[20];
+ int file2_size = sizeof(file2_buff);
+ const char file2_test_txt[] = "test text document\r\n";
+ struct archive_entry *ae;
+ struct archive *a;
+
+ extract_reference_file(reffile);
+ assert((a = archive_read_new()) != NULL);
+ assertA(0 == archive_read_support_filter_all(a));
+ assertA(0 == archive_read_support_format_all(a));
+ assertA(0 == archive_read_open_file(a, reffile, 10240));
+
+ /* First header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("LibarchiveAddingTest.html", archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertA((int)archive_entry_ctime(ae));
+ assertA((int)archive_entry_atime(ae));
+ assertEqualInt(file1_size, archive_entry_size(ae));
+ assertEqualInt(33188, archive_entry_mode(ae));
+ assertA(file1_size == archive_read_data(a, file1_buff, file1_size));
+ assertEqualMem(&file1_buff[file1_size - sizeof(file1_test_txt) + 1],
+ file1_test_txt, sizeof(file1_test_txt) - 1);
+
+ /* Second header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("testlink", archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertA((int)archive_entry_ctime(ae));
+ assertA((int)archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(41471, archive_entry_mode(ae));
+ assertEqualString("LibarchiveAddingTest.html", archive_entry_symlink(ae));
+ assertEqualIntA(a, 0, archive_read_data(a, file1_buff, 30));
+
+ /* Third header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("testdir/test.txt", archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertA((int)archive_entry_ctime(ae));
+ assertA((int)archive_entry_atime(ae));
+ assertEqualInt(file2_size, archive_entry_size(ae));
+ assertEqualInt(33188, archive_entry_mode(ae));
+ assertA(file2_size == archive_read_data(a, file2_buff, file2_size));
+ assertEqualMem(&file2_buff[file2_size + 1 - sizeof(file2_test_txt)],
+ file2_test_txt, sizeof(file2_test_txt) - 1);
+
+ /* Fourth header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("testdir/LibarchiveAddingTest.html",
+ archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertA((int)archive_entry_ctime(ae));
+ assertA((int)archive_entry_atime(ae));
+ assertEqualInt(file1_size, archive_entry_size(ae));
+ assertEqualInt(33188, archive_entry_mode(ae));
+ assertA(file1_size == archive_read_data(a, file1_buff, file1_size));
+ assertEqualMem(&file1_buff[file1_size - sizeof(file1_test_txt) + 1],
+ file1_test_txt, sizeof(file1_test_txt) - 1);
+
+ /* Fifth header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("testdir", archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertA((int)archive_entry_ctime(ae));
+ assertA((int)archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(16877, archive_entry_mode(ae));
+
+ /* Sixth header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("testemptydir", archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertA((int)archive_entry_ctime(ae));
+ assertA((int)archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(16877, archive_entry_mode(ae));
+
+ /* Test EOF */
+ assertA(1 == archive_read_next_header(a, &ae));
+ assertEqualInt(6, archive_file_count(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+/* This test is for sufficiently large files that would have been compressed
+ * using multiple lzss blocks.
+ */
+static void
+test_multi_lzss_blocks(void)
+{
+ const char reffile[] = "test_read_format_rar_multi_lzss_blocks.rar";
+ const char test_txt[] = "-bottom: 0in\"><BR>\n</P>\n</BODY>\n</HTML>";
+ int size = 20131111, offset = 0;
+ char buff[64];
+ struct archive_entry *ae;
+ struct archive *a;
+
+ extract_reference_file(reffile);
+ assert((a = archive_read_new()) != NULL);
+ assertA(0 == archive_read_support_filter_all(a));
+ assertA(0 == archive_read_support_format_all(a));
+ assertA(0 == archive_read_open_file(a, reffile, 10240));
+
+ /* First header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("multi_lzss_blocks_test.txt", archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertA((int)archive_entry_ctime(ae));
+ assertA((int)archive_entry_atime(ae));
+ assertEqualInt(size, archive_entry_size(ae));
+ assertEqualInt(33188, archive_entry_mode(ae));
+ while (offset + (int)sizeof(buff) < size)
+ {
+ assertA(sizeof(buff) == archive_read_data(a, buff, sizeof(buff)));
+ offset += sizeof(buff);
+ }
+ assertA(size - offset == archive_read_data(a, buff, size - offset));
+ assertEqualMem(buff, test_txt, size - offset);
+
+ /* Test EOF */
+ assertA(1 == archive_read_next_header(a, &ae));
+ assertEqualInt(1, archive_file_count(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_compress_best(void)
+{
+ const char reffile[] = "test_read_format_rar_compress_best.rar";
+ char file1_buff[20111];
+ int file1_size = sizeof(file1_buff);
+ const char file1_test_txt[] = "<P STYLE=\"margin-bottom: 0in\"><BR>\n"
+ "</P>\n"
+ "</BODY>\n"
+ "</HTML>";
+ char file2_buff[20];
+ int file2_size = sizeof(file2_buff);
+ const char file2_test_txt[] = "test text document\r\n";
+ struct archive_entry *ae;
+ struct archive *a;
+
+ extract_reference_file(reffile);
+ assert((a = archive_read_new()) != NULL);
+ assertA(0 == archive_read_support_filter_all(a));
+ assertA(0 == archive_read_support_format_all(a));
+ assertA(0 == archive_read_open_file(a, reffile, 10240));
+
+ /* First header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("LibarchiveAddingTest.html", archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertA((int)archive_entry_ctime(ae));
+ assertA((int)archive_entry_atime(ae));
+ assertEqualInt(file1_size, archive_entry_size(ae));
+ assertEqualInt(33188, archive_entry_mode(ae));
+ assertA(file1_size == archive_read_data(a, file1_buff, file1_size));
+ assertEqualMem(&file1_buff[file1_size - sizeof(file1_test_txt) + 1],
+ file1_test_txt, sizeof(file1_test_txt) - 1);
+
+ /* Second header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("testlink", archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertA((int)archive_entry_ctime(ae));
+ assertA((int)archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(41471, archive_entry_mode(ae));
+ assertEqualString("LibarchiveAddingTest.html", archive_entry_symlink(ae));
+ assertEqualIntA(a, 0, archive_read_data(a, file1_buff, 30));
+
+ /* Third header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("testdir/test.txt", archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertA((int)archive_entry_ctime(ae));
+ assertA((int)archive_entry_atime(ae));
+ assertEqualInt(file2_size, archive_entry_size(ae));
+ assertEqualInt(33188, archive_entry_mode(ae));
+ assertA(file2_size == archive_read_data(a, file2_buff, file2_size));
+ assertEqualMem(&file2_buff[file2_size + 1 - sizeof(file2_test_txt)],
+ file2_test_txt, sizeof(file2_test_txt) - 1);
+
+ /* Fourth header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("testdir/LibarchiveAddingTest.html",
+ archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertA((int)archive_entry_ctime(ae));
+ assertA((int)archive_entry_atime(ae));
+ assertEqualInt(file1_size, archive_entry_size(ae));
+ assertEqualInt(33188, archive_entry_mode(ae));
+ assertA(file1_size == archive_read_data(a, file1_buff, file1_size));
+ assertEqualMem(&file1_buff[file1_size - sizeof(file1_test_txt) + 1],
+ file1_test_txt, sizeof(file1_test_txt) - 1);
+
+ /* Fifth header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("testdir", archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertA((int)archive_entry_ctime(ae));
+ assertA((int)archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(16877, archive_entry_mode(ae));
+
+ /* Sixth header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("testemptydir", archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertA((int)archive_entry_ctime(ae));
+ assertA((int)archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(16877, archive_entry_mode(ae));
+
+ /* Test EOF */
+ assertA(1 == archive_read_next_header(a, &ae));
+ assertEqualInt(6, archive_file_count(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+/* This is a test for RAR files compressed using a technique where compression
+ * switches back and forth to and from ppmd and lzss decoding.
+ */
+static void
+test_ppmd_lzss_conversion(void)
+{
+ const char reffile[] = "test_read_format_rar_ppmd_lzss_conversion.rar";
+ const char test_txt[] = "gin-bottom: 0in\"><BR>\n</P>\n</BODY>\n</HTML>";
+ int size = 241647978, offset = 0;
+ char buff[64];
+ struct archive_entry *ae;
+ struct archive *a;
+
+ extract_reference_file(reffile);
+ assert((a = archive_read_new()) != NULL);
+ assertA(0 == archive_read_support_filter_all(a));
+ assertA(0 == archive_read_support_format_all(a));
+ assertA(0 == archive_read_open_file(a, reffile, 10240));
+
+ /* First header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("ppmd_lzss_conversion_test.txt",
+ archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertA((int)archive_entry_ctime(ae));
+ assertA((int)archive_entry_atime(ae));
+ assertEqualInt(size, archive_entry_size(ae));
+ assertEqualInt(33188, archive_entry_mode(ae));
+ while (offset + (int)sizeof(buff) < size)
+ {
+ assertA(sizeof(buff) == archive_read_data(a, buff, sizeof(buff)));
+ offset += sizeof(buff);
+ }
+ assertA(size - offset == archive_read_data(a, buff, size - offset));
+ assertEqualMem(buff, test_txt, size - offset);
+
+ /* Test EOF */
+ assertA(1 == archive_read_next_header(a, &ae));
+ assertEqualInt(1, archive_file_count(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_binary(void)
+{
+ const char reffile[] = "test_read_format_rar_binary_data.rar";
+ char file1_buff[1048576];
+ int file1_size = sizeof(file1_buff);
+ const char file1_test_txt[] = "\x37\xef\xb2\xbe\x33\xf6\xcc\xcb\xee\x2a\x10"
+ "\x9d\x2e\x01\xe9\xf6\xf9\xe5\xe6\x67\x0c\x2b"
+ "\xd8\x6b\xa0\x26\x9a\xf7\x93\x87\x42\xf1\x08"
+ "\x42\xdc\x9b\x76\x91\x20\xa4\x01\xbe\x67\xbd"
+ "\x08\x74\xde\xec";
+ char file2_buff[32618];
+ int file2_size = sizeof(file2_buff);
+ const char file2_test_txt[] = "\x00\xee\x78\x00\x00\x4d\x45\x54\x41\x2d\x49"
+ "\x4e\x46\x2f\x6d\x61\x6e\x69\x66\x65\x73\x74"
+ "\x2e\x78\x6d\x6c\x50\x4b\x05\x06\x00\x00\x00"
+ "\x00\x12\x00\x12\x00\xaa\x04\x00\x00\xaa\x7a"
+ "\x00\x00\x00\x00";
+ struct archive_entry *ae;
+ struct archive *a;
+
+ extract_reference_file(reffile);
+ assert((a = archive_read_new()) != NULL);
+ assertA(0 == archive_read_support_filter_all(a));
+ assertA(0 == archive_read_support_format_all(a));
+ assertA(0 == archive_read_open_file(a, reffile, 10240));
+
+ /* First header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("random_data.bin", archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertA((int)archive_entry_ctime(ae));
+ assertA((int)archive_entry_atime(ae));
+ assertEqualInt(file1_size, archive_entry_size(ae));
+ assertEqualInt(33188, archive_entry_mode(ae));
+ assertA(file1_size == archive_read_data(a, file1_buff, file1_size));
+ assertEqualMem(&file1_buff[file1_size - sizeof(file1_test_txt) + 1],
+ file1_test_txt, sizeof(file1_test_txt) - 1);
+
+ /* Second header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("LibarchiveAddingTest.odt", archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertA((int)archive_entry_ctime(ae));
+ assertA((int)archive_entry_atime(ae));
+ assertEqualInt(file2_size, archive_entry_size(ae));
+ assertEqualInt(33188, archive_entry_mode(ae));
+ assertA(file2_size == archive_read_data(a, file2_buff, file2_size));
+ assertEqualMem(&file2_buff[file2_size + 1 - sizeof(file2_test_txt)],
+ file2_test_txt, sizeof(file2_test_txt) - 1);
+
+ /* Test EOF */
+ assertA(1 == archive_read_next_header(a, &ae));
+ assertEqualInt(2, archive_file_count(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_windows(void)
+{
+ char buff[441];
+ const char reffile[] = "test_read_format_rar_windows.rar";
+ const char test_txt[] = "test text file\r\n";
+ int size = sizeof(test_txt)-1;
+ struct archive_entry *ae;
+ struct archive *a;
+
+ extract_reference_file(reffile);
+ assert((a = archive_read_new()) != NULL);
+ assertA(0 == archive_read_support_filter_all(a));
+ assertA(0 == archive_read_support_format_all(a));
+ assertA(0 == archive_read_open_file(a, reffile, 10240));
+
+ /* First header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("testdir/test.txt", archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertA((int)archive_entry_ctime(ae));
+ assertA((int)archive_entry_atime(ae));
+ assertEqualInt(16, archive_entry_size(ae));
+ assertEqualInt(33188, archive_entry_mode(ae));
+ assertA(size == archive_read_data(a, buff, size));
+ assertEqualMem(buff, test_txt, size);
+
+ /* Second header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("test.txt", archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertA((int)archive_entry_ctime(ae));
+ assertA((int)archive_entry_atime(ae));
+ assertEqualInt(16, archive_entry_size(ae));
+ assertEqualInt(33188, archive_entry_mode(ae));
+ assertA(size == archive_read_data(a, buff, size));
+ assertEqualMem(buff, test_txt, size);
+
+ /* Third header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("testshortcut.lnk", archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertA((int)archive_entry_ctime(ae));
+ assertA((int)archive_entry_atime(ae));
+ assertEqualInt(sizeof(buff), archive_entry_size(ae));
+ assertEqualInt(33188, archive_entry_mode(ae));
+ assertA(sizeof(buff) == archive_read_data(a, buff, sizeof(buff)));
+
+ /* Fourth header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("testdir", archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertA((int)archive_entry_ctime(ae));
+ assertA((int)archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(16877, archive_entry_mode(ae));
+
+ /* Fifth header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("testemptydir", archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertA((int)archive_entry_ctime(ae));
+ assertA((int)archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(16877, archive_entry_mode(ae));
+
+ /* Test EOF */
+ assertA(1 == archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_file_count(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_sfx(void)
+{
+ char buff[441];
+ const char reffile[] = "test_read_format_rar_sfx.exe";
+ const char test_txt[] = "test text file\r\n";
+ int size = sizeof(test_txt)-1;
+ struct archive_entry *ae;
+ struct archive *a;
+
+ extract_reference_file(reffile);
+ assert((a = archive_read_new()) != NULL);
+ assertA(0 == archive_read_support_filter_all(a));
+ assertA(0 == archive_read_support_format_all(a));
+ assertA(0 == archive_read_open_file(a, reffile, 10240));
+
+ /* First header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("test.txt", archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertA((int)archive_entry_ctime(ae));
+ assertA((int)archive_entry_atime(ae));
+ assertEqualInt(16, archive_entry_size(ae));
+ assertEqualInt(33188, archive_entry_mode(ae));
+ assertA(size == archive_read_data(a, buff, size));
+ assertEqualMem(buff, test_txt, size);
+
+ /* Second header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("testshortcut.lnk", archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertA((int)archive_entry_ctime(ae));
+ assertA((int)archive_entry_atime(ae));
+ assertEqualInt(sizeof(buff), archive_entry_size(ae));
+ assertEqualInt(33188, archive_entry_mode(ae));
+ assertA(sizeof(buff) == archive_read_data(a, buff, sizeof(buff)));
+
+ /* Third header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("testdir/test.txt", archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertA((int)archive_entry_ctime(ae));
+ assertA((int)archive_entry_atime(ae));
+ assertEqualInt(16, archive_entry_size(ae));
+ assertEqualInt(33188, archive_entry_mode(ae));
+ assertA(size == archive_read_data(a, buff, size));
+ assertEqualMem(buff, test_txt, size);
+
+ /* Fourth header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("testdir", archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertA((int)archive_entry_ctime(ae));
+ assertA((int)archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(16877, archive_entry_mode(ae));
+
+ /* Fifth header. */
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualString("testemptydir", archive_entry_pathname(ae));
+ assertA((int)archive_entry_mtime(ae));
+ assertA((int)archive_entry_ctime(ae));
+ assertA((int)archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(16877, archive_entry_mode(ae));
+
+ /* Test EOF */
+ assertA(1 == archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_file_count(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+DEFINE_TEST(test_read_format_rar)
+{
+ test_basic();
+ test_subblock();
+ test_noeof();
+ test_unicode_UTF8();
+ test_unicode_CP932();
+ test_compress_normal();
+ test_multi_lzss_blocks();
+ test_compress_best();
+ test_ppmd_lzss_conversion();
+ test_binary();
+ test_windows();
+ test_sfx();
+}
diff --git a/libarchive/test/test_read_format_rar.rar.uu b/libarchive/test/test_read_format_rar.rar.uu
new file mode 100644
index 000000000000..75f93b4c281a
--- /dev/null
+++ b/libarchive/test/test_read_format_rar.rar.uu
@@ -0,0 +1,11 @@
+begin 644 -
+M4F%R(1H'`,^0<P``#0````````"$4G0@D#(`%````!0````#0J+(OK=VVCX4
+M,`@`I($``'1E<W0N='AT@`BW=MH^MW;:/G1E<W0@=&5X="!D;V-U;65N=`T*
+MG2]T()`R``@````(`````WM$R;;13-@^%#`(`/^A``!T97-T;&EN:\`(T4S8
+M/E!?VCYT97-T+G1X=,W@=""0.@`4````%`````-"HLB^8W?:/A0P$`"D@0``
+M=&5S=&1I<EQT97-T+G1X=,#,8W?:/F-WVCYT97-T('1E>'0@9&]C=6UE;G0-
+M"J'(=."0,0````````````,`````8W?:/A0P!P#M00``=&5S=&1I<L#,8W?:
+M/F1WVC[FYW3@D#8````````````#`````)VKU3X4,`P`[4$``'1E<W1E;7!T
+5>61I<H#,G:O5/L5=VC[$/7L`0`<`
+`
+end
diff --git a/libarchive/test/test_read_format_rar_binary_data.rar.uu b/libarchive/test/test_read_format_rar_binary_data.rar.uu
new file mode 100644
index 000000000000..4d1cbd36d633
--- /dev/null
+++ b/libarchive/test/test_read_format_rar_binary_data.rar.uu
@@ -0,0 +1,24041 @@
+begin 644 -
+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
+H'Z=?O="#_Z/C>/Y(&GV"#Q#\_"'`/VF#O^.F>OS_/_\@Q#U[`$`'````
+`
+end
diff --git a/libarchive/test/test_read_format_rar_compress_best.rar.uu b/libarchive/test/test_read_format_rar_compress_best.rar.uu
new file mode 100644
index 000000000000..22fde0f8b673
--- /dev/null
+++ b/libarchive/test/test_read_format_rar_compress_best.rar.uu
@@ -0,0 +1,274 @@
+begin 644 -
+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
+D,`P`[4$``'1E<W1E;7!T>61I<H#,G:O5/CUZ]3[$/7L`0`<`
+`
+end
diff --git a/libarchive/test/test_read_format_rar_compress_normal.rar.uu b/libarchive/test/test_read_format_rar_compress_normal.rar.uu
new file mode 100644
index 000000000000..afc6cc08db11
--- /dev/null
+++ b/libarchive/test/test_read_format_rar_compress_normal.rar.uu
@@ -0,0 +1,328 @@
+begin 644 -
+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
+E%#`,`.U!``!T97-T96UP='ED:7+`S)VKU3Z%2NT^Q#U[`$`'````
+`
+end
diff --git a/libarchive/test/test_read_format_rar_multi_lzss_blocks.rar.uu b/libarchive/test/test_read_format_rar_multi_lzss_blocks.rar.uu
new file mode 100644
index 000000000000..dd6ab50f97cd
--- /dev/null
+++ b/libarchive/test/test_read_format_rar_multi_lzss_blocks.rar.uu
@@ -0,0 +1,444 @@
+begin 644 -
+M4F%R(1H'`,^0<P``#0````````"5L73`D$0`(TT``"<M,P$#<!6B:RZ@[CX=
+M,QH`I($``&UU;'1I7VQZ<W-?8FQO8VMS7W1E<W0N='ATP,PNH.X^+:#N/@W!
+ME1$,S1$`%=F]SKX56/`,:6:25T-W=Y;Z1J;2>M#'TZD7E[>^E"B3)2K$2:-U
+M5%)EX,^[Z/T)6TB:)CD1,U4E(I-+`,]6V+:-&:B>1$<ZO.<CD'XIS^$'D><B
+M)J`9!%`5[?WS_X=O\?KV?Z_EW,/V[/W_=A_+\_J^[N_7A^'7ZW6_I\?U^@[>
+MSVZ_1\FQU\.SEQ<&;'GQY.#%O<E=S\/A^G!\\?9'X[G:[<I\'S_?W-GM3]#9
+M_+7[G_O\^[_M]'P_7^/X;/*G9UXR+X<-OZ\C9[/TS];Q9]_>^;#M^+%ES69_
+MHXL^[K_Z?#!$V>[L_=W/I^?K5_-Q5_#M>BY<?^N7W<[W:V?Q[UXF?=CVLMGX
+M[N[CV[,/Q['QX</4_/@Q_IU?A]3VOK[W<_O.YVY=]GK]CL=?^/9_C\W9_8^/
+M^'I77];TOM[7X?^I?__#Y/X2YW^=[FIPQN.W;6WFS4^C_#7U_0_!_YX<7AYF
+MO^,._ST^''P?+AZ^Q_+^?H\/_,_J_+3YM?:R9\^3?C[>O_I+GV]C]S[MCRV9
+MM&&7@GAMW)P9]?=Q;^/>X^4D&3Y&Q0BO#W_2,>[\.MAS1^;O7V_]_'ZWI_5C
+MSZ#,MGIV'_:?M\MYIM^'3C\^]+W]G*NS5A/R[W<]V*O,9O\H\F;AQ;=E<@[/
+MM]S]GW#/]G9_ZN?:^O"*NM1(DUR^M5<SY_J_'M_UP_=-0#Z/ALYEOS[^B;M]
+MWO35MV>]1?CL8?KY,[_?6H"Y$[NC?+DW.+;@^LR+V)X7\OIF@CG7V_%C\FBK
+M'FPZ-?+AYA.9S'E8=OGFX=ZS],/#CLGHC)NX<W[>?R\K?2\_BQ9\.7BYJN1>
+M#!ROX.+?FDV,#N8]W=])YCN3>7/*+GIR[^;8P]J>/])R<7A\7I$]%Z!N+GSI
+MEOIF:>*QXM[!,ZG)D\=A\D*"<>/@\.A2SF*X>0<_*;%P;E/KY5\N<L?53/MW
+MBS^FV0T]R#H(P;G,3\7(DV:,7CY4?IH<S^:\H^"F[=$.C'CYB)F[_*F].UP<
+M[N;'X>#15CV^7V>TB:%\F'>TF.UN:'EYO<6Y!'W\D];;7%,H8_TT5ZV#-SG\
+M6]S*<^G,WMP:7E[CLG^W'36D;C\TR9;M-05M.D:?9S$[.B'FRT4<A?WED_LF
+M:SS3E1H5G[OBLO:$O&PY.\NA/QT,93#Y,$VR+.#<CT=_3MOI$[?/<XM^K0-O
+M1L[P3(?@[W%P<$?.?N^#9GBO!^67)X<N+?FX7T$]I=C*9AYN4TYYKAEYI5&[
+MF+FOFQ#_O&]IF0R<$TL:^O?.;M9MS/Z9K4)\_GM\./)R@\6*:7J;DP<-2E5+
+MG.US=;>/-9FIF702-"LU,'IR>#G<J;,%#5VD:96RV4P7.--#6/@H2,W)'H/+
+MBXZD"/#ECTZ%'E_JU;J6BN(-Y3S9R0OU3W>AF/.UQY.*:@-FY"<?#!&A#7H/
+M+DJR%-13=P<Q,,*T=\_+<4_S^Z&X/N[OTZ'<-&Y?H^'U7-GI?PZ.*&*WM[#P
+M\OO%&1QH+<Q\X6WZ7EX]`/BR51C'F_R_MQ<NOFY*HT;-KW=GL3-7R:-?@IFU
+MN8].5IH`V^+/BVIK/7(8VK+EP)[AZG!H)T`XN'AWL>W3"]!COP56VQQG.]T'
+M,%Y"-<IT"7SB=6[3GH(,I;IWU-C42UBF2M[S2BB\)`\<W77!,J\/-KFJEZ,+
+MQ9M%6#'T463011H&SCJ2)[YY(R9:J2\7%/)\FY/]*HFCQTS3!Y<<S.XK3L;'
+M*>OPPT:$S3T)0I=%1'G[R9/'!!F]2L\N#DF:_>C+<GYMNB@&;YO/.;GFXX+*
+MK!9.:VC<E%2?BWM[2J9FX>>B;Q:AK_GV=GUFXM?+YIR-].@7AH8ZFJL]]*W!
+M"_%I\,7#/3_[6/D:\I[?7?\5EK5E4C7FL/!T=O0P-7$P[NMP>#0CS6S+>YO<
+M?S1E_';L7I59;^BM2N.Q@[6]G\5(%_MM#PCVIF9K!Z&>.%4[."U'='!L+85(
+M5_W=:NEM3\3BS1FU(,=WJSA'V9<%WL>>Z=[;&'NRF[BV\^MARZGB^;U4]XO#
+M#]//@H2<,KCB*=OS=853Y#!V+#X<F3<JZ2R6P_-3IR^\7H\)]#9O>2U@"%*(
+MSO;]'"0]Z^D+^DIP1IS6]=U+SL\6>;$>'%7PS8+P[\_\@0!2+'-^/0W4/J/3
+M=#63+ZWWP`?AL+%.-]EC957ZDUY.8^<<O-Q;\W7O'\NG1W>[GK+8?Y<&UFX?
+MFTP5J1,8$\];/O\/6O)TV.SU^O_/7Z_9U^Q_+9[/8V/CZ^Q\G7]._8P6D#U'
+M#'E]#O0E"8`6:@F6'G-<1;^.MXN0K-$>/?ZVITKZ=,U'C]#YYUO/<'2Z:R2O
+ML_;KK"WV>Y6%U/W/EN5[[.Q_'8_GS:8L.O?>&W>6WU^O\M,L\%VV^Q;^_*_0
+M7MV^/LMO)P\=OBU>#8V_E['\I^KVKD+6HGY!F'X@.U.*M_;BFB"WV.C^.O]'
+M7Z?Z-Z;K;/U(<@=G#_XP_'K<C^E<C<B=GJ_1K]CV6A/LJI%V?X_)R7CFJ!;B
+M/CMV!X;,^Y-O2WR_(\5F]P^IH38_8F%]RV7+;9-_'GB#_/SW&GAYWV/CM13E
+ML@1G#@*>@.++ISC#L\_W/U3%=?^'7_G_+4MY.$GHWV_'./%ZV*C7M[#P4NEP
+MW7OX3-X\?#PSPLU^^]W(BO8(>G_M8MR;@7>Q\$UI9N#X6BFUQN>^@`NA'QJX
+MHN7SI#J^"&H\VW.59V_%:PGN7#,ZN")NO=VT+E3:&:KB.WT\'P=%DCTO=F+X
+ML\6@&T*'CS7L_C+-W0]1W!SO3&/SU?X=BZ.%[H#1O$Z;6&CG1%M^*H!C+[1M
+MWWG)?LR9?;02-:8(/]P('4'W<*5];/?I^J&I(??P`)PW@\>BSF*XK7YL]-69
+M]CU@</=M.OMZ`[+7V&6%:9P,.:B<-G/9:#0@!/I1O&A.UF@!1@G)A3G/*^W$
+M!B@U.'0&]9J69N&!0#<J3MW2U%@EE08&[CYP\]&L^6-V#UH^4%;:LT5S5GB`
+MUTH(:KBKJT!%STK,YW,=.6DX)Y+K]B>@,V>'R]1MN']>662NB(+,Y0.:@MFY
+M[G)D0>VB.I_YEW]#&3>R>'CK)<503'UX)=]&2GOQ$)F0F&^H_DW<-^;*J'?H
+MY5K\N9KN71',-9+>'BE%3<>;5'<J)'Y,^N<Y=S]VK>:@R4206"OL9KS2FS&3
+MUEX9S(W#S!0J#"N>@3?LI1&K*:AR<-M$VS8(SC?Q4`!UU!J="U_>\KW-X1Q;
+MT3/$,%V?IBC5FM@Y>\%)4[I)G/-&4\%-N0S="<;ONCQURJB/L'#2;'T/8LM[
+M3LY4';Y^[(#&9,NE;#J?ULS45,QQLR8:S!CWX?7Q/!^H#_FW79X<4*@\Y=-'
+M^'E;!<Z`C3!0%!SK=74#Z^V&`J!68-SY8)6CG'"%>?;F0R\.>KF;I5OJ*H4G
+MSO1?KCX:+C:V"KI"FFH0'7[\>UCI-%T2MY.?GGRXG_WN_E=(:VFKS>X!!,/;
+M[GV=W\.YX-GN=_9ZGJ:"ZMT&O_CU(BW6_SI$9G4E^+AOQ$\/^?6]3$U13U.I
+MBP_1=I7P0E'P3H574ZO5P_X<C?A^?W?=U?FZ;U^Y`#"8#[J=KO?7]O=_VYI?
+MQ_UUO4Q'J>M?R+-S.0EVFT($TS48\$W"O,7U?^ZRZJ`_8Y3.6PRS'>>#3!=\
+M$K0'!_V6E89'ID49#S(:U'&OH>QU^S\G7]?3M?Q-+W>AG6KXR;E3+Q](EJOX
+M]GJ/U4W\_'@J"'ZF*T.+BL]CH&\5>_H]FYCZDMQ6?-?N_A]G6^_M?AW?LFME
+ML??]E?IU9=35_@NF=NI3).B$.Z5GVN8__)_^K-E[^+;RY+0SFF42QY9TS7P\
+M4/9YN8IM#YIN+YMK9YRM</R=S'1S[0')29@Z`PO-KZ\3#-SO_#CKA(U+<\&O
+M'QK5#\^#]W?&A2/8IJZH**HH.A.FZIF`^W^C.NQ0=,ME*0OJ=_753F*1-M6<
+MEV65C7^V-56+3::F!`$0>KTT9/@NIB<(IHV*M0HP]WO_C$)FZA$^S+MXM3'F
+MP976M+-?ON0_6J[SJ;_GF3@N&Z\]_U<<Q"/ILX.FM@I.VWC*6X2FDZ@(*@#.
+MI'V?7!\[:.G4[_*[>T85^75V,'?LA,UVB[="5JU-E'Q,SF6A+[8HN'%3SV4J
+M'6"Z@8:JL3!'T^6T.%H!ZDX8'BB-'[,T5S.=351LW]S%U9)ICK@QUJQ<1JM'
+M75P:8<G.9GJ&>F"]NG@,W0/#,1MJB\VT-*<17F.P05^?'E+1=2E=9TL9_-43
+M5.?WT23HF'/5//*PU]S'HAGP.<]/X+<BS>Y!B_NY?6>#;XYUL?P:+?!BH&5J
+M&)CZ<,L@^]9'+I`P\\HQ[GGU^Z$TPR[P2Y=0W)\*'9O;M8^UU8LM<9XO',M\
+M[&HP6KUL$\?HYYGYM&;DV/;I27I4B7XT?5O.G]B;L['FK\X#2^26J'QSY*\%
+M=9T:.;AOYEIHW-%.Z"4>2-KG(KZ4#U;9=:";2H9UJ5LV6,<QJ=RX/4_'@P1R
+M*$Z[;SUZN%WUJ2`E%7.EVC-0+AKLC2&T@Q]V70,5G0W.9VE'6F0X'G6=.O#H
+MWF@SQ58%IKJ*T1FTO6JC6=[>N>Q7N$"@5_">L\,[\<Z2YFBF#X,6YN:N%)OA
+MW-GQ=%VQ#$U!\EF:Z8XCTHV!.C,38CY4^')24^IQ/U&&=V=8VR>6@UKE9PQZ
+M\V<YY]AQV\6E5:GWV>9GRL?>[O^O<^GZ]#E'M^]O4-O_>37;V\N/AG-PYJ"@
+MH%`Q/29YUZO6C\3'1UIH$_G,6?.@<VDK#U*<1-\$_?L\LT-<,#I-N'`D"VM2
+M:9_M220VH@9\JM^;DG<V.K[Q.0?7#@ZRN^8A(3IWM_@5_+2M,49^F%7G&0U)
+M;OI3KL/RXZX&VOOSD'_@OUF3W;2?>F^6SURC;XLM.12A@*=8=]YVQ-`V;5J"
+MYPU[R0N[NW3JT?YP9-0%+!\%SRBDFE;'Z@_L>CTIRIM5S)W35\#QRS0ECS70
+MBXG=ND(=`'5*,M-;3@N!A4=G?!;*YYO63YI6=T[-Q1_W!QUEY:-P7UI[:UG/
+MDO\'P>R6HIO6L=;-IK%EY;VDVEYM5KLU68]$^+R6=/FG341CH0X:-M4H=F+=
+MLWN.$$S?I45D_Z/&E7*K:CM1S26_S&47RLO<1I,)=/<?O*FL<S!6E:;=&6[@
+MS%V:7F%+U+6HUS1P[.CK;'2\=/T6"HUA!4M"TVA+_KK^/58NU<:C0X]4+>^F
+MW[UDT@YJPAM^S?HNGLWE?\>>W@G='<Z6=3ELM[CIQ$_[450#%;ZMM0NGX<^2
+MC\2<&B99\<U+\?!ZM"/G\H8#]Y/_1\+34L*UV;E4&6P=(K,T\HB'+#L[U5B:
+MZ(A&&K0?K(,_#)GK1&)X_R\MXC,[6;)O<4_A$GQZRYOM0H7Y6OR/!05]#EJH
+M4"[SX)?-(3[OQ``JPA?XP6#FXKS&FF!'S'=_BNB.VV%[Q9NCQP%V+U])-M&N
+MXLUL33V]#._QFZ+\'@_+D79^S\>]]^"*$;=1&8/C9ETO?\U*]]_C/CJ^66"^
+M%:T39/!=H;JX/^,'J%+H34,%^TP,`MIC7L.Q4K3D+NCBJ5Y/5-A^ONB]3Y>K
+M\UVF/^=4UGZCHF<E#5SM16'4@;3S;D/)(7TR<$8'!JLPO2#*^^=DI:O:F4ND
+M0!!'HX>T63.+/2T`!+>1TP3+E*>!TMFYSUC/@7JLOVCY>.BU%`?&E0N<LYE@
+M+E10S3G\ZSO/EP^#<@ISK%\_2]]<3_G,G1`XR=-#MT23+MHT>==\Z;!494NP
+M?3D6&?_-U[&5_W=N'!=N'HQ!M[<".H;UU!_9QS//,V/:]<"_]/W1SXEHD'V4
+MA!_>VC`[N'LF+(^"=>6PX^A%SK/=?I^G,A>8.HJ7.R/8ANS051ZIRM^*:C>@
+M.!KUP6>G&%<.3AK5;>#SZG(7Y/+K>BXL]!F63@N?`157O2=R=6!]Y=%UY#SP
+M5;YJZ&[5^?OTN@=GH#2J2O.CJ#L3;RISQ5+8]FQ1=K^N^M6]<&+R3"?VV1Y1
+M8[WU6:M?LIR:LZL;\ONL]7[!7/IYZG6_=*OWV;\LT*>[\4C$'&@!F+0&]GD'
+MWSE'XQG[^MHQ/?X]_>\T\<OO&+^V='^U8S]TL]O'6R8<'O>X[4J^S+G=S=ZS
+MP_OZ#Y37:!UO;$SH&!]J4(T[W\?ZV?O%.,1^'FN;W,J??'&==*:NU.F2=E1^
+MW,G&([D"A_<\Q_#0E>QO[A7^NW/_WRULV?IZ_H^\.2;K&;\'V2M7)>GR899I
+M<F_?$,B[GP?[<6/+7EY8N'^=+5LU]-"/G%=Z/,+U!M8--L,UM<S52/*TE&G)
+M\0-;MK"^3;QT',:;EAV,'>]>V:)S<UFY%SSY::/SY.C-X[_%FSTHU%ML<X,^
+M2/WK8*M9PC3H.=W!;UX`-?XX^(%-UPA8KVYIV2'IXYRL:N-NX/9<6),*/5,%
+MM;3WK-5IVTVA[;V]B>84]^V7MMMQSH[%F<3]XB['%Q4)%[>/])ZYO6\C!L];
+M3#\G8BWDLJB3HIGIO+VHH#V+HS8[,.CO<N($J("O[`KX?<>"_]@4K0.]T/6@
+M<[!Q3K5EO/$67<G#;)24/EP]#EMO5F.^DM[2@*28$3V2$(9.NXQF+#YVM"O[
+M=FQMUA=PPQIJ%]JR%0.E*@I.L^WLL[4[C.N!)3I]=F6UKNBE5Y&^YHLQ>;+=
+M@U5`P4WU2IW\A_IKVW+ABYW<45Z*.BXS.39ENEL)V!!,"=OS-]S8SU39@]_0
+M!!#H$-MY[#!P4EP8*UUP9T"@QHSW*M\]O)FB]2?1\&>UV]/Q4+WFRUVY[H#*
+M[?XT;7J][T"[T=$?G.>14Q/BG-6V[_FW]XL5.>$MQ59&.+Z@LI51)VC'I#X^
+M^YQ<$F@:?ZH0W6P]$'I<&UTA?[UCPQ?:-Q$ZG5^:J?HDUYXK]:W:]FI>DLZW
+MMDSU%M7K,YG__%IIL?OFT::7FY3M68AO"<T!CWXDT=J='?B_FK8+MO0W:K*T
+ML52>JYYIJ(-.%VKR*T_'#"O!X]`L_E\4]?\V7%%Q_3H:.M.H3:E5=,KAJJ0-
+M>-(TY#2T>>C:QD4QO]+O6F5/?-]Q,\>K7;KF-YT:+:G8%M=]4,+,[7;I+VQX
+M\G!7>>C7F,YON1/)S7\A0;7IP*\;'I>X%O`E9?98:L0_S;AX'6>RK2','P>O
+MP#WO.\OP^+1GSN3)>3IK27^WM3YQ"T='63&I9`DX9&[C\.QXJU9?3GE&#]/$
+M[>Z%"O%,55$OWY31*%<IXJ\+/=S"MUMHPV[-KN>,XN'8ZOF_"9PH$ZVZ]AV1
+M=/E4FUL]>/,Z`&J-5]KG6M]*V@"3KN,.6(\\,^:81\[>*Q;D5>[:Y[/'&)T\
+M+O`+.,?6Q>Z3!%TNM:N9/_)LXVVYWZM/<CW)K#1)%^^KT;UL//U.FN?C$WU#
+ML&&/+N-'M0;M<<0!8QG^\!MY]!%XK8=5SWJ*!%-9+H%6^[:N;4Q73N'OFMIQ
+M8\L<!)Y_7=GFE^DRVB#8H(6JYK]/(I14R(Y\+/DK56Z<^G/>L6V?/][MSXKO
+M6ZG5NO<FG3I:V*+46?.R'HYS'TZ>AJ++W09XHB\1X<>_Z]$;GL[DWQPI;2Q`
+M^6\9E$_CFNU_0C4!PTL9G54NIHAGLS:LSS5+H=7/12W%P5X'_WJJAP5?!:N[
+MFCFB:9#6,K'UX)>0D'S9;&>^WL^UYMO:OV:%>*>KZL$KI*79Z-CR?VCJ)&*@
+M3#5B*I!H%MXZ^:LG+#W:?-+<$!_[F?--N*W"#[K"UAOOWX(3@HU]6'9JZ7=J
+MS2UK:*='74^D;[>:WP>QTS2IKU?E9JF"GMC/,`Y.6^Q8_#XH=+>6:V^H+%[N
+M@#K4J"GM$#5P'J(,O:1PWOO@^\0?Z.![UP\ZMR0X[JE[RQ]&//7W])_Z6-;!
+M$N@8V\&[/I1&7=Q;=N*X\&[272M*L[1=QZN4BMTK%0PMXBV]<MN/@M*E#XWT
+M,Z<MCI-,>[56#Q6C=Z/J^@B:?+&4N7NZ&Y[Z@2I__),.%N8HX[/^_O^^]6`\
+M_RLAE?/]7Y]#=.?)IVE=NN;W>=X,4Y[F:Z45^7:X\]F;I.F77$CRXM7&[:>F
+M.X-FZU%[9]C'MV:1I\53^/)/TZ<%CGR5"!]+:W/,)FR="!U2NH:MZTC!>MU'
+M>[04$*@ZJ:@VWX^.O7)ZV@;MYZH]B=DGU$"EGDYM.Y8LOJ%F(DO[JK'O<>F>
+M4NM+>_SG-`#O,G@FM-EBXZ/<D\=O'F\=]FR/W]1EO4GJ=:KW(^_N];\</:_+
+MNSLGZ:8^9G>C\])U8.O6V\%+)^F@'CU=O\K1?LG!0IS9#R5&94FC:PC]/4VL
+M&[EGM*+TZGW+[Q5LTC+X;-5[FZ>>UZ"G,S+3B;;_#/A!YZ%W\<75%FKS<E><
+M#CIOM-'40M<WS>)W%FZ'74LW',X^_%F7YM/5,K@R'S:;+8NHR50ODZX;DQVV
+MD-TK]35?K>M6R[*7%!./]C@M3M$>X+U[DE_[.+]?UEG(U4P1X,,MWX96'=U>
+M>,SN[%?91M2]#1W,EE=)8O#'66IJ+STKQ=`V$3:'*3AXLO#'+18Z(/SVMY;>
+M7E/?@RPHI#SJ9DZ.N:0H[@?N;>B"=-?K<Q;^+PQ?+W>LFX_FG'UGY$:8P4;H
+MBS.J2M>+=O=$-]'6=RHR9BVHL-2C24QK66[M@G,+NW73=^U=<-U&T>=R:8Z6
+M;S<XR[]&V<53@7!O8Z*%"T=-VSL47XHZ!]DS4XG^#'Z;DLI?<-U1T@.WDB-#
+M:&TZ"&+14-MPA3R'!Z/@Y^9J,:]IHK8[_/UY+G*,>""[#,]L?B+4$NJ&^"[B
+M^+QS+489X[(EY,GCLNV72<?O8BGDF?B\<>NK*93?2=0R=87=5`[;$4TKHX+7
+M!E_J.G.]BYW,V._RJ]W:.JPZ><NO,-5I;]_H_%M5)J:.NC*:7P7SJPY-H.NX
+M+0Y4_2Y/F[4AG:DMK#5_#DAN>$4X-4F7^<4,O/REHJE0LW=O/K#[TQJ;3_W3
+MTEEUR-Q*FW_X%16ZTL4*K3=6\7ND<&'AG@MZG_<W;3RTK+?2-Y;WJ?9/>$[2
+M,K*/:9<O:BA\SM)Z?4N\U1$<0V<%?>M!T:T<UK/UNQ,EY<41OHEHXB?99]3Q
+MU2I^K`8*7L#26*H>BG00+P42Y0[)ETA=(3;'+N<,=6SUM/\)4OFUAS-3^&LS
+M`0YJ.C^Y"7?#^N/A@F;4_SV<&KH6/,_%YPSL,+YL.*Y5W-H-WMZY<BO8FX=)
+MYX6WIOVX-?6+YP4Z87`>*TM5`:70J<7]Y.?$P^?5%$9U)^:NO/1M8\\63[WZ
+MMW^LA6UR30"1>8$Z+P?U3A7^!.O]3]WH4WQ0@S!7FPZU,W:R;F.S3?J=?VN]
+MFUMC>I5N8O<:@9^+WUK2A_/?BS7C`^>:>'-Z`;>L`NG9&(^B8WJ;U&D$.I[\
+M-_2M:S7`2BTW%&-H"#3HM$!PMK>R;?CP6Z5NK)5)7.[^"/<N=?TSGMFI-24&
+MGOBOT1HJBX]F[NS_@,7I>MI1O5:K-29-U"<J?P!S<R:*^"Y?:?Z^6!RV"V@T
+MQ$K\>/F4J9_5;WT1![O3RQ3D;F+]GZKR4_JX[S%.W,I9-^@6S>Q<=R:+NM!V
+MJN7EQ8J3$=@HJYZK6*;[4F'I7]$)"ND5-^DBA@E_;^.TC:ZT="MV"T`4ZG%6
+M"67MKWG!-#)9H%MQN6UE7H4FV$E52Q2X"9WN]@NG8YA%*0W?8,5P)!J"\IW%
+M#AFTQC_6O/!8.A_'!JJ"Q75//*_.F<Z\=SAPQWUV*&UX:8[/<V)@IIB\_?HZ
+M]J[)FQIQZ;HFX9A#IP-*3$V;3.,Z8M=L>VTP$_'-.MFM;>'N/@M4SM>Z4DEL
+M>>G)$8(U#I@J:D(4DR[3<0P3TAGL\K@Q;GDG!GQ>'5P_DR/,\'+?>X[;>H\M
+M&V:DVVIUW4;W)Q4KK]]M6V;<O3.L2"-`PUJC5=76]H)@ZG!<1*\K+7VKYR*.
+M`)H^GL6>E_+<M/=7-+IHZ%L;\N#/<4-(\[L\)EMZ2'1YY1:NW^._:3-:IYBL
+MC1DRUBZVLOU`-SMMF'1EIM+S+5>5XGP=W*?J03J?Q$BZJ5:.IXK%O:K6_Y_N
+M.A[X)O0]VM]M\K=R,BW<$>_BKV(*9$T(VN./FOM'6MK9-5"<BB$5]J@4^BFL
+M,BZ9*6AXNK0[L+-SN9^`<6[!F>I_3D*;M'0C\?9UYPENFDHYZ;\%>F';67)X
+M[.D:(H7)VY'T1*$-.0_>\F.L-6>YNFX^2>EOX_);D=:+-%TQ=6G2/J9!I_E3
+MG(>"ET[=CK?)AS1U#C4H;[6_S/J[WTVX?K?5^/;_K'YC^<D_/__[_.C@````
+M````2=D^```!)V3X!)V3X````"3LGP`````````6```````,X`"P``````).
+MR?```````````````````````````````````"3J3X``D[)\D[)\`````2=D
+M^``````````````````).R?````$G9/@```````D[)\D[)\`````````````
+M`D[)\````````"3LGP`DZD^````````````````````````````````````,
+M(``````````````!)V3X`````````````"3LGP```````````````$G9/@``
+M`!)V3X```````````!)V3X```$G9/R=D^D[)\`2=D^``S`!)V3X````).R?`
+M`````````S``D[)\`````````````"3LGP``````````````````````````
+M`````````L6```````,X`"P``````).R?```````````````````````````
+M````````"3J3X``D[)\D[)\`````2=D^``````````````````).R?````$G
+M9/@```````D[)\D[)\``````````````D[)\````````"3LGP`DZD^``````
+M``````````````````````````````,(``````````````!)V3X`````````
+M````"3LGP```````````````$G9/@```!)V3X```````````!)V3X```$G9/
+MR=D^D[)\`2=D^``S`!)V3X````).R?``````````S``D[)\`````````````
+M"3LGP```````````````````````````````````L6```````,X`"P``````
+M).R?```````````````````````````````````"3J3X``D[)\D[)\`````2
+M=D^``````````````````).R?````$G9/@```````D[)\D[)\```````````
+M```D[)\````````"3LGP`DZD^```````````````````````````````````
+M`,(``````````````!)V3X`````````````"3LGP```````````````$G9/@
+M```!)V3X```````````!)V3X```$G9/R=D^D[)\`2=D^``S`!)V3X````).R
+M?``````````S``D[)\`````````````"3LGP````````````````````````
+M```````````L6```````,X`"P``````).R?`````````````````````````
+M``````````"3J3X``D[)\D[)\`````2=D^``````````````````).R?````
+M$G9/@```````D[)\D[)\``````````````D[)\````````"3LGP`DZD^````
+M````````````````````````````````,(``````````````!)V3X```````
+M``````"3LGP```````````````$G9/@```!)V3X```````````!)V3X```$G
+M9/R=D^D[)\`2=D^``S`!)V3X````).R?``````````S``D[)\```````````
+M``"3LGP```````````````````````````````````L6```````,X`"P````
+M``).R?```````````````````````````````````"3J3X``D[)\D[)\````
+M`2=D^``````````````````).R?````$G9/@```````D[)\D[)\`````````
+M`````D[)\````````"3LGP`DZD^`````````````````````````````````
+M```,(``````````````!)V3X`````````````"3LGP```````````````$G9
+M/@```!)V3X```````````!)V3X```$G9/R=D^D[)\`2=D^``S`!)V3X````)
+M.R?``````````S``D[)\`````````````"3LGP``````````````````````
+M`````````````L6```````,X`"P``````).R?```````````````````````
+M````````````"3J3X``D[)\D[)\`````2=D^``````````````````).R?``
+M``$G9/@```````D[)\D[)\``````````````D[)\````````"3LGP`DZD^``
+M``````````````````````````````````,(``````````````!)V3X`````
+M````````"3LGP```````````````$G9/@```!)V3X```````````!)V3X```
+M$G9/R=D^D[)\`2=D^``S`!)V3X````).R?``````````S``D[)\`````````
+M````"3LGP```````````````````````````````````L6```````,X`"P``
+M````).R?```````````````````````````````````"3J3X``D[)\D[)\``
+M```2=D^``````````````````).R?````$G9/@```````D[)\D[)\```````
+M```````D[)\````````"3LGP`DZD^```````````````````````?_I+V3Q(
+MT\2BNG+`G[^<#:=#P````````````!X```````````````O;\```````````
+M``!>WX```````````````"]OP````O;\````````````O;\```"]O[V_7M^`
+M+V_``<`%[?@````O;\`````````#@`7M^`````````````!>WX``````````
+M`````````````````````````9@``````'P`#``````!>WX`````````````
+M``````````````````````7J_``%[?E[?@````"]OP`````````````````!
+M>WX````O;\```````%[?E[?@`````````````%[?@````````7M^`%ZOP```
+M````````````````````````````````!X```````````````O;\````````
+M`````!>WX```````````````"]OP````O;\````````````O;\```"]O[V_7
+MM^`+V_``<`%[?@````O;\`````````#@`7M^`````````````!>WX```````
+M````````````````````````````9@``````'P`#``````!>WX``````````
+M`````````````````````````7J_``%[?E[?@````"]OP```````````````
+M``!>WX````O;\```````%[?E[?@`````````````%[?@````````7M^`%ZOP
+M```````````````````````````````````!X```````````````O;\`````
+M````````!>WX```````````````"]OP````O;\````````````O;\```"]O[
+MV_7M^`+V_``<`%[?@````O;\`````````#@`7M^`````````````!>WX````
+M````````%[?@``````!>WX`````````````!>K\``!>WX`````/`````````
+M`````````"]OP```!>WX```````+V_+V_``````````7M^```"]OP```````
+M`+V_`"]7X````````````````````````````````````\``````````````
+M`7M^``````````````O;\```````````````!>WX````7M^````````````7
+MM^```!>W][?KV_`%[?@`.`"]OP````7M^`````````!P`+V_````````````
+M``O;\```````````````````````````````````,P``````#X`!@``````O
+M;\```````````````````````````````````+U?@`"]OR]OP````!>WX```
+M```````````````O;\````7M^```````"]OR]OP`````````````"]OP````
+M````+V_`"]7X````````````````````````````````````\```````````
+M````7M^``````````````O;\```````````````!>WX````7M^``````````
+M``7M^```!>W][?KV_`%[?@`.`"]OP````7M^`````````!P`+V_`````````
+M`````O;\```````````````````````````````````,P``````#X`!@````
+M``O;\```````````````````````````````````+U?@`"]OR]OP````!>WX
+M``````````````````O;\````7M^```````"]OR]OP`````````````"]OP`
+M```````+V_`"]7X````````````````````````````````````\````````
+M```````7M^``````````````O;\```````````````!>WX````7M^```````
+M`````7M^```!>W][?KV_`%[?@`.`"]OP````7M^`````````!P`+V_``````
+M````````O;\```````````````````````````````````,P``````#X`!@`
+M`````O;\```````````````````````````````````+U?@`"]OR]OP````!
+M>WX``````````````````O;\````7M^```````"]OR]OP`````````````"]
+MOP````````+V_`"]7X````````````````````````````````````\`````
+M``````````7M^``````````````O;\```````````````!>WX````7M^````
+M````````7M^```!>W][?KV_`%[?@`.`"]OP````7M^`````````!P`+V_```
+M```````````O;\```````````````````````````````````,P``````#X`
+M!@``````O;\```````````````````````````````````+U?@`"]OR]OP``
+M``!>WX``````````````````O;\````7M^```````"]OR]OP````````````
+M`"]OP````````+V_`"]7X````````````````````````````````````\``
+M`````````````7M^``````````````O;\```````````````!>WX````7M^`
+M```````````7M^```!>W][?KV_`%[?@`.`"]OP````7M^`````````!P`+V_
+M``````````````O;\```````````````````````````````````,P``````
+M#X`!@``````O;\```````````````````````````````````+U?@`"]OR]O
+MP````!>WX``````````````````O;\````7M^```````"]OR]OP`````````
+M````"]OP````````+V_`"]7X````````````````````````````````````
+M\```````````````7M^``````````````O;\```````````````!>WX````7
+MM^````````````7M^```!>W][?KV_`%[?@`.`"]OP````7M^`````````!P`
+M+V_``````````````O;\```````````````````````````````````,P```
+M```#X`!@``````O;\```````````````````````````````````+U?@`"]O
+MR]OP````!>WX``````````````````O;\````7M^```````"]OR]OP``````
+M```````"]OP````````+V_`"]7X`````````````````````````````````
+M```\```````````````7M^``````````````O;\```````````````!>WX``
+M``7M^```````#^!$_L_$HKIR@3W\%I0\````+V_````O;^]OU[?@"]OP`'`!
+M>WX````+V_``````````X`%[?@`````````````7M^``````````````````
+M`````````````````&8``````!X`!@``````O;\`````````````````````
+M``````````````+U?@`"]OR]OP````!>WX``````````````````O;\````7
+MM^```````"]OR]OP`````````````"]OP````````+V_`"]7X```````````
+M`````````````````````````^```````````````+V_``````````````7M
+M^````````````````O;\````+V_````````````+V_````O;^]OU[?@"]OP`
+M'`!>WX````+V_``````````X`%[?@`````````````7M^```````````````
+M````````````````````&8``````!X`!@``````O;\``````````````````
+M`````````````````+U?@`"]OR]OP````!>WX``````````````````O;\``
+M``7M^```````"]OR]OP`````````````"]OP````````+V_`"]7X````````
+M````````````````````````````^```````````````+V_`````````````
+M`7M^````````````````O;\````+V_````````````+V_````O;^]OU[?@"]
+MOP`'`!>WX````+V_``````````X`%[?@`````````````7M^````````````
+M```````````````````````&8``````!X`!@``````O;\```````````````
+M````````````````````+U?@`"]OR]OP````!>WX``````````````````O;
+M\````7M^```````"]OR]OP`````````````"]OP````````+V_`"]7X`````
+M```````````````````````````````^```````````````+V_``````````
+M````7M^````````````````O;\````+V_````````````+V_````O;^]OU[?
+M@"]OP`'`!>WX````+V_``````````X`%[?@`````````````7M^`````````
+M``````````````````````````&8``````!X`!@``````O;\````````````
+M```````````````````````+U?@`"]OR]OP````!>WX`````````````````
+M`O;\````7M^```````"]OR]OP`````````````"]OP````````+V_`"]7X``
+M``````````````````````````````````^```````````````+V_```````
+M```````7M^````````````````O;\````+V_````````````+V_````O;^]O
+MU[?@"]OP`'`!>WX````+V_``````````X`%[?@`````````````7M^``````
+M`````````````````````````````&8``````!X`!@``````O;\`````````
+M``````````````````````````+U?@`"]OR]OP````!>WX``````````````
+M````O;\````7M^```````"]OR]OP`````````````"]OP````````+V_`"]7
+MX````````````````````````````````````^```````````````+V_````
+M``````````7M^````````````````O;\````+V_````````````+V_````O;
+M^]OU[?@"]OP`'`!>WX````+V_``````````X`%[?@`````````````7M^```
+M````````````````````````````````&8``````!X`!@``````O;\``````
+M`````````````````````````````+U?@`"]OR]OP````!>WX```````````
+M```````O;\````7M^```````"]OR]OP`````````````"]OP````````+V_`
+M"]7X````````````````````````````````````^```````````````+V_`
+M`````````````7M^````````````````O;\````+V_````````````+V_```
+M`O;^]OU[?@"]OP`'`!>WX````+V_``````````X`%[?@`````````````7M^
+M```````````````````````````````````&8``````!X`!@``````O;\```
+M````````````````````````````````+U?@`"]OR]OP````!>WX````````
+M``````````O;\````7M^```````"]OR]OP`````````````"]OP````````+
+MV_`"]7X````````````````````````````````````^```````````````+
+MV_``````````````7M^````````````````O;\````+V_````````````+V_
+M````O;^]OU[?@"]OP`'`!>WX````+V_``````````X`%[?@`````````````
+M7M^```````````````````````````````````&8``````!X`!@``````O;\
+M```````````````````````````````````+U?@`"]OR]OP````!>WX`````
+M`````````````O;\````7M^```````"]OR]OP`````````````"]OP``````
+M``+V_`"]7X````````````````````````````````````^`````````````
+M``+V_``````````````7M^````````````````O;\````+V_````````````
+M+V_````O;^]OU[?@"]OP`'`!>WX````+V_``````````X`%[?@``````````
+M```7M^```````````````````````````````````&8``````!X`!@``````
+MO;\```````````````````````````````````+U?@`"]OR]OP````!>WX``
+M````````````````O;\````7M^```````"]OR]OP`````````````"]OP```
+M`````+V_`"]7X````````````````````````````````````^``````````
+M`````+V_``````````````7M^````````````````O;\````+V_`````````
+M```+V_````O;^]OU[?@"]OP`'`!>WX```']'_`95<H(_P=*/`O;\````````
+M`#@`7M^`````````````!>WX```````````````````````````````````9
+M@``````'@`&``````"]OP```````````````````````````````````O5^`
+M`+V_+V_`````%[?@`````````````````"]OP```!>WX```````+V_+V_```
+M```````````+V_`````````O;\`+U?@`````````````````````````````
+M``````#X```````````````O;\`````````````!>WX```````````````"]
+MOP````O;\````````````O;\```"]O[V_7M^`+V_``<`%[?@````O;\`````
+M````#@`7M^`````````````!>WX`````````````````````````````````
+M``9@``````'@`&``````"]OP```````````````````````````````````O
+M5^``+V_+V_`````%[?@`````````````````"]OP```!>WX```````+V_+V_
+M``````````````+V_`````````O;\`+U?@``````````````````````````
+M`````````#X```````````````O;\`````````````!>WX``````````````
+M`"]OP````O;\````````````O;\```"]O[V_7M^`+V_``<`%[?@````O;\``
+M```````#@`7M^`````````````!>WX``````````````````````````````
+M`````9@``````'@`&``````"]OP`````````````````````````````````
+M``O5^``+V_+V_`````%[?@`````````````````"]OP```!>WX```````+V_
+M+V_``````````````+V_`````````O;\`+U?@```````````````````````
+M````````````#X```````````````O;\`````````````!>WX```````````
+M````"]OP````O;\````````````O;\```"]O[V_7M^`+V_``<`%[?@````O;
+M\`````````#@`7M^`````````````!>WX```````````````````````````
+M````````9@``````'@`&``````"]OP``````````````````````````````
+M`````O5^``+V_+V_`````%[?@`````````````````"]OP```!>WX```````
+M+V_+V_``````````````+V_`````````O;\`+U?@````````````````````
+M```````````````#X```````````````O;\`````````````!>WX````````
+M```````"]OP````O;\````````````O;\```"]O[V_7M^`+V_``<`%[?@```
+M`O;\`````````#@`7M^`````````````!>WX````````````````````````
+M```````````9@``````'@`&``````"]OP```````````````````````````
+M````````O5^``+V_+V_`````%[?@`````````````````"]OP```!>WX````
+M```+V_+V_``````````````+V_`````````O;\`+U?@`````````````````
+M``````````````````#X```````````````O;\`````````````!>WX`````
+M``````````"]OP````O;\````````````O;\```"]O[V_7M^`+V_``<`%[?@
+M````O;\`````````#@`7M^`````````````!>WX`````````````````````
+M``````````````9@``````'@`&``````"]OP````````````````````````
+M```````````O5^``+V_+V_`````%[?@`````````````````"]OP```!>WX`
+M``````+V_+V_``````````````+V_`````````O;\`+U?@``````````````
+M`````````````````````#X```````````````O;\`````````````!>WX``
+M`````````````"]OP````O;\````````````O;\```"]O[V_7M^`+V_``<`%
+M[?@````O;\`````````#@`7M^`````````````!>WX``````````````````
+M`````````````````9@``````'@`&``````"]OP`````````````````````
+M``````````````O5^``+V_+V_`````%[?@`````````````````"]OP```!>
+MWX```````+V_+V_``````````````+V_`````````O;\`+U?@```````````
+M````````````````````````#X```````````````O;\`````````````!>W
+MX```````````````"]OP````O;\````````````O;\```"]O[V_7M^`+V_``
+M<`%[?@````O;\`````````#@`7M^`````````````!>WX```````````````
+M````````````````````9@``````'@`&``````"]OP``````````````````
+M`````````````````O5^``+V_+V_`````%[?@`````````````````"]OP``
+M`!>WX```````+V_+V_``````````````+V_`````````O;\`+U?@````````
+M```````````````````````````#X```````````````O;\`````````````
+M!>WX```````````````"]OP````O;\````````````O;\```"]O[V_7M^`+V
+M_``<`%[?@````O;\`````````#@`7M^`````````````!>WX````````````
+M```````````````````````9@``````'@`&``````"]OP```````````````
+M````````````````````O5^``+V_+V_`````%[?@`````````````````"]O
+MP```!>WX```````+V_+V_``````````````+V_`````````O;\`+U?@`````
+M``````````````````````````````#X```````````````O;\``````````
+M```!>WX```````````````"]OP````O;\````````````O;\```"]O[V_7M^
+M`+V_``<`%[?@````O;\`````````#@`7M^``````'\!'_`95<H(_P=*/````
+M```%[?@``````````````````````````````````!F```````>``8``````
+M+V_```````````````````````````````````"]7X``O;\O;\`````7M^``
+M````````````````+V_````%[?@```````O;\O;\``````````````O;\```
+M`````"]OP`O5^````````````````````````````````````/@`````````
+M`````"]OP`````````````%[?@```````````````+V_````"]OP````````
+M```"]OP```+V_O;]>WX`O;\`!P`7M^````"]OP`````````.`!>WX```````
+M``````%[?@``````````````````````````````````!F```````>``8```
+M```+V_```````````````````````````````````"]7X``O;\O;\`````7M
+M^``````````````````+V_````%[?@```````O;\O;\``````````````O;\
+M````````"]OP`O5^````````````````````````````````````/@``````
+M````````"]OP`````````````%[?@```````````````+V_````"]OP`````
+M``````"]OP```+V_O;]>WX`O;\`!P`7M^````"]OP`````````.`!>WX````
+M`````````%[?@``````````````````````````````````!F```````>``8
+M``````+V_```````````````````````````````````"]7X``O;\O;\````
+M`7M^``````````````````+V_````%[?@```````O;\O;\``````````````
+MO;\````````"]OP`O5^````````````````````````````````````/@```
+M```````````"]OP`````````````%[?@```````````````+V_````"]OP``
+M`````````"]OP```+V_O;]>WX`O;\`!P`7M^````"]OP`````````.`!>WX`
+M````````````%[?@``````````````````````````````````!F```````>
+M``8``````+V_```````````````````````````````````"]7X``O;\O;\`
+M````7M^``````````````````+V_````%[?@```````O;\O;\```````````
+M```O;\````````"]OP`O5^````````````````````````````````````/@
+M``````````````"]OP`````````````%[?@```````````````+V_````"]O
+MP```````````"]OP```+V_O;]>WX`O;\`!P`7M^````"]OP`````````.`!>
+MWX`````````````%[?@``````````````````````````````````!F`````
+M``>``8``````+V_```````````````````````````````````"]7X``O;\O
+M;\`````7M^``````````````````+V_````%[?@```````O;\O;\````````
+M``````O;\````````"]OP`O5^```````````````````````````````````
+M`/@``````````````"]OP`````````````%[?@```````````````+V_````
+M"]OP```````````"]OP```+V_O;]>WX`O;\`!P`7M^````"]OP`````````.
+M`!>WX`````````````%[?@``````````````````````````````````!F``
+M`````>``8``````+V_```````````````````````````````````"]7X``O
+M;\O;\`````7M^``````````````````+V_````%[?@```````O;\O;\`````
+M`````````O;\````````"]OP`O5^````````````````````````````````
+M````/@``````````````"]OP`````````````%[?@```````````````+V_`
+M```"]OP```````````"]OP```+V_O;]>WX`O;\`!P`7M^````"]OP```````
+M``.`!>WX`````````````%[?@``````````````````````````````````!
+MF```````>``8``````+V_```````````````````````````````````"]7X
+M``O;\O;\`````7M^``````````````````+V_````%[?@```````O;\O;\``
+M````````````O;\````````"]OP`O5^`````````````````````````````
+M```````/@``````````````"]OP`````````````%[?@```````````````+
+MV_````"]OP```````````"]OP```+V_O;]>WX`O;\`!P`7M^````"]OP````
+M`````.`!>WX`````````````%[?@````````````````````````````````
+M``!F```````>``8``````+V_```````````````````````````````````"
+M]7X``O;\O;\`````7M^``````````````````+V_````%[?@```````O;\O;
+M\``````````````O;\````````"]OP`O5^``````````````````````````
+M``````````/@``````````````"]OP`````````````%[?@`````````````
+M``+V_````"]OP```````````"]OP```+V_O;]>WX`O;\`!P`7M^````"]OP`
+M````````.`!>WX`````````````%[?@`````````````````````````````
+M`````!F```````>``8``````+V_`````````````````````````````````
+M``"]7X``O;\O;\`````7M^``````````````````+V_````%[?@```````O;
+M\O;\``````````````O;\````````"]OP`O5^```````````````````````
+M`````````````/@``````````````"]OP`````````````%[?@``````````
+M`````+V_````"]OP```````````"]OP```+V_O;]>WX`O;\`!P`7M^````"]
+MOP`````````.`!>WX`````````````%[?@```````````#^`1_"\2RMN6#O^
+MAZ6/```````````````````````,P``````#@`&``````"]OP```````````
+M````````````````````````O5^``+V_+V_`````%[?@````````````````
+M`"]OP```!>WX```````+V_+V_``````````````+V_`````````O;\`+U?@`
+J``````````````````````````````````#P```````*GZ#$/7L`0`<`
+`
+end
diff --git a/libarchive/test/test_read_format_rar_noeof.rar.uu b/libarchive/test/test_read_format_rar_noeof.rar.uu
new file mode 100644
index 000000000000..7cf88e7c6248
--- /dev/null
+++ b/libarchive/test/test_read_format_rar_noeof.rar.uu
@@ -0,0 +1,5 @@
+begin 644 -
+M4F%R(1H'`,^0<P``#0````````"$4G0@D#(`%````!0````#0J+(OK=VVCX4
+M,`@`I($``'1E<W0N='AT@`BW=MH^MW;:/G1E<W0@=&5X="!D;V-U;65N=`T*
+`
+end
diff --git a/libarchive/test/test_read_format_rar_ppmd_lzss_conversion.rar.uu b/libarchive/test/test_read_format_rar_ppmd_lzss_conversion.rar.uu
new file mode 100644
index 000000000000..a41b007a0d23
--- /dev/null
+++ b/libarchive/test/test_read_format_rar_ppmd_lzss_conversion.rar.uu
@@ -0,0 +1,3930 @@
+begin 644 -
+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
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````8``````````````````*$OPP`Q?VO4_^?______________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M_______________^@$?\B__K'_I_________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M_________________________________________________________Z!'
+M_(O_ZQ_Z?___________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M______________________________________^@3`'1%0R-%\6=F]S/A7.S
+M5W8"T;9`[O=G2*&IP\3W2`(833>H2:8/`,[&-M/&Y!GWK4@<D`9+\//#CQL>
+M,-D75WT2#SF<NKJ[NKJZ\=Y\2K^$7ZOU>#E*Z5VOR5^KBL``````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````````````````````````````>K]
+M7T\[_GZN?T/^/I_GT/4O.Q?SYW0Y_K]^YZGQ].4NQT.+`?0]2.AT80FY^38M
+MC-UH&0]R&?>\/3Z/1^X4ZT^!N4Z4:9*:-$CN+!,AN>Z5('3INPWS_NJT>I`Q
+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
+MT;6[0R[0Y+&X>-&5*QYNCCJ;<WU-K2NWC1F.X@]:,YCDB05]\JK(1(:L@[&W
+MC[JL_"F?*N,%&DA]2?=TI8T@^XL&149^2<BG8ZO3_OIPHZ+U8;S.]U.G'\"P
+M7.1:A`^22;?A\MOV=_1[/4TX4F2Z,'0#H]KK_7D2HNGW?<#O=O3]D^SNZ'L7
+M1ZWNGU;G,OA\4?^F_&,[%R65$^*GIFY'M_*R<].=CZ+\,;W(;5BA1TK@[=_(
+M'NI*(.[=7+D9VR)6IV=19U8C"[HU.<QN9J5WY`7=25AKC)GFUP))-IG;$2[8
+MHT.WMZTJA2P`<*UL='CJ2U>GQV.5<O#5O5V.?:V0/-?F(K#<J='3\"=W;==P
+M'`"UX%SJO[17QI["I]`&>63LCPVSZ%<=8_&<$7YI5O82X$^Z<##T4I_X<RDS
+MGB;#97B_Q;L7>S;/-5[M4JN)*<.,PUX=<@21*+8?\@!8`NJL$\VJOXQXJ9_D
+M3.WKH>4UTR@[R57^/8HS5-09>'[^!EC_/B&H.[#.Q3A=.O\</0`=G(/&Y;(.
+MQEQI7,/5U67I!H=R(LY]RA\K)THR__[3U$``````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````/_9+R/Z,7]KU/_G_____
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M_________________________H!'_(O_ZQ_Z?_______________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M______^@1_R+_^L?^G__________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M________________________________________________H$?\B__K'_I_
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M_____________________________Z!,C_A?VNV[3!\`````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`'50AS509H$MI%\/F/4^T]A]:GY61>W-$D=K*48D@J19KZ-UX@W5I(05CF6[
+M[(CXM-/'Q^C,.*&X3^7'/##8'_F>E+Z+.!7!K[5XEI)C,E`)2K9=PC^3W!*>
+M/=^JWKV#J"(QKCPP6:'6E9)Y.J(:%'W-59W0K-G+@+-9/@"A""<GR:A@3A.P
+M``````&33]-UZFL!1#TW+M"JKMBU)9S'')>&TDQUZZ*Z!(7K==%W;K&"$J@J
+MALS;<TVQBKXTKA=#*Y(`#AJ#EY0$%.@;"IQD$11"'Q4>75>P>"E5\-;N4E/M
+M0A%P9LKU*,B)FLB7(LC%+GP-Z^OAE/&,`'46Y6\TGV,SB'PST\;25YCUTI@)
+M"8'KR<U<*PA&](,1GI'N)KIH!Z:3E+K)N7)USOZ@\H4M!\3:X)%\=LBS"ZCD
+M6YK)Z[B6G^+C,A,>_&OC2FE?A7ZGV6/IWY1];IKK:><9*`-O+^*CC4T2?\3C
+M_M'7BFGLD;Y)8-WV+?F70"PKR_K2?DS;!F2K#Q)U^)[$X!XV5*%UYZ=7A]'N
+MJRJW(KWG&Y:)'M=LW^%%XYMC7J/SQ2BQFE=9%4H:KU#/U&Z)XW&/F1DY^*&?
+MKF)^:[Y;RQ8402:`0</+!;+PW_N?@5X6Z@WL^!Y%BTC-P"<?H(!?I(^8GY=@
+MU`LHF7*Y!!E[`L+.<=TADK8>.G!SK912WR+3;6S1-%I+>%40ZT<0YQAHQO;*
+M\@_]:\Z&\O@X6JRH!7L'0]=%F\#4G+=W3O;]?@ST(*H"J*!>=9,1I"NM^<5$
+M,?M3##_F0@61;>:`LF\VDL')];&<]T56:4]2!OY.9(`/*6V>1@]'8#"*GU77
+M;#NK:^GSZ[&-$_(<R@/Y!>WYR<(5I51ZVR&>0E=MYM$UWTOV5=5'&,C<D_>R
+MBKOW;AR"NES,-/?Z>M505*><)/.8)UL,A0CY:<H^]$D[**0$0_2(N!BT$_:`
+MT`\&+E2X30\#D6B2O/V[A#:UK_T]K+T?9MN%3A#[MG+;V8Z!'5BZILB@;Q<<
+M<G0PH8//]LG4,QQU]++IPI1WOLX05%SZVV@W\S!H.OB)>\.+<F#/K-E7&WE<
+M%YM>IC`GC%8_TJ5_HG*`HW#K&]2WB/L(8";`73ZE8Y;1D(J@(T,=])2H!$P7
+M0R:0/B15*(]<*@J1D[43+>O$MZ$A&')!G0?"`I/RWJEW*L#<#D!I$\V:\",/
+M[J!XYT&0)B+9L6#"$>!0#V`<HEBN,5<W;Q5\J8+=U%]8TT1M/@["X-7T<)Z>
+M*;I#]B(J/TC[I-H4P\V$J3&_7VBB^Z,]'9,8PUO5QM2^Y5?P<O:T28Q10CUV
+MAMOL7GAFL=;P#WD,GL[IQ!T3/%1LD@(`2+V7GY,VWYF;ED6]`)N81B9;<O0>
+M1\:_.IO%T4N"#U2-1H8Z]$6"3B%^+CQZ7CM4]>!+A*F1!\CK@_PCBB3,5V$W
+MFK@M_W+2%)';;*J7&Y01`W``3(_X7]KVPYX0A2`H3^W1````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M``````````````%`2_#`#%_:]3_Y________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M__________________________________________________________Z`
+M1_R+_^L?^G__________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M________________________________________H$S/],17/Z59'_P`````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````(```````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````'!,`9$53(T7Q5F;[,_%5R8N9`6#;(',YDX1
+M0Q.'4\P@"&$PSB$FF#V!OD8VT]MR#/_42!R0!DOIUT[>VQ[89(N+GPD'O6]7
+M5U=W5U===[_)5Z$7E>5T:I72NUXE?QTE8```````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````````````````!ZOS?3SO^?JY_0_
+MX^G^?0]2\[%_/G=#G^OW[GJ?'TY2['0XL!]#U(Z'1A";GY-BV,W6@9#W(9][
+MP]/H]'[A3K3X&Y3I1IDIHT2.XL$R&Y[I4@=.F[#?/^ZK1ZD#&6'[\,TB^]<>
+M9\"Y-'I=B--7:1>90X9!B^ZVMRLSBZ9H3>*UL(X9WO3T;88(NBWJ;FWYMCU:
+M_`%SO[.K)IJ?V@]X?H^G?YY_.^CG18D4%>CL=WJ];U#S>YFST<_/_)_+L;'E
+M@R"(8&S]S/W[H'VO3[-G[XE?]16`H7C7$6F?`7.ERJ_\NC3.&L[XU<8.@9'&
+ML'1%!-IUL?&T8$DS.,.S_X.*MFY1YV-X9_`(S_AWXIX>G6]DL&G_OS_IAR`Z
+M?BI3QZ.HD:>+P"$%C35TX0*EI^YVGV?T]ST<W3ZT%T"0#B.5@&JY<>4:L"3(
+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
+M!PK6QT>.I+5Z?'8Y5R\-6]78Y]K9`\U^8BL-RIT=/P)W=MUW`<`+7@7.J_M%
+M?&GL*GT`9Y9.R/#;/H5QUC\9P1?FE6]A+@3[IP,/12G_AS*3.>)L-E>+_%NQ
+M=[-L\U7NU2JXDIPXS#7AUR!)$HMA_R`%@"ZJP3S:J_C'BIG^1,[>NAY373*#
+MO)5?X]BC-4U!EX?OX&6/\^(:@[L,[%.%TZ_QP]`!V<@\;EL@[&7&E<P]759>
+MD&AW(BSGW*'RLG2C+__M/40`````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M```````````````````````````?^TO(_HQ?VO4_^?__________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M___________^@$?\B__K'_I_____________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M_____________________________________________________Z!'_(O_
+MZQ_Z?_______________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M__________________________________^@1_R+_^L?^G______________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M________________H$?\B__K'_I_________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M_____________________________________________]"'A_UBY2R"4]W"
+ML*RE:_OGG3#+\L@,>,PN7D[&4009/5G@?.;JM:BXCPHCK]VV<T,.3>[!W!8P
+MYAI3ZHH(AMZ-VR@&&VJ'#SQX0QE)?R4N3VT'614`IIGL^R($79%MI#B-X4CY
+M2<,-?%!I-[HQ#<T2K08&<KK;P1)6"&,)P#]*3M`6Y.=>M]PYYZ?6SOAM+5LW
+MF&<#GI93057E-9"T'5(%972#)X_X&MZ%%<J"NOIY_OUK2@9"Z7'@(^UR&T[#
+M+P]D-$_7G4<D8W:7;LI=9VN1ARH&626N<A%DLZ$'=G_JPJ73$6EEM)]_^@:C
+M[$G:9TAWFSF*0;F,MH?R-J_G#M3>>,"#R0K[^%DUAQ_L=6WC_=;3^$B&IX@7
+M6#\FJ!/@DO,_:Q4&@$=1%+9L9'QX-`*25C]4+S1EM<'\+&/@+SZ!Z;8S%PZ;
+M(==I$41B7WFK6VK3@'SRI+W`+B[X)G@4O0_W,7;CI_)#=I9$>48_/@*<Z,`#
+M1:R#@RJ\G3#6@:+N9D.6G[/":;%]QF^#*6^UW!`>[!9_P6E;Z30VBMPXWC4A
+MRUON:T2OHRGTI6-N1.9O4Q7!K2]V<9LB\ZOK`;O-+6./K\O;V>YL3U0;<@G]
+MLA2<ZT`*)K<C"YF[CY=CBNECVG&2>,Q)]X^--?L#,";:,7QJQN4A;W5Z;,Q7
+M)^5/T,L?'O%IN1VBJHSYE"_F##3P-7AKO2*<+FA"Q7SX?[-K1*!"L]\N9+:.
+M0,0/+O.NFOO8/98)R4T.=YUS'P05OYLC5UIA3#;.%]R3H86ZW$_$0R7#/%`,
+MXN35/Z7_EIY(DISE:VN1+&?5:$\/OB?_.UY_;YHU]1>KOO^1>SO&=^G!C.=(
+MELO]V=4)15`MSI")D`+9IQ_M4>U*+:4'_Z><SR,EH8COU@/V/4I4X-J_)M[,
+M2Q.1G';<E[*.*IH+V9&"@*P9YM0XX7^?&/@!AZZZ\GU1DZC&,^K)CMVF=-7A
+M38QB*DN!E-C^354>[O6X((_Q"?<;ZJ5$<+9V6$EU40\:$&L%"BJB(8<0I[G_
+M!\`J./DJ`+W_1/'D9-O>\"'>)A+>%(A^RMG>^['D=3[P%6?=^<0A-E2XHAZ&
+MM=M"/D&+NG;>+:_<_&(J-_X/$>`%(*^FHJEU.9*6OP.!?U:YX0_DSJ)4K>;9
+M<`K%R=FAF@5??,.T'?Q$9N9;%S:]GTXV!-OLL]NJ;\1'O+T/NS/BRH>?$*/D
+M[P!,C_A?VNV'/"$*0%"?VZ(`````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````````````````````````H!+\,`,
+M7]KU/_G_____________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M_____________________________________H!'_(O_ZQ_Z?___________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M__________________^@1_R+_^L?^G______________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+MH$P!T14,C1?%G9O<SX5SLU=V`M&V0.[W9TBAJ</$]T@"&$TWJ$FF#P#.QC;3
+MQN09]ZU(')`&2_#SPX\;'C#9%U=]$@\YG+JZN[JZNO'>?$J_A%^K]7@Y2NE=
+MK\E:7/38````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M``````````````````````'J_/Z>=_S]7/Z'_'T_SZ'J7G8OY\[H<_U^_<]3
+MX^G*78Z'%@/H>I'0Z,(3<_)L6QFZT#(>Y#/O>'I]'H_<*=:?`W*=*-,E-&B1
+MW%@F0W/=*D#ITW8;Y_W5:/4@8RP_?AFD7WKCS/@7)H]+L1IJ[2+S*'#(,7W6
+MUN5F<73-";Q6MA'#.]Z>C;#!%T6]3<V_-L>K7X`N=_9U9--3^T'O#]'T[_//
+MYWT<Z+$B@KT=CN]7K>H>;W,V>CGY_Y/Y=C8\L&01#`V?N9^_=`^UZ?9L_?$K
+M_J*P%"\:XBTSX"YTN57_ET:9PUG?&KC!T#(XU@Z(H)M.MCXVC`DF9QAV?_!Q
+M5LW*/.QO#/X!&?\._%/#TZWLE@T_]^?],.0'3\5*>/1U$C3Q>`0@L::NG"!4
+MM/W.T^S^GN>CFZ?6@N@2`<1RL`U7+CRC5@29!,>/[>FKU&*UKZXJCN%^S2ZG
+M-B`]*#(YVL,%!/I[OE]^<$ZO0T?!^AO"!JK##VOMU/'5V]*KP7&DM7+]\;=-
+MHXXN9'5&>>5N:/[)FET[,S)4R"@?.L\4A&IYKPQ9_[CKK%!HKUQBB(:<8,UV
+M_-'[(2!SS=.NH^VGK^Z^;W.WI:/@TY9Q7==8@:>N-D&]2`E2VI'?K^JII/-^
+MH[PL(JDL>0926S!'E@D'Z/4ZO[UJ7UYNM73C"^N^E3Y2$"7BNBU^R"E2I1D=
+MPE$H;YNE7Y)DOZ]5/HOB]7EU^R#100\_[L,6CKIZ6W`@/8WVK_FF*$_KO#;^
+MV#)]OZ?7_Q\W2O?*_E[G_M9/,#=';TL_P1M6^A<^'[J3CI_=%OP05+,6G$Q=
+M'@2Z<=_&_=!=YU9\&$S#7GH4=(8;++7&-WKO1>*]<?O!PZS:E;[4^/C2^[M7
+M]K=OH3XU/6W[SPT_;$^!+,2/#)'XROV?AR!%/R*];.>6>HEE_XWGX02:]6K/
+M]XB"R<="=Y>7(3=$=F0(J@EH6`N249QM"FA;\9"HJRY"EB(==`E[4*3L?1-+
+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
+MD]V.FR?ISQA/K2><$JVK-<E<.%URI;)R337I]S1[=S3:N9A:&A/B`KIZ78T.
+M[U>I0.=;K51D!"5P6&XK.X-<7FCV^G:8KY)?/>W\^$P="5XN3!/X&#(\7_^@
+MP7!M/_E>R#T)`7\A[5CP*9#\527(66VZXC1KJ4_P_01EUE(;>,E%8U9#;C?_
+MK[=`I/S,J146QT;9`G6QKWH]J[EYMXRF"G,N5VPDP/8>>V/*.#F?7EIX-#W]
+M=W(&B*L@:%C;=Y:K>K-][&['I>27XTLY5;,0][5#)W&S47HC[\?1B`+#)6'R
+M78UDJ_[ZT^8R71O\>F%(\(4.BZ-K=H9=H<EC</&C*E8\W1QU-N;ZFUI7;QHS
+M'<0>M&<QR1(*^^55D(D-60=C;Q]U6?A3/E7&"C20^I/NZ4L:0?<6#(J,_).1
+M3L=7I_WTX4=%ZL-YG>ZG3C^!8+G(M0@?))-OP^6W[._H]GJ:<*3)=&#H!T>U
+MU_KR)473[ON!WNWI^R?9W=#V+H];W3ZMSF7P^*/_3?C&=BY+*B?%3TS<CV_E
+M9.>G.Q]%^&-[D-JQ0HZ5P=N_D#W4E$'=NKER,[9$K4[.HLZL1A=T:G.8W,U*
+M[\@+NI*PUQDSS:X$DFTSMB)=L4:';V]:50I8`.%:V.CQU):O3X['*N7AJWJ[
+M'/M;('FOS$5AN5.CI^!.[MNNX#@!:\"YU7]HKXT]A4^@#/+)V1X;9]"N.L?C
+M."+\TJWL)<"?=.!AZ*4_\.929SQ-ALKQ?XMV+O9MGFJ]VJ57$E.'&8:\.N0)
+M(E%L/^0`L`756">;57\8\5,_R)G;UT/*:Z90=Y*K_'L49JFH,O#]_`RQ_GQ#
+M4'=AG8IPNG7^.'H`.SD'C<MD'8RXTKF'JZK+T@T.Y$6<^Y0^5DZ49?_]IZB`
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M``_]@$O(_HQ?VO4_^?__________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M_______________________________________________^@$?\B__K'_I_
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M_____________________________Z!'_(O_ZQ_Z?___________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M__________^@1_R+_^L?^G______________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________H$PAU1$,
+MS1$`%A6]G/PHZ,\&EFE%I)N[L8V+L!6VF+0Q]%A-9N;N^)%$FDE6(DTM-46F
+M7@W[O@!2?0B4HY'1,S15%(G!N;XZPPB3-1,=7.^*^)<_P@_<_OW.1'!//"8$
+M>DR`````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M```````````````````````````Y?C_Q[O\?H[OZGR_P[GIYZ^E_#YOX>G__
+M+:2Q1_Q*=6?_1I\;_^NGE>L.A>"$BG>H5PH<%D4*^S`T'!>&1:+)"4O#P*AC
+M8[^7\IS&7!O>S72H0ZD0SA*YNYG\/'#I(BP[V:2*1Q0[GKT:+:V.]*WYZ-^F
+M:7M!0R>&RG3CF5FDO72W4\LTIFB;]$X]2:^LW/),H3'Q\R^;/%>WS?'QRC>"
+MJ+MHNHC0R%HR>:20#FF]Z96/AGJWGAY\87]Z$8?U^]P\DW9=,^YPZ;16UC9_
+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
+M^:N!T8LT13%V9R1]/`+Z5.>L[IQ3MW/D^;8GW*#@`;__[3HX````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````/_E+Q/[,7]KU/_G_________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M_________________________________________________________H!'
+M_(O_ZQ_Z?___________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M______________________________________^@1_R+_^L?^G__________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________H$?\B__K'_I_____________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M_Z!,`=$5#(T7Q9V;W,^%<[-7=@+1MD#N]V=(H:G#Q/=(`AA--ZA)I@\`SL8V
+MT\;D&?>M2!R0!DOP\\./&QXPV1=7?1(/.9RZNKNZNKKQWGQ*OX1?J_5X.4KI
+M7=_DN>RP````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+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
+M3(?BJ2Y"RVW7$:-=2G^'Z",NLI#;QDHK&K(;<;_]?;H%)^9E2*BV.C;($ZV-
+M>]'M7<O-O&4P4YERNV$F![#SVQY1P<SZ\M/!H>_KNY`T15D#0L;;O+5;U9OO
+M8W8]+R2_&EG*K9B'O:H9.XV:B]$??CZ,0!89*P^2[&LE7_?6GS&2Z-_CTPI'
+MA"AT71M;M#+M#DL;AXT94K'FZ..IMS?4VM*[>-&8[B#UHSF.2)!7WRJLA$AJ
+MR#L;>/NJS\*9\JXP4:2'U)]W2EC2#[BP9%1GY)R*=CJ]/^^G"CHO5AO,[W4Z
+M<?P+!<Y%J$#Y))M^'RV_9W]'L]33A29+HP=`.CVNO]>1*BZ?=]P.]V]/V3[.
+M[H>Q='K>Z?5N<R^'Q1_Z;\8SL7)943XJ>F;D>W\K)STYV/HOPQO<AM6*%'2N
+M#MW\@>ZDH@[MU<N1G;(E:G9U%G5B,+NC4YS&YFI7?D!=U)6&N,F>;7`DDVF=
+ML1+MBC0[>WK2J%+`!PK6QT>.I+5Z?'8Y5R\-6]78Y]K9`\U^8BL-RIT=/P)W
+M=MUW`<`+7@7.J_M%?&GL*GT`9Y9.R/#;/H5QUC\9P1?FE6]A+@3[IP,/12G_
+MAS*3.>)L-E>+_%NQ=[-L\U7NU2JXDIPXS#7AUR!)$HMA_R`%@"ZJP3S:J_C'
+MBIG^1,[>NAY373*#O)5?X]BC-4U!EX?OX&6/\^(:@[L,[%.%TZ_QP]`!V<@\
+M;EL@[&7&E<P]759>D&AW(BSGW*'RLG2C+__M/40`````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`#_V2\C^C%_:]3_Y____________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M______________________________________________Z`1_R+_^L?^G__
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________H$?\B__K'_I_____________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M_________Z!)#_4%IS_=3_\`````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M``````````````````$`````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````````````````````````!Q,(=41
+M#,T1`!85O9S\*.C/!I9I1:2;N[&-B[`5MIBT,?1836;F[OB11)I)5B)-+34%
+MIEX-^[V`4GT(E*.1T3,T512)P;F^.L,(DS43'5SOBOB7/\(/W/[]SD1P3SPF
+M!'I,@```````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````.7XW\>[_'Z.[^I\O\.YZ>>OI?P^;^'I__RVDL4?\2G5G_T:?&__K
+MIY7K#H7@A(IWJ%<*'!9%"OLP-!P7AD6BR0E+P\"H8V._E_*<QEP;WLUTJ$.I
+M$,X2N;N9_#QPZ2(L.]FDBD<4.YZ]&BVMCO2M^>C?IFE[04,GALITXYE9I+UT
+MMU/+-*9HF_1./4FOK-SR3*$Q\?,OFSQ7M\WQ\<HW@JB[:+J(T,A:,GFDD`YI
+MO>F5CX9ZMYX>?&%_>A&']?O</)-V73/N<.FT5M8V?WC>\$V'A#;8AY^:-F[!
+M<+R;L;2\W<U##D9THHEY^*V6HO:_*-7N!*'XKHD(F:;5+:R1PRC;,U7%)AMA
+MHV(/U3V,G9\]U$NB/1X+]-]21.97'M^'CX>&/WE[NW#\"VZ13S4Z)=:V3Q#T
+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
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````#_Y2\3^S%_:]3_Y________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M__________________________________________________________Z`
+M1_R+_^L?^G__________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M________________________________________H$?\B__K'_I_________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M_____________________Z!'_(O_ZQ_Z?___________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M__^@3`'1%0R-%\6=F]S/A7.S5W8"T;9`[O=G2*&IP\3W2`(833>H2:8/`,[&
+M-M/&Y!GWK4@<D`9+\//#CQL>,-D75WT2#SF<NKJ[NKJZ\=Y\2K^$7ZOU>#E*
+MZ5W?Y+GLL```````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M```````````````````````````````````````````'J[_3SO^?JY_0_X^G
+M^?0]2\[%_/G=#G^OW[GJ?'TY2['0XL!]#U(Z'1A";GY-BV,W6@9#W(9][P]/
+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
+M,G<;-1>B/OQ]&(`L,E8?)=C62K_OK3YC)=&_QZ84CPA0Z+HVMVAEVAR6-P\:
+M,J5CS=''4VYOJ;6E=O&C,=Q!ZT9S')$@K[Y560B0U9!V-O'W59^%,^5<8*-)
+M#ZD^[I2QI!]Q8,BHS\DY%.QU>G_?3A1T7JPWF=[J=./X%@N<BU"!\DDV_#Y;
+M?L[^CV>IIPI,ET8.@'1[77^O(E1=/N^X'>[>G[)]G=T/8NCUO=/JW.9?#XH_
+M]-^,9V+DLJ)\5/3-R/;^5DYZ<['T7X8WN0VK%"CI7!V[^0/=240=VZN7(SMD
+M2M3LZBSJQ&%W1J<YC<S4KOR`NZDK#7&3/-K@22;3.V(EVQ1H=O;UI5"E@`X5
+MK8Z/'4EJ]/CL<JY>&K>KL<^UL@>:_,16&Y4Z.GX$[NVZ[@.`%KP+G5?VBOC3
+MV%3Z`,\LG9'AMGT*XZQ^,X(OS2K>PEP)]TX&'HI3_PYE)G/$V&RO%_BW8N]F
+MV>:KW:I5<24X<9AKPZY`DB46P_Y`"P!=58)YM5?QCQ4S_(F=O70\IKIE!WDJ
+MO\>Q1FJ:@R\/W\#+'^?$-0=V&=BG"Z=?XX>@`[.0>-RV0=C+C2N8>KJLO2#0
+M[D19S[E#Y63I1E__VGJ(````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M``!_[$O(_HQ?VO4_^?__________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M_______________________________________________^@$?\B__K'_I_
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M_____________________________Z!'_(O_ZQ_Z?___________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M__________^@1_R+_^L?^G______________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________H$PAU1$,
+MS1$`%A6]G/PHZ,\&EFE%I)N[L8V+L!6VF+0Q]%A-9N;N^)%$FDE6(DTM-46F
+M7@W[O@!2?0B4HY'1,S15%(G!N;XZPPB3-1,=7.^*^)<_P@_<_OW.1'!//"8$
+M>DR`````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M``````````````````````````````````````````````!R_'_CW?X_1W?U
+M/E_AW/3SU]+^'S?P]/_^6TEBC_B4ZL_^C3XW_]=/*]8="\$)%.]0KA0X+(H5
+M]F!H."\,BT62$I>'@5#&QW\OY3F,N#>]FNE0AU(AG"5S=S/X>.'21%AWLTD4
+MCBAW/7HT6UL=Z5OST;],TO:"AD\-E.G',K-)>NENIY9I3-$WZ)QZDU]9N>29
+M0F/CYE\V>*]OF^/CE&\%47;1=1&AD+1D\TD@'--[TRL?#/5O/#SXPO[T(P_K
+M][AY)NRZ9]SATVBMK&S^\;W@FP\(;;$//S1LW8+A>3=C:7F[FH8<C.E%$O/Q
+M6RU%[7Y1J]P)0_%=$A$S3:I;62.&4;9FJXI,-L-&Q!^J>QD[/GNHET1Z/!?I
+MOJ2)S*X]OP\?#PQ^\O=VX?@6W2*>:G1+K6R>(>FIY<])L<NKP1N_DDS3.#)_
+MM&MI;(2;ID@Y.U[^BH',"%5;)/4EU5=RJKS^7*MW-6="=3D:`9IV._!YG%>9
+M=VJL1P%/>T<\W#?-)GHR<F#;0XLM[+NNPS;@%%:X;]X/<<8-^(ZDX'>3-5]`
+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
+MYFTQ!/OX4'O]SA6I$F:"1B$$U2@_1W"QN$['*?N_`&^2.#+J/L.G?]F?>CJI
+MNK$CI_5O9J.QOS:W,1N--&?B-]:,H?U'QXJ4>>I7N<W41MZ&"YS(Q'P23>I?
+M1R/\8OR>]^QCRK1LUPB45VXF)M"(-)BT0CA;F_GW?-=7*MFR5-5SM01[FSVO
+MWGMMD!--4&EKBGP1DJ88\Z<+Q0K^VX%`JM$UDW!)RG0!S>S\]?#>GORZJK@^
+MSA6L;S9O8I39_"'OH.#V]/BAG(V$O\7]<7*?]>3$)3NRO+/P31;-_)R6YHM+
+M0=07,?8;/HRQ,%%"/5&Q3C&DV-:7HCD*RBIP344+N7SCMU]1`IE!*18+-`IP
+M(57<KQ:7Q$"9[):(2VZ5Y-@5749-L<E4Y8O[9;NLNQR1%)FW>D$KG&-<(7DY
+MQ0\\AF,WYT?P5VI1P:@`L-U3U*G[SQGM1.<-NUYZ-KW-IL.)=/+&(N_,E[0F
+M3(33DOBB;SR1#I&-)K$VB]<9O.UU/VUV`EXY<ZY=FL8>YN&H&=2NDZ8(Z9O(
+MBZ,PWF5,.$)J9==N($)UFSVGE+LF]^,C,^3R8.?R5SRW@YK[_)6'J/1/K5N=
+MVU:==F-[GXYMU_&.K5;<Q+.NQ7L!^H#5,W5F@F?;N=;DH]9:>UCW(F0`EQ]+
+M0N_R4RA9\7XL;N@+'&K@RU%`R/DBIE-9)#F4\F%76COU^S6"\Q11HS\5#NMB
+MWFBG2F\R1E=M,0K5'KQ)QW<Q^Q%W3HB19J55[_GOA;_V_<D][XNW4]VD=M\S
+M=Z,"\=T>_DI,04KDYT:D./HU!O:U?RO83D,0BGM313Y@:P*+>I2SWB[-/H?C
+M[<I1,_"'%XXV9[%?H$/\O=[6YK^T6)9;VZ28=N<6?S9=8,1._-_4^A5>FJN]
+M(N]^.:AM66IM<[Y)96_C\U<#HQ9HBF+LSDCZ>`7TJ<]9W3BG;N?)\VQ/N4'`
+M`W__VG1P````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````/_E+Q/[,7]KU/_G_________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M_________________________________________________________H!'
+M_(O_ZQ_Z?___________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M______________________________________^@1_R+_^L?^G__________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________H$?\B__K'_I_____________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M_Z!,`=$5#(T7Q9V;W,^%<[-7=@+1MD#N]V=(H:G#Q/=(`AA--ZA)I@\`SL8V
+MT\;D&?>M2!R0!DOP\\./&QXPV1=7?1(/.9RZNKNZNKKQWGQ*OX1?J_5X.4KI
+M7=_DN>RP````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M``````````````````````]7?Z>=_S]7/Z'_'T_SZ'J7G8OY\[H<_U^_<]3X
+M^G*78Z'%@/H>I'0Z,(3<_)L6QFZT#(>Y#/O>'I]'H_<*=:?`W*=*-,E-&B1W
+M%@F0W/=*D#ITW8;Y_W5:/4@8RP_?AFD7WKCS/@7)H]+L1IJ[2+S*'#(,7W6U
+MN5F<73-";Q6MA'#.]Z>C;#!%T6]3<V_-L>K7X`N=_9U9--3^T'O#]'T[_//Y
+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
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`'_L2\C^C%_:]3_Y____________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M______________________________________________Z`1_R+_^L?^G__
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________H$?\B__K'_I_____________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M_________Z!'_(O_ZQ_Z?_______________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M____________________________________________________________
+M__________________________________________________^@2,_X7]KU
+M=IP=H```````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+>````````````````````````````.:3$/7L`0`<`
+`
+end
diff --git a/libarchive/test/test_read_format_rar_sfx.exe.uu b/libarchive/test/test_read_format_rar_sfx.exe.uu
new file mode 100644
index 000000000000..ea084ecacb76
--- /dev/null
+++ b/libarchive/test/test_read_format_rar_sfx.exe.uu
@@ -0,0 +1,2215 @@
+begin 644 -
+M35J0``,````$````__\``+@`````````0```````````````````````````
+M````````````````````Z`````X?N@X`M`G-(;@!3,TA5&AI<R!P<F]G<F%M
+M(&-A;FYO="!B92!R=6X@:6X@1$]3(&UO9&4N#0T*)`````````#3[14&EXQ[
+M59>,>U67C'M5GO3H58*,>U67C'I5.HQ[58G>[E62C'M5GO3X59Z,>U6>]/]5
+MNHQ[59[TZ566C'M5GO3O59:,>U6>].I5EHQ[55)I8VB7C'M5````````````
+M`````````%!%``!,`04`#1WA30``````````X``#`0L!"0``&@$``&(!````
+M``"`M````!`````P`0```$```!`````"```%``````````4``````````+`"
+M```$`````````@``A0``$```$``````0```0````````$````)!+`0`S````
+M.#P!`-P`````8`(`>$```````````````````````````````````,`R`0`<
+M```````````````````````````````````````````````````````````P
+M`0#``@``````````````````````````````````+G1E>'0```"8&0$``!``
+M```:`0``!```````````````````(```8"YR9&%T80``%1P````P`0``'@``
+M`!X!`````````````````$```$`N9&%T80```"S_````4`$```(````\`0``
+M``````````````!```#`+D-25``````0`````%`"```"````/@$`````````
+M````````0```0"YR<W)C````>$````!@`@``0@```$`!````````````````
+M`$```$``````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````````````````(#Y0',6@/D@<P8/
+MK=#3^L.+PL'Z'X#A']/XP\'Z'XO"P\S,S,S,S,S,S,S,S,S,S(M$)`B+3"00
+M"\B+3"0,=0F+1"0$]^'"$`!3]^&+V(M$)`CW9"04`]B+1"0(]^$#TUO"$`#,
+MS,S,S,S,S,S,S,Q75E,S_XM$)!0+P'T41XM4)!#WV/?:@]@`B40D%(E4)!"+
+M1"0<"\!]%$>+5"08]]CWVH/8`(E$)!R)5"08"\!U&(M,)!B+1"04,]+W\8O8
+MBT0D$/?QB]/K08O8BTPD&(M4)!2+1"00T>O1V='JT=@+VW7T]_&+\/=D)!R+
+MR(M$)!CWY@/1<@X[5"04=PAR!SM$)!!V`4XSTHO&3W4']]KWV(/:`%M>7\(0
+M`,S,S,S,S%=653/_,^V+1"04"\!]%4=%BU0D$/?8]]J#V`")1"04B50D$(M$
+M)!P+P'T41XM4)!CWV/?:@]@`B40D'(E4)!@+P'4HBTPD&(M$)!0STO?QB]B+
+M1"00]_&+\(O#]V0D&(O(B\;W9"08`]'K1XO8BTPD&(M4)!2+1"00T>O1V='J
+MT=@+VW7T]_&+\/=D)!R+R(M$)!CWY@/1<@X[5"04=PAR#SM$)!!V"4XK1"08
+M&U0D'#/;*T0D$!M4)!1->0?WVO?8@]H`B\J+TXO9B\B+QD]U!_?:]]B#V@!=
+M7E_"$`#,48U,)`0KR!O`]]`CR(O$)0#P__\[R'(*B\%9E(L`B00DPRT`$```
+MA0#KZ<.+5"0$,L"`.E)U*X!Z`6%U)8!Z`G)U'X!Z`R%U&8!Z!!IU$X!Z!0=U
+M#3A"!G4(B(&P<0``_L#"!`!J`/^QK'$``/^QJ'$``.AX2```PU97BWPD#(T$
+M/U"+\>@DF@``B0:%P'4.A?]T"KE\7D$`Z"@B``")?@2)?@A?B\9>P@0`5E>+
+M?"0,5XOQZ/69``")!H7`=0Z%_W0*N7Q>00#H^2$``(E^!(E^"%^+QE["!`#_
+M="0$@\$P4>C$G```]]@;P$#"!`"+1"0$5HOQ`48$BTX$BT8(.\AV+XO0P>H"
+M5XU\`B`[SW8"B_F-!#]0_S;HR)D``(D&A<!U"KE\7D$`Z)@A``")?@A?7L($
+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
+M"`/*P>$(`\B)BVA*``#IJP```(/X=`^%H@```+@``@``9H5&"`^$@P```(U-
+MK.BJ$```C86$[___4.C"C```BTWT#[<)C;XP!```.\%U+6C_`P``5XV%A.__
+M_U#H\L\``&C_`P``_W7X5^@7SP``_W7X_W7XZ/+'``#K(6@`!```0"O(5U&-
+MA`6$[___4(V%A.___U"-3:SH41```&:#/P!U%+C__0``9B%&".L),\!FB88P
+M!```B\OH./K__[@`!```9H5&"'01:@B-ACP,``!0C4W,Z-YU``"+1<C_,(V.
+M1`P``.ATS```,_^X`!```(F^:`P``(F^C`P``(F^L`P``&:%1@@/A-@```"-
+M1<10C4W,Z!MU``"-@Q17``")1;"-@SA7``")1;2-@UQ7``")1;B-@X!7``")
+M1;R)??#'1?0,````BT7PBWR%L`^W1<2*3?33Z(E%P*@(=':#??``=!F-1<A0
+MC4W,Z`-U``#_=<B+S^CDRP``BT7`BU7PBW25L&H)68U]A/.EJ`1T`_]%F(-E
+MG`!J`UXCQGXD*_#!Y@.+^(U%ZE"-3<SH870```^V1>J+SM/@@\8("46<3W7C
+MBT7PBWR%L&H)68UUA/.EBW7L_T7P@VWT!(-]]/P/CV+___^+AM@,```!@ZAQ
+M``"+AMP,``"-3<P1@ZQQ``"*1@C`Z`,D`8A%P/]UP.C==```]]!FB8/"<0``
+M9CD&#X3%````BT7L@W@$>G4<_W7XZ,N*```]^P,``',-:.0R00#_=?CHS8P`
+M`&H!N7Q>00#&@\!Q```!Z*L0``"`??\`=!5J`(U-S.B#=```]]!F.8.L2@``
+M=7+_=?CHF,<``%#H4L<``%!J:.CC?P``4(V#&`0``%#H/9L``(/$#.M*C;NX
+M2@``C;.L2@``I:6-@\1*``!0C4W,I>AV<P``C8/(2@``4(U-S.BF<P``N``"
+M``!FA8/`2@``=`^-@\Q*``!0C4W,Z"AS```S_U>-3<SH^W,``(!]_P"+B[!*
+M``#WT&:)@\)Q``")BZ1*```/A(\```"+5=`K5=R#P@@!DZAQ```1NZQQ``!F
+M.8.L2@``='&#^7MU3O:#P%<```1T15.-3:CH`Y```(O+Z``Q``!7:@=>*\8;
+MUU)0B\OH2C8``,9%_P&+R^C&.```A,!T!,9%_P!.=>Z-3:CH](\``(!]_P!U
+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
+M$_]U$/]U"/]U_.BA2@``A,!U(4.+C_1.``"-1?10C47\4.A;P```A,!UUC/`
+M7UY;R<(,`(MU#(7V=!/_=0C_=?SH6;X``/?8&L#^P(@&B\/KVU-55HOQ5XN^
+M]$X``#/M._UT#HO/Z,G^__]7Z,&&``!9B[[X3@``._UT#HO/Z+'^__]7Z*F&
+M``!9B[[\3@``._UT#HO/Z)G^__]7Z)&&``!9B[X$3P``._UT#HO/Z('^__]7
+MZ'F&``!9C;X`3P``BQ\[W70.B\OH9_[__U/H7X8``%F)+U^)K@1/``")KOQ.
+M``")KOA.``")KO1.``"-CE@M``!>75OI']```%:+\>A-____B\Y>Z91+``!6
+M5XOQZ#S___\SP+^H````5\:&PS8```!FB8;4.@``B(;T0@``9HF&]$8``(B&
+MP#8``(B&P38``.CUA0``687`=`F+R.B6OP``ZP(SP%>)AO1.``#HV84``%F%
+MP'0)B\CH>K\``.L",\!7B8;X3@``Z+V%``!9A<!T"8O(Z%Z_``#K`C/`5XF&
+M_$X``.BAA0``687`=`F+R.A"OP``ZP(SP%>)A@1/``#HA84``%F%P'0)B\CH
+M)K\``.L",\!?B88`3P``7L-6B_'HXDH``#/`B\Z)A@!/``")A@1/``")AOQ.
+M``")AOA.``")AO1.``#H"____XO&7L-5B^Q=Z?J;```SR6H(B\%:J`%T"='H
+M-2"#N.WK`M'H2G7NB02-P%%!`$&!^0`!``!\V<.#/<1100``=07HR/___XM,
+M)`B+1"0$5HMT)!!7A?9V&_;!!W06#[81#[;X,]?!Z`@S!)7`44$`3D'KX8/^
+M"')_B_[![P,S`8/!"`^VT,'H"#,$E<!100"#[@@/MM#!Z`@S!)7`44$`#[;0
+MP>@(,P25P%%!`(O0#[;"BP2%P%%!`#-!_,'J"#/"#[;0P>@(,P25P%%!``^V
+MT,'H"#,$E<!100`/MM#!Z`@S!)7`44$`#[;0P>@(,P25P%%!`$]UAC/2A?9V
+M&E,/MCP*#[;8,_O!Z`@S!+W`44$`0CO6<NA;7U["#`#_="0$_W0D#/]T)`SH
+M^GP``,((`%6+[('L\`$``%-6BW4(5S/;B_F)??AF.1X/A$("```X710/A3D"
+M``")7116C8/@54$`4.CU@0``A<!U/#E%#'4*.(/@5D$`="#K+8"[X%9!``!T
+M)&H(_W4,C8/A5D$`4.A#?@``A<!U#XI%&#B#Z59!``^$\`$``/]%%('#*@$`
+M`('[J`0``'*B:`````&-A1#^__]05NB+P0``5NC7@```B]@#VX-]#`!T%6H(
+M_W4,C80=$/[__U#HN7T``(/#"(V%=/___U#HYK<``(-E_`#_=1B-A1#^__]3
+M4(V%=/___U#H_+<``(M%_/]U&(O(B$44P?@0B$46:@.-1110C85T____P?D(
+M4(A-%>C3MP``BT7\)?\_`(!Y!T@-`,#__T!U0FH76?]U&(U%T%"-A1C___^-
+MM73___^-O1C___]0\Z7H0K@``(M%_(I-X)F!XO\_```#PHM5^,'X#HB,$"\"
+M``"+^O]%_(%]_```!``/C%O_____=1B-1>10C85T____4.@!N```C9\?`@``
+M,_:+^XM$M>2#910`BTT4@T44"(O0T^J(%T>#?10@?.Q&@_X$?-ZA:%I!`/]U
+M"&G`*@$```7@54$`4.C5?P``@WT,`*%H6D$`#Y7!:<`J`0``B(C@5D$`@/D!
+M=1%J"/]U#(V`X59!`%#H>WP``*%H6D$`BDT8:<`J`0``:A"(B.E600!3C8#`
+M54$`4.A8?```H6A:00"+??AIP"H!``!J$(''+P(``%<%T%5!`%#H-GP``*%H
+M6D$`0(/@`Z-H6D$`BTWX,\`X11!7#Y3`4U#H-WH``%]>6\G"%`"+=11I]BH!
+M``!J$(V&P%5!`%"-GQ\"``!3Z/![``!J$(V&T%5!`(''+P(``%!7Z-M[``#K
+ML0^V1"0,4/]T)`S_="0,_Q5P,D$`4/\5=#)!`,(,``^V1"0,]]@;P(/@"5#_
+M="0,_W0D#/\5<#)!`%#_%6PR00#"#`!5B^R#?0PP="2!?0P0`0``=2B*12`D
+M`0^VP%#_=1BYB%Y!`/]U".BU;P``ZPW_=0BYB%Y!`.A7;0``,L!=PAP`B\$S
+MR8A(!(E("(E(#(E($,-5B^R#[`Q35HMU##/2B]F*#D(SP%>+?12)7?B(30\Y
+M51`/AJT````[11@/@ZD```"#>P@`=0Z*##*(2P1"QT,("`````^V2P3!Z0:#
+MZ0`/A/H```!)#X3/````20^$J````$EU7@^V##)"A,EY?(H<,H/A?T)!08A=
+M_XE-](7)?C\[11AS.HM-"&8/O@P(9@^V??]F`\^__P```&8CSV8/MGT/NP`!
+M``!F#Z_[9@//BWT4_TWT9HD,1T"#??0`?\&+7?C`8P0"@T,(_CM5$`^"4___
+M_SM%&'($BT482#/)9HD,1U]>6\G"%`!!0>L6.T48<]"+70AF#[X<&&:)'$>+
+M7?A)0(7)?^;KN68/MDPR`;L``0``9@^ORV8/MAPR9@/+9HD,1T!"0NN69@^V
+M?0]F#[8,,KL``0``9@^O^V8#SXM]%&:)#$=`0NER____9@^V##)FB0Q'0$+I
+M9?___S/`B0&)003&00@!B$$)B$$*PS+`P@@`:FOH!W```%#H/88``%G#58OL
+MN``0``#H/-[___\5A#%!`(/X`W5Z5E>_``0``%>-A0#X__]0_W4,_W4(Z')'
+M``"-A0#X__]0Z(5\``"+\(V%`/C__U#HOT\``(3`=1Z-A0#P__]05_\56#%!
+M`(V%`/#__U#H67P``(UT!@&X!`$``%\[\%YV&5!HKP```.A[;P``4&@`,T$`
+MZ->*``"#Q`S)P@@`BU0D!(O"2'0*2'04+?T```!U!8,Y`'4"B1'_003"!`"+
+M`87`=`6#^`%U[\<!`@```.OG5HMT)`B!_O\```!U!H!Y"`!T&U:Y?%Y!`.BO
+M____Z-(E``#HTY```%;HTWT``%["!`"+P3/)B0B)2`3&0`@!B$@)B$@*PU:+
+M\>C:_O__:@B+SNBI____7L-5B^R![``(``"`/6Q:00``5HOQ=3!H``0``(V%
+M`/C__U#_=0S_=0CH5D8``(V%`/C__U!J=NBC;@``4&H`Z`**``"#Q`QJ`HO.
+MZ%G___]>R<((`%6+[+@`$@``Z,?<__^`>0D`=7135F@`!```C84`^/__4/]U
+M#/]U".@#1@``C84`^/__4&ITZ%!N``!0C84`[O__:``%``!0Z$!]``"#Q!#_
+M%80Q00!J-6I^B_#H*FX``%"-A0#N__]0_S7\P4$`_Q5H,D$`@_@$5@^4P_\5
+M@#%!`%Z*PUOK`C+`R<(,`%6+[('L``@``(`];%I!``!6B_%U,V@`!```C84`
+M^/__4/]U#/]U".AV10``C84`^/__4&@$`@``Z,!M``!0:@#H'XD``(/$#&H"
+MB\[H=O[__U[)P@@`58OLN``0``#HY-O__U:^``0``%:-A0#P__]0_W4,_W4(
+MZ"9%``!6C84`^/__4/]U%/]U$.@310``C84`^/__4&IMZ&!M``!0C84`\/__
+M4.BZB```@\0,7LG"$`!5B^RX`!```.B(V___5E>^``0``%:-A0#P__]0_W4,
+MB_G_=0CHQT0``%:-A0#X__]0_W44_W40Z+1$``"-A0#X__]0:F[H`6T``%"-
+MA0#P__]0Z%N(``"#Q`S_=12+S_]U$.CE_/__7U[)PA``58OLN``0``#H&]O_
+M_U:^``0``%:-A0#P__]0_W4,_W4(Z%U$``!6C84`^/__4/]U%/]U$.A*1```
+MC84`^/__4&IUZ)=L``!0C84`\/__4.CQAP``@\0,7LG"$`!5B^RX`!```.B_
+MVO__5KX`!```5HV%`/#__U#_=0S_=0CH`40``%:-A0#X__]0_W44_W40Z.Y#
+M``"-A0#X__]0:G3H.VP``%"-A0#P__]0Z)6'``"#Q`Q>R<(0`.GK_/__5O]T
+M)`R+\?]T)`QJ`&H`Z"____]J`HO.Z,[\__]>P@@`5O]T)!2+\?]T)!3_="04
+M_W0D%.AF____:@6+SNBI_/__7L(0`/]T)`C_="0(:@!J`.@C_O__P@@`_W0D
+M"/]T)`AJ`&H`Z&O^___""`!5B^R#[!13,]LX'6Y:00`/A90```"-1?Q0:B#&
+M!6Y:00`!_Q5X,4$`4/\5"#!!`(7`='96BS4$,$$`5XU%\%!H-#-!`%/'1>P!
+M````QT7X`@```/_6BSTD,$$`A<!T(E-34XU%[%!3_W7\_]>%P'01_Q6$,4$`
+MA<!U!\8%;5I!``&-1?!0:`PS00!3_]:%P'0-4U-3C47L4%/_=?S_U_]U_/\5
+M?#%!`%]>6\G#5HOQC8X4#```Z&"V``"-CC@,``#H5;8``(V.7`P``.A*M@``
+MB\9>PU6+[+CD0```Z!S9___HTSL``(7`#X3I`0``BT405C/V.\9T%&8Y,'0/
+M4(V%_.___U#HEW<``.L4:`````&-A?SO__]0_W4,Z-JW``!F.;7\[___="EF
+M.;7^[___=2!H7#-!`(V%_/?__U#H7G<``(V%_.___U"-A0#X___K#8V%_.__
+M_U"-A?SW__]0Z#QW``!35XV%_/?__U#H!'<``(VT1?SW__^+10B+N!1D``"+
+MF!!D``"-A?SW__]0T>_HX'8```/'/0($``!S%%=64^BMMP``,\!FB01^9H,^
+M.G01:@.Y?%Y!`.B*^O__Z0\!``"-1@)04.CD0P``C8T<O___Z-+^__^+=1"+
+M?0QJ`(V%'+___U!65^A@+```,]N(11.+A23+__]#A,-T"X/@_E!65^@C)```
+M:`````&-A;S3__]0C87\]___4.BEM@``C8W<X___Z$0:``!3C87\]___4(V%
+MO-/__U"-C=SC___H3AX``(3`=""+30B-A=SC__]0:@#H_>K__X3`=`N-C=SC
+M___H<1H``(V-O-?__^C[&0``@'T3`'0T4U-65XV-O-?__^CN&P``A,!T(8V%
+MK-/__U"-A:33__]0C86<T___4/^UP-?___\5=#%!`/^U),O__U97Z'`C``"-
+MC;S7___HCAL``(V-W./__^B#&P``7UM>R<(,`%6+[(/L#.C3.0``A<`/A)L`
+M``!35HMU"#/;4XU%]%"+SHE=](E=^(E=_.A0ZO__A,!T;.CM_/__:@=8.!UM
+M6D$`=`-J#UC_=?10.5T0=`O_=1#_%1PP00#K"?]U#/\5(#!!`#O#=3C_=0SH
+MT*\``%!HY`,``.A>:```4('&&`0``%;HN(,``+Y\7D$`@\0,B\[HM];__VH!
+MB\[HT/C__SE=]'0(_W7TZ#UQ``!>6\G"#`!5B^R+10B`N'0M````5HMU#'0A
+M:&@S00"-AA!8``!0Z/=S``"%P'4,_W44_W405N@:____:&0S00"-AA!8``!0
+MZ-9S``"%P'4,_W44_W405NCR_/__7EW"$`!65XOQZ"JS``"-?BB+S^A#7@``
+M@Z9,!0```#/`:/!B`0!FB89<$0``Z/EV``!9A<!T"E>+R.B6U@``ZP(SP&H`
+MB\B)AD@%``#HL=P``%^+QE[#4U:+\8M,)!!7Z`H?``"+?"00,]N!QQ@H``")
+MAO@$``")EOP$``")GE`%``")GE0%``!F.1]T$%>-AEP1``!0Z"1T``!F.1\/
+ME<"+SHB&7!(``(B>[@0``(B>71(``(B>7QX``,:&604```&(GEH%``"(GEL%
+M``#HW[,``%]>6\((`%:+\5>+OD@%``"%_W0.B\_HS-H``%?H*G8``%EH``$`
+M`&H`@<9<$0``5NA><```7U[#58OL@^P,5E=H```!`(U-].BFU?___W7XBWWT
+MBTT(5^A-70``B_"%]G1'4XM=#(/^_W0],\`[11!\"'\$._-R`HOSBTT(5E?H
+MAUX``(-]$`!\#'\$A=MR!BO>@UT0`/]U^(M-"%?H!UT``(OPA?9UOEN%_W0&
+M5^A<;P``7U[)P@P`58OLN%@R``#H@M3__X-]$`!3BUT(BH/#-@``5HMU#%>+
+M^8A%\'4X@+_N!`````^$=0X``/]U\(U'*&H`4%;HL^8``(3`=1%J`;E\7D$`
+MZ(GV___I40X``,:'7QX```"+AJ1*``")10B#^'0/A+$```"#^'9T!8/X>74'
+MQH=?'@```8/X>G5&:&PS00"-AA!8``!0Z*)Q``"%P'4'QH=?'@```8"_71(`
+M``!T:(V'7A8```^W"/?9&\DCR%&-AUX2``!05E/H5?W__XM%"(/X>W5"]H;`
+M5P```0^$R@T``/]U\(U'*&H`4%;H".8``(3`#X11____:@#&AU\>````_[:D
+M<0``B\[_MJ!Q``#H;1P``.L'B\[HV=/__[`!Z8D-``"`OU\>````QH==$@``
+M``^%<PT``(.[3"T```!U'HN#]$X``(N/5`4``#M(('(-@+]9!0````^%3`T`
+M`(V&`$L``%!0Z-RJ``"-A@!+``!0C85H^O__4.A+<```,\!FB85(YO__B$7O
+M:@6-1>]0C8;02@``4(O+Z&#L__^%P`^511.`?1,`=`V`?>\`=0?&AUD%````
+MN``"``!FA8;82@``=`WHH;,``,9%_P&$P'4$QD7_``^V1?_WV!O`C8]>%@``
+M(\&`??\`B47T=%*-A4CF__]0C88`3P``4.A$/@``:`````&-A4CB__]0C85(
+MYO__4.A!L0``A,!T(XV%2.+__U#H3$,``(3`=!.-A4CB__]0C85H^O__4.B(
+M;P``C85H^O__4%#H^3P``(O.Z!O<__^$P`^%O_[__[@`"```9H6&V$H``'1/
+MBX.D,@``@_@!=%R`?>\`=5:%P'4#B$43:@"-A4CF__]0C85H^O__4.@@1```
+MBXND,@``23O(=2MJ`8V%2.;__U"-A6CZ__]0Z`!$``#K&(O.Z)W;__^$P'4-
+M@[ND,@```78$QD43`(O.Z+#;__^*AMA*``#0Z"0!B(?N!```QH?O!````(N&
+MJ'$``"N&J%<``(N.K'$``!N.K%<``&H`45"+SNAM&@``@'T3`,9%#P#&10L`
+MQD7K`'41BH:Q<0``B$7KA,`/A$H+``"`??!)_W7K#Y3`#[;`4`^V@^(M``!0
+MC85(YO__4(V%:/K__U#H97D``(3`#X1#"P``]H;82@``!'1;C8=<$0``9H,X
+M`'5/:(````!0C85(YO__4(V%:/K__U!J`>C0[/__A,!U,&H`Z.!X``!9C85H
+M^O__4.C^J0``4&ISZ(]B``!0Z,5X``!96<:'7AX```'IWPH``(V#$`0``(V/
+M7A(``%!1B4WXZ.AM``"#NT@M```$=3*`??!8=2QJ.NC)-P``A,!T(8M%^,9%
+M"P'&``"`??!%=!>#NT@M```!=`Z-A6CZ___K$L9%"P#KXXV%:/K__U#H:CH`
+M`%#_=?CHM6X``(M%^`^V`%#H7Z@``(!]"P"(1>IT1X"_7Q(``%]U(P^^AV`2
+M``!0Z$8W``"$P'02BD7J+$$\&7<)QH=?$@``.NL;BT7X@#A?=1.`OU\2``!?
+M=0K&`%S&AU\2``!<@'W_``^$GP```(V#$`@``&:#.`!T#U"-AUX6``!0Z'YN
+M``#K&&@````!C8=>%@``4(V#$`0``%#HO:X``(!]"P!T"3/`9HF'7A8``(!]
+M\$5T$8.[2"T```%T"(V%2.;__^L,C85(YO__4.CM.0``4(V'7A8``%#HDFX`
+M`(!]"P!T,&:#OV`6``!?=28/MX=B%@``4.A\-@``A,!T%6HZ6&:)AV`6``#K
+M"3/`9HF'7A8``(!]ZP!U#?:&V$H```'&10L!=`3&10L`@+M$+0```'4)@+M%
+M+0```'1K@'WP170&@'WP6'5?C8VHS?__Z+KU__]J`(V%J,W__U#_=?3_=?CH
+M2B,``(3`="^-AA17``!0C8V\V?__Z$ZM``"$P'0F@+VXV?__`'095XV-O-G_
+M_^C5K```A,#K!X"[1"T```!T!,9%"P#VAMA*```$=!IF@[]<$0```'40:@&Y
+M?%Y!`.CE\/__QD4+`(J&\$H``#PD=$$\'70]@+[Q2@``,'0TC85H^O__4.B.
+MIP``4&ILZ!]@``!0C888!```4.AY>P``@\0,:@&Y?%Y!`,9%"P#HEO#__XV-
+M2.[__^BS$```_[;T2@``Z#(:``"$P`^%,0,``(O.Z/+7__^$P`^$U`$``(!]
+M"P`/A+H!``"`??!0#X2P`0``@'WP10^$I@$``(.[2"T```$/A)D!``"`?>L`
+M#X6/`0``_X=,!0``@+OB+0````^%?`$``("[ART```#_MO1*```/E,`/ML!0
+M_W7T_W7XZ%P:``"%P`^$I0```/]U]/]U^.@Q&0``B$4+A,!T0_]U]/]U^.B4
+M&0``4.AQ&0``A,!U+O^V[$H``(U%"_^VM%<``/^VL%<``%#_LR0M``#_=?3_
+M=?AJ`%/H;@T``,9%"P!J`?]U]/]U^.B[&P``@+N'+0```/^V]$H```^4P`^V
+MP%#_=?3_=?CHTQD``(7`=""`?0L`=".`NX<M````=1'_MO1*``#_=?3_=?CH
+M.1D``,:'71(```'K1O]U^.@4I@``4&IOZ*5>``!0C888!```4.C_>0``@\0,
+M_W7TN7Q>00#_=?CHAN[__[E\7D$`Z/#,__]J";E\7D$`Z`;O__^`OUT2````
+M=$2+@[0R``#WV!O`C8Y<5P``(\%0BX.P,@``]]@;P(V..%<``"/!4(N#K#(`
+M`('&%%<``/?8&\`CQE#_=?3_=?CH%!L``+,!C8U([O__Z+D0``"*P^ET!@``
+MC8U([O__Z*<0``#IU/C__XJ#XBT``(3`=`J`?0L`=`3&10\!@'WP170*@'WP
+M6`^%*@$``(!]"P`/A"8!``"$P`^%&`$``/^V[$H``(U%__^VM%<``/^VL%<`
+M`%#_LR0M``"-A4CN____=?3_=?A04^CU"P``A,`/A>$```"(10LX1?\/A=L`
+M``"-EUX6``!2_W7XC888!```C4X74%&Y?%Y!`.@;\/__:@FY?%Y!`.CQ[?__
+M_W7XZ((\``"$P`^%H````&A6!```Z$!=``!0C888!```4.B:>```65EH``0`
+M`/]U^(V%2.+__U#HW*,``&H!_W7XZ*P\``!J`6H`_W7XZ,$9``#_MNQ*``"-
+M1?__MK17``#_MK!7``!0_[,D+0``C85([O__:@#_=?A04^@U"P``A,!T!L9%
+M"P'K:(V'7A8``%#_=?B-AA@$``!0C4874+E\7D$`Z&7O__^`?0L`=4.`OK%Q
+M````=#!J`6H`:@"-A4CF__]0C85H^O__4,9%ZP'&10\!QD4+`>CZ<@``A,!U
+M>C+;Z5'^__^`?0L`#X2*!```@'WK`'5C@'T/`'57@'WP4'11C8U([O__Z,L.
+M``"$P'1"_W7XZ*6C``!0:`8$``#H,UP``%"-AA@$``!0Z(UW``"#Q`R-AUX6
+M``!0_W7XC888!```4(U&%U"Y?%Y!`.@$\/___X=,!0``_X=0!0``,\")AQ`%
+M``")AQ0%``")AQ@%``")AQP%```XAK!Q```/E<"#CS@%``#_2(F'-`4``("^
+MY$H```!U/&B`````C85H____4(V'7!$``%#_%60R00!H@````(V%:/[__U"-
+MA6C___]0Z-2H```SP&:)A6;____K$XV'7!$``%"-A6C^__]0Z%UH```/MX;8
+M2@``J`1T#`^VCO!*``")3?3K!(-E]`"`OO!*```DC4\H&M(E``0``/["#[?`
+M#[;24O?8&\!J`(V6#%<``"/"4(V%:/[__U#_=?3H+%$``(N&J%<``(E'2(N&
+MK%<``(E'3(V%2.[__U!6C4\HZ.I0``"*10^*3>N(1U&(3U*$P'5Q.(;`<0``
+M=6F+AJA7``"+CJQ7``"+EK17```/I,$+P>`+.\I\3'\(.X:P5P``=D*%TGPG
+M?PR!OK!7````X?4%<AF+SNA`$@``.Y:L5P``?"%_"#N&J%<``'87_[:T5P``
+MC8U([O___[:P5P``Z.D1``"`NX`M````#Y3`@+OB+0```(B%6^[__W4*@'WK
+M`,9%]`%T!,9%]`#_=?2-AS0%``!0_W7XC4<H5E#H2Z<``(3`=`N*1?2(AUT2
+M``#K</:&V$H```%U9X"^\4H``#!U%_^VM%<``(U'*/^VL%<``%#H/_/__^M'
+MBX=(!0``BXZP5P``B8A`S```BXZT5P``B8A$S```QH!8S````(J&V$H``(N/
+M2`4``,#H!"0!#[;`4`^VAO!*``!0Z#[:``"+SNADR/__BH:P<0``A,!T$HN/
+M-`4``#N.Z$H``'04A,!U%(N&Z$H``/?0.8<T!0``=02P`>L",L#VAMA*```0
+M=0G&AUL%````ZRB`OO%*```P=!^#OK17````?!9_"8.^L%<```!V"X3`=`?&
+MAUL%```!@'WK`,9%_P!U7X3`=5OVAMA*```$=!DXAUL%``!U$8V%:/K__U#H
+MA:```%!J<.L/C85H^O__4.ATH```4&IQZ`59``!0C888!```4.A?=```@\0,
+M:@.Y?%Y!`,9%_P'H?.G__^A5Q___@'T/``^%^0```(!]\%AT"H!]\$4/A>D`
+M``#_MO1*``#H!!,``(3`#X76````.(-`+0``=`>#IO1*``#?@'W_`'08@+N`
+M+0````^$M````(V-2.[__^CT"@``BY.T,@``]]H;THV&7%<``"/0BX.P,@``
+M]]@;P%*-ECA7```CPE"+@ZPR``#WV(V.%%<``!O`(\%0C8U([O__Z%0.``"-
+MC4CN___H80D``(N+M#(``/?9&\F-AEQ7```CR%&+BZPR``#WV1O)C8845P``
+M(\A1C8U([O__Z(0*``"`NX<M````=1G_MO1*``"-A6#R__]0C85?[O__4.A?
+M$@``QH==$@```8V-2.[__^AV"@``@'T3`'0&_X=4!0``@+_O!````'4A@'T+
+M``^%B?+__X"^L7$````/A'7R__^`?>L`#X5R\O__,L!?7EO)PA``58OLN(">
+M``#HT,7__U97_W4(B_&-C8!A___H<<S__XV&7`D``%"-OEP%``!7C8V`8?__
+MZ$T+``"$P'41:@:Y?%Y!`.CBY___Z2\!``!J`8V-@&'__^BYQO__A,!U%VAP
+M,T$`5^B!,@``A,`/A`L!``!J`>O)4S/;,_\XG3+3__\/A*````"-A9=A__]0
+MC84`_/__4.A]8@``C8689?__4(V%`/3__U#HU6,``/:%0*S__Q!T#8"],-/_
+M_P!U!#+`ZP,SP$!0:``$``"-A0#T__]0C84`_/__4.C',P``C8U@W___Z*/K
+M__]J`(V%8-___U"-A0#T__]0C84`_/__4.@K&0``A,!T$HN%8.O__P/XBX5D
+MZ___$]CKD8V&*`4```$X$5@$BWT(C86`8?__4%>+SNCA[O__BH?#-@``6SQ4
+M=`0\274'QH?B+0```8V-@&'__^BOQ/__C8V`8?__Z%?/__^-30M14(V%@&'_
+M_U!7B\[HUN___X3`==V-C8!A___H>,S__U\SP%[)P@0`58OLN*05``#H0<3_
+M_U.+70A6B_'&AEX>````BH/#-@``5XV-7.K__XB&[`0``.C*ZO__OP`$``"-
+MAEP)``!7C8Y<!0``4(E%"%'K/FH`C85<ZO__4/]U"(V&7`4``%#H/1@``(3`
+M=!>+C5SV__^-AB@%```!"(N-8/;__Q%(!%?_=0B-AEP%``!0B\OHHMS__X3`
+M=;>+BP!/``#H(IT``.MJC8,8*```4(V%_/[__U#H/6(``%.+SNBT_?__B47\
+MC87\_O__4(V#&"@``%#H'V(``(-]_`%TR6H`C85<ZO__4/]U"(V&7`4``%#H
+ML!<``(3`=!>+C5SV__^-AB`%```!"(N-8/;__Q%(!%?_=0B-AEP%``!0B\OH
+M%=S__X3`=8"#ODP%````=3*`N\,V``!)="DXAEX>``!U%6A#`P``Z+Y4``!0
+M_W4(Z!QP``!966H*N7Q>00#H/N7__U]>6\G"!`!5B^R![``,``!35E>+?0B[
+M]@,``(7_=`Y7Z!)?```[PP^''P$``(MU#(7V=`Y6Z#%A```[PP^'"@$``(-E
+M"`"%_W0=@#\`=!A7Z'$O``")10B%P'4+5^C57@```\>)10B#90P`A?9T'V:#
+M/@!T&5;H9R\``(E%#(7`=0Q6Z.-@``"-!$:)10PSP#/;QH4`_/__`&:)A0#T
+M__]#A?]T)(`_`'0?_W4(BT4(4U<KQU"-A0#\__]HC#-!`%#HO&(``(/$&(7V
+M="QF@SX`=";_=0R+10Q3*\96T?A0:'0S00"-A0#T__]H``0``%#HLV(``(/$
+M'(V%`/3__U"-A0#\__]0Z'0-``"$P'0+@?M`0@\`?31#ZX:%_W02@#\`=`V-
+MA0#\__]05^CY7@``A?9T$V:#/@!T#8V%`/3__U!6Z$U@``"P`>L",L!?7EO)
+MP@@`58OLN,`P``#HC\'__U-65XV-0,___^@PZ/__,_]7C85`S___4/]U"%?H
+MP14``(3`#X1O`0``9CF]P-O__P^$8@$``(V%P-O__U"-A4#3__]0Z*4K``!0
+MZ!ZB``"%P`^$00$``(V%P-O__U#_=0CHB"L``%#H`:(``(7`#X4D`0``9HF%
+M`/C__S/;O@`$``!F.;T`^/__=5Y6_W4(C84`^/__4.B1F0``4VB8,T$`5HV%
+M`/C__U#H0"L``%#HDV$``(/$$(V%`/C__U!7Z%H,``"$P'0),\!FB84`^/__
+M@\-[@?L0)P``?*9F.;T`^/__#X2O````5O]U"(V%`/#__U#H,YD``(V%0-/_
+M_U#HZ2H``%"-A0#P__]0Z-PJ``!0Z!M?``"+-7`Q00"-A0#X__]0C84`\/__
+M4/_6A<!T9HV-X./__^C'`@``_W4(,MM7Z-8+``"$P'43:@'_=0B-C>#C__]7
+MZ`H&``"*V(V%`/#__U"-A0#X__]0_]:$VW06C8W@X___Z/$"``"-C>#C___H
+M:P,``(V-X./__^A5!```L`'K`C+`7UY;R<($`%6+[(M%'('L!`P``(7`=`/&
+M``!35HMU%%>+?1!65\9%_P#H5@L``#/;0^F[`0``@'W_`'5E:``$``"-A?SS
+M__]05E>(7?_H_B@``(V%_//__U#H^_W__X3`=#^%_W07@#\`=!)H`````5>-
+MA?SS__]0Z$.>``"%]@^$90$``&:#/@`/A%L!``"-A?SS__]05NC]70``Z4D!
+M``"+11C&1?\`@_@"#X1?`0``@_@#=1A65^A._/__A,`/A24!``"#91@`Z1P!
+M``"+30B`N6@M````#X4;`0``.\,/A!,!``"%P'0)@_@$#X7W````,\!FB87\
+M\___5XV%_/O__U#H)5P``%;H=)8``%"-A?SS__]0Z'U=```SP#E%#`^4P%#_
+M=2B-A?SS____=23_=2!0C87\^___4.@7=@``#[[`4/\U`%!!`.@46P``B\LK
+M#0!000`#P3O##X27````:@)9.\$/A*,```"#^`,/A*<```"#^`0/A*D```"#
+M^`5U4HV%_/O__U#H;2@``(V-_/O__SO!B\%05W4&Z%HH``!0Z(5;``"%]G0]
+MC87\\___4.B;*```C8W\\___.\&+P5!6#X7,_O__Z(0H``!0Z<'^__^#^`9U
+M#VC_````N7Q>00#HF^/__U97Z),)``"$P`^%/?[__XM-#(7)=#Q35E?HQ0,`
+M`(3`=#"*P^M3BT4<A<!T`H@8,L#K1HM%"(F8)"T``.O1BT4<A<!T`H@8BT4(
+MB8@D+0``Z]U65^B=#0``4U97Z!H,``"+30R%R70*4U97Z',#``#K!U97Z`<*
+M``!?7EO)PB0`B\&#2`3_,\DSTL<`L#-!`(A(%V:)D!@$``"(2!*(2`B)2`R(
+M2!"(2!&)B!@,``"(2!;&0!,!B8@<#```QD`4`8A(%<.#?"0$_W0=,\"#/(5P
+M6D$``'0*0#T``0``<N[K!XD,A7!:00#"!`!35HOQ@WX,`+,!=`:#9@P`ZVB+
+M1@2#^/]T8(!^$`!U.%#_%7PQ00"+V$OWVQK;_L-U"8,]<%Y!``!U'3/`.32%
+M<%I!`'0*0#T``0``<N_K"(,DA7!:00``@TX$_X3;=1HX7A1T%8V&&`0``%"-
+M1A=0N7Q>00#H?]____^&'`P``%Z*PUO#5HOQ@WX,`'0$,L!>PX-^!/]T!>AC
+M____@'X3`'3KC888!```4(/&%U;HX@@``%[#58OL45-6B_&#RO\SVSE6!'4:
+M.%X4=&V-AA@$``!0C4874+E\7D$`Z/C?__]7:@&-1?Q04_]V!(E=_/\5;#%!
+M`(OX@___=23_%80Q00"%P'0:.%X4=#*-AA@$``!0@\875KE\7D$`Z+G?__^+
+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
+M!(7`=!&`.`!T#/]T)`Q0Z'+^___K`C+`P@P`58OL@>P@"```Z`84``"%P`^$
+M(0$``(M%$%,SVSO#=`C&1?X!.1AU`XA=_HM%%#O#=`C&1?T!.1AU`XA=_8M%
+M&#O#=`C&1?\!.1AU`XA=_U>+?0Q7_W4(Z`#]__^)1?B#^/\/A-,```"H`0^$
+MRP```%-7_W4(QD4/`>@+_?__5F@`!```C87@]___4%?_=0CH'QH``%-H````
+M`FH#4VH#:````$"-A>#W__]0_Q5<,4$`B_"#_O]T?#A=_G0,BTT0C47@4.A:
+MC```.%W]=`R+312-1>A0Z$F,```X7?]T#(M-&(U%\%#H.(P```^V1?[WV!O`
+MC4W@(\%0#[9%__?8&\"-3?`CP5`/MD7]]]@;P(U-Z"/!4%;_%70Q00!6_Q5\
+M,4$`.%T/=`S_=?A7_W4(Z%7\__]>7UO)PA0`B%T/Z3O___]J`/]T)`S_="0,
+MZ#?\___""`"+P8.(!`P``/\SR<8``&:)B``$``#&@``,```!PXN!!`P``(/X
+M_W0'4/\5?#!!`,-65XM\)`R+\87_="57C88`!```4.A>3@``@#X`=0QH````
+M`597Z'2.``#&A@`,```!7U["!`!5C6PDF('L4`H``%-65^A&$@``OP````&%
+MP`^$D`$``(M%>(7`=!5F@S@`=`]0C848]O__4.@'3@``ZQ!7C848]O__4/]U
+M=.A.C@``BW5\@\O_C848_O__4#E=<'4[C848]O__4/\5C#!!`(E%<#O#=5+_
+M%80Q00"#^`)T#X/X`W0*@_@2=`4SP$#K`C/`B(:<%```Z:L"``#_=7#_%8@P
+M00"%P'45B5UP_Q6$,4$`@_@2#Y7`B(:<%```.5UP#X2``@``C848]O__4(V>
+M``0``%/H:DT``(V%1/[__U!3Z!@9``!0Z%=-``!75E/H=HT``&H!:@!J`/^U
+M-/[__^C*K/__BXTX_O__,_\#P8F&``P``(N%&/[__XF&"`P``(U%3%"-AH`,
+M```3UU")E@0,``#H"DT``(N%'/[__XF&@!0``(N%(/[__XF&A!0``(N%)/[_
+M_XF&B!0``(N%*/[__XF&C!0``(N%+/[__XF&D!0``(N%,/[__XF&E!0``(V%
+M+/[__XV^%`P``%"+S^@MBP``C84<_O__4(V..`P``.@;BP``C84D_O__Z7L!
+M``"+172%P'04@#@`=`]0C848^O__4.@-2P``ZQ!7C848^O__4/]U>.B-C```
+MBW5\@\O_C84H____4#E=<'4KC848^O__4/\5A#!!`(E%<#O#=4+_%80Q00"#
+M^`(/A'S^__^#^`/I;?[___]U</\5@#!!`(7`=16)77#_%80Q00"#^!(/E<"(
+MAIP4```Y77`/A`$!``"-A1CZ__]05NB&2@``C854____4%;H2!<``%#H<TH`
+M`%>-A@`$``!05N@IC```:@%J`&H`_[5$____Z$NK__^+C4C___\SVP/!B88`
+M#```BX4H____B88(#```5XV&@`P``%"-15@3TU")E@0,``#HXXL``(N%+/__
+M_XF&@!0``(N%,/___XF&A!0``(N%-/___XF&B!0``(N%./___XF&C!0``(N%
+M//___XF&D!0``(N%0/___XF&E!0``(V%//___XV^%`P``%"+S^BMB0``C84L
+M____4(V..`P``.B;B0``C84T____4(V.7`P``.B)B0``B\_HVH@``(F&#`P`
+M`(.FF!0```"+17!?7EN#Q6C)PA``4U565XM\)!2+\3/;ZW-7C88`!```4%8X
+MG@`,``!T#VK_Z(+\__^)A@0,``#K"_^V!`P``.AO_/__@_C_=$W_MP@,``")
+MGY@4``#HW??__XB'$`P``%>(G@`,``#H[!4``(OH:+@S00!5Z())``"%P'0/
+M:+0S00!5Z'-)``"%P'4.B)^<%```.!YU@S+`ZP*P`5]>75O""`!5B^Q6_W4,
+MBW40_W4(QH:<%````.AO$@``A,!T!#+`ZS16_W4,_W4(:O_HX?O__X/X_W3I
+M4/\5?#!!`/^V"`P``(.FF!0```#H1_?__XB&$`P``+`!7EW"$`!65[\"@```
+M5XOQZ%1,``!95VH`4(E&".B"1@``7XO&7L/_<0CH+4P``%G#B]&+0@B+"@/(
+M#[8!5@^V<0$/MDD"P>`("\;!X`@+P6H(62M*!%[3Z"7__P``PXM!!`-$)`2+
+MT,'J`P$1@^`'B4$$P@0`Z;;___]6B_&+1AC'!F`T00#'1@0D-$$`QT8(Z#-!
+M`,=&#,PS00"%P'0*BPA0_U$(@V88`%[#BT0D!/]`$(M`$,($`+@"0`"`P@@`
+M,\#""`!6BW0D"/]V$/\58#)!`(7`=0-`ZPN+1A"+3"0,B0$SP%[""`!J$/]T
+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
+M1X3`#X3%````/"IT*CP_=!PZPW0</"YU#83;=,:`^UQTP3K8=+TRP.FH````
+MA-MT]4:)=0SKK(H'A,!U![`!Z9$````\+G5\C5\!@#LJ=0:`?P(`=.=J+E;H
+M;#@``(`[`(OP=1.%]G0*@'X!`'0$,\#K8C/`0.M=A?9T,&AT-D$`5XEU#.BI
+M.```A<!U'FHN1E;H,S@``(7`=1'_=1!64^CT_O__]]@;P$#K*8MU#.L3_W40
+M5E?H'____T:$P`^%>?___X`^`'7HZ5C___\SP(3;#Y3`7UY;7<(,`%6+[('L
+M``@``%.+70A65XM]$(O'P>@?)`&!Y___``"(11`/A!D!``!3Z)<W``"+\(/_
+M`G0L@_\#="?_=1!6_W4,4^B5_O__A<!U%HM%#(H$!CQ<=`@\+W0$A,!U!+`!
+MZWR#_P%U!#+`ZW.^``0``%:-A0#\__]04^@S"```5HV%`/C__U#_=0SH(P@`
+M`(/_`G0%@_\#=1K_=1"-A0#X__]0C84`_/__4.@0_O__A<!UM8/_!'0)@_\%
+M#X6"````:@"-A0#\__]0Z(T!``"$P'03_W40_W4,4^@A_O__7UY;R<(,`(/_
+M!'0D:@!3Z&D!``"$P'48_W40C84`^/__4(V%`/S__U#HLOW__^LL@+T`_/__
+M`'0K_W40C84`_/__4.B@-@``4(V%`/C__U"-A0#\__]0Z*/]__^%P`^%)?__
+M_U/H0`0``/]U#(O8Z#8$``!J!HOP5FAX-D$`Z/UQ``"%P`^$_O[___]U$%:#
+M_P(/A6+___]3Z$+]___WV!O`0.E8____5E=HP#8``#/_B_%75N@S-0``N/__
+M_W^)OB0M``")OAPM``")OG`M``")OF0M``!?QT8,``!``,>&*"T```,```#&
+MAH0M```!QX:L,@``!````(F&T"T``(F&U"T``(F&V"T``(F&W"T``%[#5FC`
+M-@``B_%J`%;HR30``(V.6"T``%[I-(0``%:+\3/)C898+0``B0B)2`2)2`B-
+MCH@M``#H<78``(V.K"T``.AF=@``B\[H2/___XO&7L-6BW0D"%;HK3<``(7`
+MC41&_G<"B\9>P@0`BT0D"(7`=!-F@S@`=`UH@#9!`%#H6#D``.L9@WPD!`!U
+M!#/`ZQ1H=#9!`/]T)`CHR34``/?8&\#WV,((`(-\)`1<=`N#?"0$+W0$,\#K
+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
+M=00STNL#,])"A<EU!6H"6.L'B\$E````@`O"B4<PZ;S[__^+3?B*602$VW0%
+M#[8.ZP*+#HM7,(/B`8E-](3;=`4/M@#K`HL`BTWT*\HKR(3;=`:!X?\````[
+M3?1WJ.N<BT\L@?D```0`<T:+5PR+P27__P,`BP00.T4,<S3_3?R#??P`?B]K
+MP"@#10B#P02+V(E/+.EN^O___W,,B\_H6?7__XM=^(/#*/]-_.E6^O__L`'K
+M`C+`7UY;R<((`/F,0``2C4``3(U``+N-0`#XC4``)XY``#".0`!4CD```HY`
+M`':.0`"?CD``PXY``.".0```CT``#(]``!6/0``>CT``)X]``"V/0``\CT``
+M58]``&Z/0``EDD``DH]``*N/0`#VCT``+)!``$N00`!OD$``HY!``,F00`#5
+MD$``])!``/R00``'D4``.)%``%N10`"*D4``Z)%``&B20`!>DD``58OL4U:+
+M=0R+V8-C!`"#(P"X`(```%<[\',"B\:+?0A05_]S".@G&@``,\DRP$&(10L[
+M\78+,@0Y03O.<OB(10MJ"(O+Z)73__^+=1"*10N#9A``.@</A<T!``#_=0R+
+MRU?H,O+__XOXA?]T.&H!B\[H#?/__XM&$(U(`6O`*`,&@V4,`(E.$(U(#(DY
+MB4@4C4@<:@.)2"19QP`H````B4@8B4@(B\OH2M/__VH!B\N+^.@HT___]\<`
+M@```#X1;`0``4^@!\?__BPN#90@`0(E%$#M-#`^#30$``.L#BT40.44(#X,T
+M`0``C7X@:@&+S^A@5P``BS\#?0B+R^CTTO__P>@(:@B+RX@'Z,_2__^+10S_
+M10@Y`W+$Z?\```!J`8O.Z%OR__^+?A!K_R@#/HO+Z+_2__^+RZD`@```=0?!
+MZ`QJ!.L(P>@*@^@8:@:)!^B)TO__BP?V@!!000`$=!V+R^B.TO__J0"`__\/
+ME<!J`8O+B$<$Z&/2___K!,9'!`"-1QAJ`UF)11")"(L'C5<(B0H/MH`04$$`
+M(\&)10C'1R0`````QT<4`````'YK#[9'!%!2B\OH#_+__X-]"`)U$0^V1P10
+M_W40B\OH^O'__^M'@W\(`75!BP?V@!!000`8=#:+1PRY``$``#O!?`0KP>LC
+M/8@```!\!RT(`0``ZQ*#^!!\!8/H".L(@_@(?`.#Z!`#1A")1PS_1A"+10PY
+M`P^"]O[__VH!B\[H4?'__XM&$(U(`6O`*`,&B4X0C4@,B4@4C4@<B4@D:@-9
+MB4@8B4@(,]+'`!8````SR3E6$'XE,_^+!@/'.5`4=0:-6`R)6!0Y4"1U!HU8
+M'(E8)$&#QR@[3A!\W5]>6UW"#`!5B^Q35HMU"%=J'(U&+(OY4(U'$%#HIQ<`
+M`(M&&+L`(```B44(.\-R`XE="(-]"`!T%/]U"(M'#/]V%`4`P`,`4.A[%P``
+MBTT(BT8D*]D[PW("B\.%P'044(M'#/]V((V$"`#``P!0Z%47``"#9S``QT<L
+M```$`(M&#(O8A<!U`HL>BT80A<!^$U!3B\_H;O;__X3`=0;'`Q8```"+5PR+
+MBB#``P"+@AS``P"[__\#`"/+(\.-'`B!^P``!`!R!#/`,\D#T8E62(E&3(/&
+M%(O.Z&%F``"+1PR+B##``P"XP!\``#O(<P*+P87`=!R-6$!3B\[HSE0``(M'
+M#%,%`,`#`%#_-NBX%@``7UY;7<($`%6+[%%6B_&#?A@`5W1:BTX0BWX$BU4(
+MB\$KQP/"B7W\=#]3B]CWTT.#XP\#V%.+SNB!5```BP:+3@P#QU-0Z)K%__^+
+M3AB+^(L&`T7\4U#HTY?___??&_\C?0A;`7X0ZRD#RHE.$.LB@WT(`'0<_W4(
+MZ$!4``"+1A`#!O]U"(M.#%#H5L7__P%&$%]>R<($`(M!%#M!$',0BQ&*!!"+
+M5"0$B`+_013K!XM$)`3&``#"!`"+012-4`$[41!S*(L1`\)F#[90`68/M@!6
+MO@`!``!F#Z_69@/0BT0D"&:)$(-!%`)>ZPF+3"0$,\!FB0'"!`"+012-4`,[
+M41!S,(L1`\(/ME`#5@^V<`+!X@@#U@^V<`$/M@#!X@@#UL'B"`/0BT0D"(D0
+M@T$4!%[K!XM$)`2#(`#"!`!6B_&+1A17BWPD$(U,./]7.TX0<Q.+#@/(4?]T
+M)!3H6!4```%^%.L+:@#_="04Z!L5``!?7L((`(M1$(/Z`G8<@'PD!`!T`XM1
+M%(L!0(/"_E)`4&K_Z+.5___K`X/(_\($`(M4)`2+P3/)B0B)2`2)2`B)4`R)
+M2!2)2!")2!C"!``SP(/*_X@!B$$,B4$@B4$DQD$H`8A!*8A!*HB!Q00``(B!
+MQ@0``(B!QP0``(E!+(E!,(E!&(E!-(F!%`4``(F!&`4``(F!R`0``(F!S`0`
+M`(F!\`0``(F!]`0``(F!Z`0``(F![`0``(F!X`0``(F!Y`0``(F!V`0``(F!
+MW`0``(F1$`4``(F1#`4``(F1"`4``(F1P`0``(E!.(E!/(B!Q`0``(F!``4`
+M`(F!!`4``(F!^`0``(F!_`0``,-5B^R`>2@`=%Z+02R%P'17BY$`!0``5HNQ
+M!`4``%>+^@O^=!B)51"+D?@$```!50B+D?P$``")=10150S_=13_=1#_=0S_
+M=0C_L+17``#_L+!7``#_L?0$``#_L?`$``#HVB4``%]>7<(0`(M$)`2%P'0#
+MB4$LBT0D"(7`=`.)03"#B<`$``#_P@@`58OLBT4,,])6#[<P.%44="+_=1CW
+MWE+_=10;]B-U"/]U$(FQ%`4``%"#P4#H"Y7__^LM]]X;]B-U"(-]"!U3_W48
+M#YS#B;$8!0``#[;S5E+_=1"!P8`"``!0Z-V4__];7EW"%`"+1"0$B4$4BT0D
+M",9!#`&)01#""`!6B_&-3D#H.A$``(V.@`(``.@O$0``B\[H(?[__XO&7L-5
+MB^R#[`R+10A35E<S_XOQB7WXB47\.7T,#X;'````BUXL,\`[1B2)7?1\#W\(
+MBT4,.T8@=@6+1B#K`XM%#(`^`'07_W8$_W8(_W4(Z,82``"+?@2#9@0`ZT"#
+M>P3_#X3P````4/]U_(O+Z-3!__^+^(M&.(7`=0:-@]!*``#V0`@"=!97_W7\
+MC9X0!0``_S/H%)/__XD#BUWTB\>9C8[H!````0$1400!??@!??PI?0PI1B"+
+M1B`95B0+1B1U)SB&Q@0``'0?#[:&Q`0``%!J`593Z"Z)``"$P'1]@WT,``^'
+M.?___XM&+(7`="V+B*!Q``#_MM0$```#CN@$``"+@*1Q``#_MM`$```3ANP$
+M``!048O.Z,#]__^#__]T)X.^&`4```"+1?B+^'09J`]T!H/@\(/`$%#_=0B-
+MCH`"``#H1Y/__^B440``B\=?7EO)P@@`@\C_Z_3&AL<$```!Z_)3BUPD"%:+
+M\8!^#`!7BWPD%(E>'(E^&'07.WX0=R)74_]V%.B-$0```7X4*7X0ZQ"`?BD`
+M=0J+3C!74^B,O___C8;P!````3B#4`0`@'XJ`'415X'&#`4``%/_-NCFD?__
+MB0;H%5$``%]>6\((`(O!,\F)"(E(!(A($,/_,>B"$```PU6+[+@L-```Z*UU
+M__]7:ES_=0B+^>A^%0``A<"-A=3K__]U)V@`!```4&H`_Q6H,$$`:ER-A=3K
+M__]0Z(45``"%P`^$=0(``(/``O]U"%#H"A0``%:-C=3S___HS[?__S/V5FH!
+MC874Z___4%:-C=3S___HO[G__X3`=1"-C=3S___HC;G__^DP`@``@TW\_\9%
+M"P")=?A3@WW\_P^%#0$``(V-U//__^BBN/__B]AH`"```(V%U,O__U"-C=3S
+M___HF+___XE%]#/V@\#P#XBJ````@+PUU,O__RIU(H"\-=7+__\J=1AJ"V@,
+M-T$`C80UULO__U#HO1(``(7`='EF@[PUU,O__RIU*8V$-=C+__]F@WC^*G4;
+MBTWT@\'@._%_$6H+:/`V00!0Z`D4``"%P'1!@+PUU,O__U)U)H"\-=7+__]A
+M=1QJ!&CH-D$`C80UULO__U#H71(``(7`#X1,`0``BT7T1H/`\#OP#XYA____
+MZPG&10L!`_.)=?R+1?1J`(U$&/!J`%"-C=3S___H%;W___]%^(%]^(`````/
+M@O/^__^#??S_#X0!`0``BT7\F6H`4E"-C=3S___HZ+S__V@"``@`Z)P.``")
+M!XV-U//__X7`#X3:````:```"`!0Z'>^__^`?0L`B4<$=`?1Z(E'!.LSC40`
+M`E#H9PX``(OPA?8/A*4```"+1P2+#\8$"`"+1P1`4%;_-^B64@``_S?H60X`
+M`(DWBT\$N```!``[R'<"B\&+#S/29HD403/),]LY3P1V7(L'#[<46$-FA=)T
+M4&:#^EQU,0^W-%B#[B)T(X/N.G0:@^X2=!&#[@1T"$Y.=21J">L.:@WK"FH*
+MZP9J7.L":B)#ZPYF@_H-=`9F@_H*=0-J#%IFB11(03M?!'*DBP<STF:)%$B)
+M3P2-C=3S___H6;?__UM>7\G"!``SP#D!#Y7`PU:+,0^W!E=FA<!T4(M\)`QF
+M.P=U+6H'C4<"4(U&`E#H2Q(``(7`=1IF@WX0/7439H-^$B)U#(O&ZR1F@_@,
+M=`Q&1@^W!F:%P'7PZP)&1F:#/@QT^`^W!F:%P'6T,\!?7L($`(!Y$`!T'FKL
+M_W0D"/\50#)!``T``$``4&KL_W0D#/\5/#)!`,($`%6+[+@4(```Z%ER__]3
+MB]F#.P!65P^$$@$``(M%%(/H`+DR-T$`=!1(=`I(=1.Y,#=!`.L,N2PW00#K
+M!;DH-T$`:@%1:O_H)8[__X-]&`"+^+X`$```="Q6C87LW___4/]U&.C)4```
+MC87LW___4.@X#@``4(V%[-___U!7Z.Z-__^+^%:-A>SO__]0_W4(Z)U0``"-
+MA>SO__]0QD7K`.@(#@``4(V%[.___U!7Z+Z-___WT%!H'#=!`(U%[&H*4.A9
+M$@``@\00C47L4(O+Z*/^__^%P'16C5@4:@Q3Z&(1``"%P'0(*\/1^(OPZP6^
+M_P```(M%$(U(_SOQ=@CWV!O`(\&+\(M]#(7V=@A64U?H)A```&HB,\!79HD$
+M=^A/$0``A<!T&#/)9HD(ZQ&+10PY10AT"?]U"%#HS`\``%]>6\G"%`!5B^R!
+M[``$``!35E?_=0B-A0#\__]J`6@``@``4&@T-T$`Z)3^__]J*HV%`/S__U#H
+MRA```(OX:F1;A?]T(8V%`/S__U#H25,``(MU#(/'`E>)!N@[4P``BTT0B0'K
+M"HM-$(MU#(D9B1XY'G4(.1EU!#/`ZP,SP$!?7EO)P@P`58OL@>P`"```5E=J
+M`(OY_Q6P,$$`:@6^0#=!`%90_Q6L,$$`A<!T!L9'$`'K,K@X-T$`4&H!:``$
+M``"-C0#X__]14(O/Z/+]__]6C84`^/__4.AZ#P``]]@:P/[`B$<07U[)PU6+
+M[('L1`@``%-65XU%^%"-1?10_W4,B4WPZ/[^__^+'9PR00"(1?^-1=Q0_W4(
+M_].-1;Q0_W4(_Q5<,D$`BWWD*WW$BW7HBT7(*WW<*_`K=>!'1H!]_P!T,X!]
+M$`!U<@^O1?AH!@(``)EJ9%GW^0/&4(M%Q`^O1?29]_D#QU`SP%!04/]U"/\5
+MB#)!`(!]$`!U/V@`!```C86\]___4/]U"/\5C#)!`/]U#(M-\&H!:``$``"-
+MA;SW__]04.@6_?__C86\]___4/]U"/\5,#)!`&H(_Q60,D$`:@7_=0@K\/\5
+ME#)!`(-E"`")11")1>SIV````(%]"``"```/C=,```!H``0``(V%O/?__U#_
+M=1#_%8PR00!F@[V\]___`'0J_W4,BTWP:@%H``0``(V%O/?__U!0Z)S\__^-
+MA;SW__]0_W40_Q4P,D$`@'W_`'1FC47,4/]U$/_3BT78*T70:`0"``!`#Z]%
+M^)EJ9%GW^5"+1=0K1<Q`#Z]%])GW^5"+1=`K1>`KQ@^O1?B9]_E0B\>9*\*+
+MR(M%S-'Y*\$K1=QJ9`^O1?19F??Y4&H`_W40_Q6(,D$`:@+_=1#_%90R00")
+M11`[1>QT"_]%"(7`#X4@____7UY;R<(,`%;_="0(B_'HF_C__XO.Z*S]__]>
+MP@0`H:A^00!`HZA^00"#^`AR!S/`HZA^00!35<'@"@6H7D$`5HOP,\"]B%Y!
+M`%>+S6:)!N@<^___BQV$,D$`OP`"``"$P'425U;_="0<_S5X7D$`_].%P'4.
+M5U;_="0<_S5T7D$`_]-J`&H`5U96B\WH<?O__U^+QEY=6\($`(M$)`B+3"0,
+MBU0D!%:+,#,QB3*+<`0S<02)<@2+<`@S<0B)<@B+0`PS00Q>B4(,P@P`58OL
+M@^PH4U97:B#_=0B-1=A0B4WXZ/H(```SP&H$,\F)10@SVUJ#^`H/C]\````[
+MVGTBC72=V(EU_#O*?1F+??B--(&-?+<4BW7\`57\0T$[VJ5\Y3O*=09`B44(
+M,\D[VGS#@_@*#X^B````QT7\L*Y!``^V=>6*1=@RAM"O00`/MG7FBI[0KT$`
+M#[9UYS!=V8J>T*]!``^V=>0P7=J*GM"O00"+=?PR!C!=V_]%_&H#B$78C47<
+M7S/VBEPP_#`<,$8[\GST`\)/=>TSVX-]"`I_.SO:?2"-1)W8.\I]&HMU"(M]
+M^(TTL8U\MQ2+\$,#PD$[VJ5\Y#O*=07_10@SR3O:?,F#?0@*#XYE____7UY;
+MR<($`%6+[(/L'%-65X/!)&H$B4W\QT7T"0```%\SP(M-_(UT!>2#P0*)??@/
+MME$!#[99_XJ4D+!^00`RE)BPAD$`#[99_C*4F+"*00`/MADRE)BP@D$``\^(
+M%@/W_TWX=<I`.\=\N&H0C47D4/]U_.B.!P``@T7\$/]-]'6?7UY;R<-5B^R#
+M[!!35E>+^8V'M````%#_=0B-1?!0Z!S^__\/MD7PBP2%L)I!``^V3?TS!(VP
+MED$`#[9-^C,$C;"200`/MDWW,P2-L(Y!`(MU#`^V3?&)!@^V1?2+!(6PFD$`
+M,P2-L)9!``^V3?XS!(VPDD$`#[9-^S,$C;".00`/MDWUB48$#[9%^(L$A;":
+M00`S!(VPED$`#[9-\C,$C;"200`/MDW_,P2-L(Y!``^V3?F)1@@/MD7\BP2%
+ML)I!`#,$C;"600`/MDWV,P2-L))!``^V3?,S!(VPCD$`C9^D````B48,QT4(
+M"````%-6C47P4.A&_?__#[9%\(L$A;":00`/MDW],P2-L)9!``^V3?HS!(VP
+MDD$`#[9-]S,$C;".00`/MDWQB08/MD7TBP2%L)I!`#,$C;"600`/MDW^,P2-
+ML))!``^V3?LS!(VPCD$`#[9-]8E&!`^V1?B+!(6PFD$`,P2-L)9!``^V3?(S
+M!(VPDD$`#[9-_S,$C;".00`/MDWYB48(#[9%_(L$A;":00`S!(VPED$`#[9-
+M]C,$C;"200`/MDWS,P2-L(Y!`(/K$/]-"(E&#`^%+O___XU')%!6C47P4.AQ
+M_/__#[9%\(J`T*Y!`(@&#[9%_8J`T*Y!`(A&`0^V1?J*@-"N00"(1@(/MD7W
+MBH#0KD$`B$8##[9%](J`T*Y!`(A&!`^V1?&*@-"N00"(1@4/MD7^BH#0KD$`
+MB$8&#[9%^XJ`T*Y!`(A&!P^V1?B*@-"N00"(1@@/MD7UBH#0KD$`B$8)#[9%
+M\HJ`T*Y!`(A&"@^V1?^*@-"N00"(1@L/MD7\BH#0KD$`B$8,#[9%^8J`T*Y!
+M`(A&#0^V1?:*@-"N00"(1@X/MD7SBH#0KD$`@\<45U96B$8/Z)?[__]?7EO)
+MP@@`58OL@>P$`P``4U8SP#/)0+X;`0``5XO0@.*`#[[2B(0-_/S__XB$#?O]
+M__^(C`7\_O__0??:&](CUHT\`#/7,\*#^`%UT#/)7XO0@.*`#[[2]]H;THB!
+ML*Y!`"/6`\`SPD&#^1YRXC/;B5W\ZP.+7?R$VW08#[;##[:$!?S^__^-C?O]
+M__\KR`^V`>L",\"-#``SR`/),\@#R3/(`\DSP8O(P?D(,LB`\6.-!)T`````
+MC9"PGD$`B(O0KT$`B$H!B`J(B+.B00"(B+"B00"(B+.F00"(B+*F00"(B+*J
+M00"(B+&J00!T%0^VT0^VE!7\_O__#[:4%17]___K`C/2B)"SGD$`B)"RHD$`
+MB)"QID$`B)"PJD$`A,ET%0^VR0^VC`W\_O__#[:,#?W\___K`C/)B(BRGD$`
+MB(BQHD$`B(BPID$`B(BSJD$`#[;SB\[!X0,SSL'A`C/.`\F+T<'Z"#+1@/(%
+M=#*+SL'A`S/.P>$",\X#R8O1P?H(#[;2#[;),]&#\@4/MHP5_/[__XV5^_W_
+M_RO1BAKK`C+;BTW\B)G0KD$`A-MT%0^VRP^VC`W\_O__#[:4#63]___K`C/2
+M#[;SB\[!X0*(D+*.00"(D+&200"(D+"600"(D+.:00"(D;)^00"(D;&"00"(
+MD;"&00"(D;.*00"$VW02#[:4-?S^__\/MI05P_W__^L",]*(D+".00"(D+.2
+M00"(D+*600"(D+&:00"(D;!^00"(D;."00"(D;*&00"(D;&*00"$VW02#[:4
+M-?S^__\/MI05ZOW__^L",]*(D+&.00"(D+"200"(D+.600"(D+*:00"(D;%^
+M00"(D;""00"(D;.&00"(D;**00"$VW02#[:4-?S^__\/MI05V_W__^L",]+_
+M1?R!??P``0``B)"SCD$`B)"RDD$`B)"QED$`B)"PFD$`B)&S?D$`B)&R@D$`
+MB)&QAD$`B)&PBD$`#XR/_?__7EO)PX`]T*]!``!6B_%U!>@,_?__B\9>PU6+
+M[(M%"(/L(%:+\5.)!C/`5XM]#(H<.(O(B]#!Z0*#X@-`C505X(@<BH/X$'+C
+M7S/`6XM-$(H,"(A,!@1`@_@0?/"-1>!0B\[H?/C__X,^`74'B\[HA?G__U[)
+MP@P`58OL@^PD4U97BWT(B]F%_P^$E@```(MU#(7V#X:+````C4,$:A!0B44,
+MC47<4.A,`0``P>X$B77\B74(A?9V5HMU$(U%[%!7B\OHL/G__XU%W%"-1>Q0
+M4.C<]___BP>)1=R+1P2)1>"+1PB)1>2+1PR)1>B+1>R)!HM%\(E&!(M%](E&
+M"(M%^(E&#(/'$(/&$/]-"'6M:A"-1=Q0_W4,Z-L```"+1?S!X`3K`C/`7UY;
+MR<(,`%6+[/]U"&H`_Q6X,$$`4/\5M#!!`%W"!`!5B^R#?0@`=!+_=0AJ`/\5
+MN#!!`%#_%;PP00!=P@0`58OL@WT(`'4*_W4,Z+?____K%?]U#/]U"&H`_Q6X
+M,$$`4/\5P#!!`%W""`!5B^Q1:@&-10A0C44(4/\5>#)!``^V10A0_Q5\,D$`
+MB47\:@&-1?Q0C47\4/\5@#)!`(M%_,G"!`!5B^Q1@V7\`.L'BT7\0(E%_(M%
+M_#M%$',-BT4(`T7\BDT,B`CKY(M%",G"#`!5B^Q1@V7\`.L'BT7\0(E%_(M%
+M_#M%$',2BT4(`T7\BTT,`TW\B@F(".O?BT4(R<(,`%6+[(M%$(M-$$F)31"%
+MP'8ZBT4(#[8`BTT,#[8).\%]!8/(_^LGBT4(#[8`BTT,#[8).\%^!8/(_^L2
+MBT4(0(E%"(M%#$")10SKN#/`7<(,`%6+[%&+10@[10QS$/]U$/]U#/]U".AC
+M____ZRB+11!(B47\ZP>+1?Q(B47\@WW\`'P2BT4(`T7\BTT,`TW\B@F(".OA
+MBT4(R<(,`%6+[%&#9?P`BT4(#[X`BTT(08E-"(7`=`F+1?Q`B47\Z^:+1?S)
+MP@0`58OLBT4(#[X`A<!T&8M%"`^^`#M%#'4%BT4(ZPN+10A`B44(Z]TSP%W"
+M"`!5B^Q1_W4(Z)____](B47\ZP>+1?Q(B47\@WW\`'P8BT4(`T7\#[X`.T4,
+M=0B+10@#1?SK!.O;,\#)P@@`58OL45&#9?P`ZP>+1?Q`B47\BT4(`T7\#[X`
+MA<!T/(-E^`#K!XM%^$")1?B+10P#1?@/O@"%P'0@BT4(`T7\#[X`BTT,`TWX
+M#[X).\%U"(M%"`-%_.L&Z\SKL#/`R<((`%6+[(M%#`^^`(7`=!J+10B+30R*
+M"8@(BT4(0(E%"(M%#$")10SKW(M%",8``(M%"%W""`!5B^R+11"+31!)B4T0
+MA<!V)HM%"(M-#(H)B`B+10A`B44(BT4,#[X`A<!U`NL)BT4,0(E%#.O,BT4(
+M7<(,`%6+[#/`0'1&BT4(#[X`BTT,#[X).\%]!8/(_^LSBT4(#[X`BTT,#[X)
+M.\%^!8/(_^L>BT4(#[X`A<!U`NL0BT4(0(E%"(M%#$")10SKM3/`7<((`%6+
+M[(M%$(M-$$F)31"%P'9&BT4(#[X`BTT,#[X).\%]!8/(_^LSBT4(#[X`BTT,
+M#[X).\%^!8/(_^L>BT4(#[X`A<!U`NL0BT4(0(E%"(M%#$")10SKK#/`7<(,
+M`%6+[/]U#/]U".C<_?__`T4(4.C&_O__BT4(7<((`%6+[%&#9?P`BT4(#[<`
+MBTT(04&)30B%P'0)BT7\0(E%_.OEBT7\R<($`%6+[(M%"(M-#&:+"6:)"(M%
+M"$!`B44(BT4,#[<`BTT,04&)30R%P'7:BT4(7<((`%6+[(M%"(M-#&:+"6:)
+M"(M%"$!`B44(BT4,#[<`BTT,04&)30R%P'0-BT402(E%$(-]$`!_S8M%"%W"
+M#`!5B^S_=0S_=0CH6____XM-"(T$05#H>?___UW""`!5B^R+10@/MP"+30P/
+MMPD[P74@BT4(#[<`A<!U!#/`ZRN+10A`0(E%"(M%#$!`B44,Z]"+10@/MP"+
+M30P/MPDSTCO!#YW"C502_XO"7<((`%6+[(M%$(M-$$F)31"%P'Y(BT4(#[<`
+MBTT,#[<).\%]!8/(_^LUBT4(#[<`BTT,#[<).\%^!8/(_^L@BT4(#[<`A<!U
+M`NL2BT4(0$")10B+10Q`0(E%#.NJ,\!=P@P`58OLBT4(#[<`A<!T&HM%"`^W
+M`#M%#'4%BT4(ZPR+10A`0(E%".O<,\!=P@@`58OL4?]U".AC_O__2(E%_.L'
+MBT7\2(E%_(-]_`!\'(M%_(M-"`^W!$$[10QU"XM%_(M-"(T$0>L$Z]<SP,G"
+M"`!5B^R+10@/MP"%P'0BBT4(#[<`4/]U#.AV____A<!T!8M%".L,BT4(0$")
+M10CKU#/`7<((`%6+[/]U"/\5R#!!`%W"!`!5B^Q1C440B47\_W7\_W4,_W4(
+M_Q4<,D$`@V7\`/]U".B0^___R<-5B^Q1C444B47\_W7\_W40_W4(_Q7$,4$`
+M@V7\`/]U".B=_?__R<-5B^Q1@WT(,'P/@WT(.7\)QT7\`0```.L$@V7\`(M%
+M_,G"!`!5B^S_=0CHN?G__UW#58OL_W4(Z)/Y__]=PU6+[%&#9?P`BT4(#[8`
+M4.BN____A<!T'(M%_&O`"HM-"`^^"8U$"-")1?R+10A`B44(Z]2+1?S)P@0`
+M58OL_Q60,$$`7<.+1"0(PU6+[(/L(&CX3$(`:`$!``#HYO___UE9B47\@WW\
+M`'0-BTW\Z,!!``")1>SK!(-E[`!H?%Y!`&H,Z+[___]968E%^(-]^`!T#8M-
+M^.CZ@/__B47HZP2#9>@`:(A>00!J%.B6____65F)1?2#??0`=`V+3?3H4>C_
+M_XE%Y.L$@V7D`&@XTT$`:`A/``#H:____UE9B47P@WWP`'0-BTWPZ)EY__^)
+M1>#K!(-EX`#)PS/`PXM,)`R%R70CBD0D"`^VP&G``0$!`8O14U>+?"0,P>D"
+M\ZN+RH/A`_.J7UN+1"0$PU6+[(-]$`!U!#/`7<.+30R+10C_31!T"HH0.A%U
+M!$!!Z_$/M@`/M@DKP5W#BT0D!(7`?0+WV,/HX_[__S/`4%!04.C5+0``PU97
+MBWPD#(OQB\^)/NCSH/__B48(B58,BX<<#```B4807XO&7L($`(O!BPB+4!`[
+MD1P,``!U#6H`_W`,_W`(Z!RF___#58OL@^P<5C/V5E965HU%Y%#_%4@R00"%
+MP'0A5E96C47D4/\53#)!`(U%Y%#_%5`R00"-1>10_Q54,D$`7LG#58OL@>PL
+M`0``@SVP4$$``%-65[\`!```=3%J9(V%U/[__U!J#U?_%<PP00!FBX74_O__
+M9J-`(D(`,\!FHT(B0@#'!;!000!`(D(`C46<4/]U#/]U".A9-0``BUT4BW40
+M4U8SP&B@4$$`9HD&C46<4&H`5_\5T#!!`#/`7V:)1%[^7EO)PA``58OLBT4(
+M/4!"#P!V!\'H",%M#`B#?0P`=00SP.L2.44,<P5J9%CK"&O`9#/2]W4,7<((
+M`%6+[%%35HMU"%>%]@^$HP````^W!F:%P`^$EP```(M]#(EU_,9%"P!J(EIF
+M.\)U2(U.`F8Y$74A@'T+`'44.W7\=0\/MT8$9H/X+'0,9H7`=`>+\6:)%^LQ
+MBET+A-MT!L9%"P#K#5)1Z*+[__^%P`^510LZ70MU%`^W!F:#^"QU!H!]"P!T
+M%F:)!T='1D8/MP9FA<!UDC/`9HD'ZQ0SP&:)!T9&#[<&4.C<,P``A,!U\8O&
+MZPB+30PSP&:)`5]>6\G""`!5B^Q148U%^%#_%:PQ00"-1?Q0_W4,:@#_%:@Q
+M00#_=0C_=?S_%;0Q00"+1?C_=?R+"%#_413)P@@`BT0D!&:#.`"+R'0X5@^W
+M$6:#^EQU(`^W<0)F._)U#6I<6F:)$$!`@\$$ZQ%F@_YN=01J"NOK9HD00$!!
+M06:#.0!UREXSR6:)",($`%6+[(/L*%-65S/_5_\5S#%!`(LU7#!!`%")1?C_
+MUO]U^(O8_]:)1?R-1=A0:AC_=0C_%4PP00"+1>`/KT4,F?=]W#M%$'T#B440
+M_W40_W4,_W7X_Q50,$$`_W4(BS54,$$`4XE%]/_6_W7TB44(_W7\_]9H(`#,
+M`/]UX(E%\/]UW%=74_]U$/]U#%=7_W7\_Q58,$$`_W4(4__6_W7P_W7\_]:+
+M-60P00!3_];_=?S_UO]U^%?_%<@Q00"+1?1?7EO)P@P`@SU$(D(``'4G5FH`
+M_Q7,,4$`B_"%]G07:EA6_Q5(,$$`5FH`HT0B0@#_%<@Q00!>H40B0@`/KT0D
+M!&I@F5GW^<($`(,]2")"``!U)U9J`/\5S#%!`(OPA?9T%VI:5O\52#!!`%9J
+M`*-((D(`_Q7(,4$`7J%((D(`#Z]$)`1J8)E9]_G"!`!J9.AS____@_A]?0]J
+M9.BJ____@_A]?0,SP,,SP$##4XM<)`A65U/HZO?__XOX,\EJ`EJ-1P/WX@^0
+MP??9"\A1Z&?Z__]9B_!3C48"4.CN]___:B)89HE$?@)FB096,\!39HE$?@3H
+MU??__U;H+OK__UE?7HO#6\($`%6+[(/L8%-65VIH_S4`PD$`_Q5P,D$`@#T4
+MTT$``(LUT#%!`(OXB7W\N[$```!U,HL-U+!!`.B=L?__:@57_Q5L,D$`:O]J
+M`%-7_]9H-#=!`&H`:,(```!7_];&!13300`!OP#A]0575U/_=?S_UHU%H%!J
+M`&@Z!```_W7\QT6@7````/_6,\!`@'T(`,9%N0")1:1T'(M-J('A____OPO(
+MB4VHQT6TH````,=%I`$``$"-3:!14&A$!```_W7\_];_=0QJ`&C"````_W7\
+M_]975U/_=?S_UH!]"`!T'HM%J(/@_@T```!`B46HC46@4&H!:$0$``#_=?S_
+MUFA8-T$`:@!HP@```/]U_/_67UY;R<((`%6+[+@`&```Z`%8__^+10B%P'0F
+M9H,X`'0FC4T,45"-A0#H__]0_Q7$,4$`C84`Z/__4&H!Z++^____!?C!00#)
+MPU6+[+@`%```Z+]7__]H``0``(V%`/C__U#_=0S_=0CH`\'__X!]&`"-A0#X
+M__]0=`1J9NL":F7H1NG__U"-A0#L__]H``8``%#H-OC__X/$$(V%`.S__U!J
+M9?\U`,)!`/\5U#%!`.@V^O__,\`X!?+!00`/E,#)PA0`58UL))BX4!(``.A#
+M5___4U>+?7`SVU-3:(`W00#_=7S_=7C_=717Z`AW__^$P'0(,\!`Z0L#``"+
+M170M$`$``%9T:4@/A?8"```/MT5X:@)>*\9T&(/H:G1-2'032'1#2'0\2'0U
+M2`^%TP(``&H%7E-3:'$!``!J9E?_%>0Q00`[PW0'4/\5X#%!`%97_Q7<,4$`
+M,\!`Z:<"``!J!NO0:@/KS&H$Z\@S]D;KQ&IL5_\5<#)!`%#_%=@Q00"^``0`
+M`%;_=7R-A1CN__]0Z!XO``!64XV%&.[__U#HUKW__XV%&.[__U!J95>+/=0Q
+M00#_UV@``0``:+0"``"-A1CV__]04XV%&.[__U#_%:0Q00!3_[48]O__:'`!
+M``!J9O]U</\5Y#%!`(V%S/S__U"-A1CN__]0_Q6,,$$`B45T@_C_#X3Y`0``
+MC45(4(V%X/S__U#_%>0P00"-15A0C45(4/\5X#!!`&HRC46`4%.-15A0:@)6
+M_Q7<,$$`:C*-1>104XU%6%!35O\5V#!!`(U%@%"-1>10:($```#H:>?__U!H
+M;#=!`+L``@``C87,^/__4U#H4_;__X/$&(V%S/C__U!J:O]U</_7_W5T_Q5\
+M,$$`]H7,_/__$'5G:C*-A1S___]0:@%J`&H`_[7H_/__Z(Y3__^+C>S\__\S
+MVP/!$]-24.A?^/__:(````#H]^;__U"-A1S___]0:&`W00"[``(``(V%S/C_
+M_U-0Z-KU__^#Q!2-A<SX__]0:FC_=7#_UVH`_[48]O__:'`!``!J9_]U</\5
+MY#%!`(U%4%`/MP7@P$$`4`^W!>+`00!0_Q6(,4$`C4584(U%4%#_%>`P00!J
+M,HU%@%!J`(U%6%!J`E;_%=PP00!J,HU%Y%!J`(U%6%!J`%;_%=@P00"-18!0
+MC47D4&B!````Z$OF__]0:&PW00"-A<SX__]34.@Z]?__@\08C87,^/__4&IK
+M_W5P_]?VA<S\__\0H>S`00"+#>C`00!T!HO1"]!T16HRC94<____4E!1Z%OW
+M__]H@````.CSY?__4(V%'/___U!H8#=!`(V%S/C__U-0Z-OT__^#Q!2-A<SX
+M__]0:FG_=7#_US/`7E];@\5HR<(0`%6+[%:+=117BWT(:@!J`&B@-T$`5O]U
+M$/]U#%?HQW/__X3`=5N+10PM$`$``'0T2'4*#[=%$$AT$DAT!#/`ZT-J`%?_
+M%=PQ00#K-6@`!```_S5,(D(`:F97_Q7H,4$`:@'KWU9J98DU3")"`(LUU#%!
+M`%?_UO\U3")"`&IF5__6,\!`7UY=PA``58OL5HMU"&H`:@!HM#=!`/]U%/]U
+M$/]U#%;H0'/__X3`=4F+10PM$`$``'0S2'4*#[=%$$AT$DAT!#/`ZS%J`%;_
+M%=PQ00#K(VB`````:/#`00!J95;_%>@Q00!J`>O@_W44:F96_Q74,4$`,\!`
+M7EW"$`!J`/]T)!#_="0,Z)7V__]0:`($``!J:O\U`,)!`/\5Y#%!`,(0`%6+
+M[+@`(```Z-92__^`/?+!00``=46+10QF@S@`=#Q6_Q6$,4$`B_"-11!0_W4,
+MC84`X/__4/\5Q#%!`(V%`.#__U!H!#-!`.B(^O__65F%]G0'5O\5@#%!`%[)
+MP_]T)"#_="0@_W0D(/]T)"#H:/___^A!]?__PB``58OLN&`>``#H7%+__U;H
+MU2D``&C0-T$`:/L)0@#H@.___XL-+")"`&C\,D$`Z!,M``#_=0AH+!I"`.C.
+M\/___W4(OCC300!J`(O.Z/-J__]J!%BC[`5"`*/H!4(`H^0%0@"@Y<!!`*)\
+M`$(`H.3`00"-C:#A___&!:P`0@`!HGT`0@#HRWO__U:-C:#A___HAXW__XV-
+MH.'__^B(?/__7LG"!`!5B^Q6BW445XM]"&H`:@!HU#=!`%;_=1#_=0Q7Z(9Q
+M__^$P`^%@0```(M%#"T0`0``=&=(=0\/MT402'1%2'0W@^AD=`0SP.MD:@#_
+M-5`B0@#HSKO__U#_-5`B0@!J>^@7X___4%?H"FC__X3`=#O_-5`B0@#K*FH`
+M5_\5W#%!`.LH:``$``#_-5`B0@!J95?_%>@Q00!J`>O?B350(D(`5FIE5_\5
+MU#%!`#/`0%]>7<(0`%6+[+@`%```Z`51__^`?0A4=`^`?0A8=1#'10AY````
+MZP?'10@+`@``:``$``"-A0#X__]0_W40_W4,Z"VZ__^-A0#X__]0Z"6[__]0
+M_W4(Z'/B__]0C84`[/__:``&``!0Z&/Q__^#Q!"-A0#L__]0:@#H>/?__\G"
+M#`!5B^R![`0(``"#9?P`4U:+=0A7ZP)&1@^W!E#HSB@``(3`=?$/MP9FA<`/
+MA&P!```S_S+;A-MU#0^WP%#HK2@``(3`=4N!__\#``!S0P^W!FHB668[P74E
+MC48"9CD(=19F.4X$=02$VW0.9HF,??SW__^+\.L/A-L/E,/K"6:)A'W\]___
+M1T9&#[<&9H7`=:0SP/]%_(-]_`%FB81]_/?__P^$</___V:#O?SW__\O=`YF
+M@[W\]___+0^%6/___P^WA?[W__]0Z-4Q``"#Z$0/A*P```!(='F#Z`MT88/H
+M`P^%,?___P^WA0#X__]0Z*XQ``"#Z`!T,(/H,70K2'0<@^@>#X4.____:``$
+M``"-A0+X__]0:!+*00#K=L<%#,)!``(```#K"L<%#,)!``$```#&!1;300`!
+MZ=G^__]H@````(V%`/C__U!H$M)!`.M!#[>%`/C__U#H0S$``(/X3`^%L/[_
+M_V:#O0+X__\`#X6B_O__Q@41PD$``>F6_O__:``$``"-A0#X__]0:!+"00#H
+MG"<``.E[_O__7UY;R<($`%6+[+@`(```Z.9.__]3B]E7BWT(A=MT`\8#`(M%
+M$(7`=`/&``"%_P^$H0````^W!V:%P`^$E0```%8S]C/)#[?`1T=F@_@]=16#
+M?0P`=!N%]G47A=MT`\8#`8ORZQMF@_@-="AF@_@*="1FB0*+111"@\#^0CO(
+M?PL/MP=!9H7`=;SK"HM%$,8``>L"1T>+70PSP&:)`H7;="]FB0.%]G0H:``0
+M``"-A0#@__]05O\5Z#!!`/]U%(V%`.#__U!3Z,PF```SP&:)!HO'7NL",\!?
+M6\G"$`!5B^R#[!Q6BS7L,$$`5VH*_W4(_]:_`@$``.L9:@%J`&H`:@"-1>10
+M_Q5(,D$`:@K_=0C_UCO'=.-?7LG"!`!5B^R!["`(``!H``0``(V%X/?__U#H
+M&V0``(`]%=-!``!U:VH&_S6<4$$`C87@]___4.@&N/__4.@\+P``A<!U36CL
+M-T$`Z-=C``"-A>#W__]0Z`'L__\SR6H>9HF,1>+W__]1C47@4.B\Z/__:A18
+M9HE%\(V%X/?__XE%Z(U%X%#'1>0#````_Q6@,4$`R<-5B^RX!"```.A!3?__
+M4U9H```"`.CCY___B_"%]G4*N7Q>00#HZV___S/`9HD&,]OK;6:#/@!U"F:#
+MO?S?__][=%UF@[W\W___?71WC87\W___4.APZ___`\,]^_\``'=BC87\W___
+M4%;H\>O__U;H5.O__XO8A=MV$8U$7OYF@S@@=0=+2$B%VW?S@'W_`'4.:%@W
+M00"-!%Y0Z%/K__]H`!```(U%_U!J`/\W,\F-E?S?___HHOW__XD'A<`/A6__
+M__^+QEY;R<-3,]O&!?'!00`!.1T`PD$`=!9J?>@BWO__4&H"_S4`PD$`_Q74
+M,4$`H0#"00")'?3!00#&!?#!00`!.\-T2VH!4/\5;#)!`#D=)--!`'4(.!T4
+MTT$`=`@Y'?C!00!U(E-J`6@1`0``_S4`PD$`_Q70,4$`ZPQ3_Q7P,$$`Z-GN
+M__\Y'0#"00!U[#@=",)!`%MT!>D0_O__P_]T)`16Z(?J__\SR68Y#G0GB\8/
+MMQ!F@_HZ=`QF@_I<=`9F@_HO=09J)5IFB1!!C01.9H,X`'7;P@0`58OL@>P(
+M"```4S/;.!T0PD$`=&QF.1W8L$$`=&-6:-BP00"-M?CW___HE____XU%^%"-
+M1?Q04V@&``(`4U-3:/0W00!H`0``@/\5$#!!`%Z%P'4L_W4(Z-#I__^-1``"
+M4/]U"(V%^/?__VH!4U#_=?S_%10P00#_=?S_%1@P00!;R<($`%6+[+@,$```
+MZ"!+__^`/1#"00``#X2-````5O]U"(VU].___^@7____C47X4&H!:@!H]#=!
+M`&@!``"`_Q4`,$$`7H7`=6&-1?Q0C87T]___4(U%]%!J`(V%].___U#_=?C'
+M1?P`"```_Q4,,$$`A<!U+-%M_+C_`P``.47\<P.+1?S_=0PSR6:)C$7T]___
+MC87T]___4/]U".@L(P``_W7X_Q48,$$`R<((`%6+[('L'`@``.C8\/__A,`/
+MA-D```!7:@7_=0C_%90R00"#90@`B_B)??R%_P^$NP```%.+'=`Q00!6@7T(
+M``(```^-I````&@`!```C87D]___4%?_%>PQ00!H'#A!`(V%Y/?__U#H]"H`
+M`(7`=6%J\%?_%4`R00"#X!\\#G51:@!J`&AS`0``5__3B_"%]G0_C47D4&H8
+M5O\53#!!`/]U[.C\[___4/]UZ.BP[___4%;HY.[__U!J`&AR`0``5__3.S78
+MN$$`=`=6_Q5@,$$`:@)7_Q64,D$`B_@[??QT"_]%"(7_#X5/____7EM?R<($
+M`%:+="0(:B!6Z&#I__^%P'0:9H,^(G045N@TL/__9H,X(G0(5NCI[___ZP*+
+MQE["!`!5B^Q6BS7P,4$`@#WFP$$``(M%#*/HP$$`BT40H^S`00"+112CX,!!
+M`'0%,\!`ZRF`/>?`00``=`5J`ECK&_]U"&BNND``_S4`PD$`:(`W00#_-71>
+M00#_UDAT3TAT7DAT0DAU(_]U"&CZO4``_S4`PD$`:*`W00#_-71>00#_UH7`
+M=(:P4NLP2'0.2+!.=2C&!>?`00`!ZQ_&!?+!00`!L$/K%,8%YL!!``%J`/]U
+M"/\5U#!!`+!97EW"$`"P3NOW58OL@>P`"```4U:+=0Q7BWT(:``$``"-A0#X
+M__]05E?HT['___]U&(V%`/C___]U%/]U$%#H!?___XK8A?9T$V:#/@!T#8V%
+M`/C__U!6Z.[F__^%_W07@#\`=!)H`````5>-A0#X__]0Z/HF``!?7HK#6\G"
+M&`!5B^R![``(``!F@ST2TD$``%9T$?]U&(MU%&@2TD$`5NF+````@WT(`J$`
+MPD$`B_!U#5#_%?0Q00"%P'4",_9H``0``(V%`/C__U#_=1#_=0SH*['__V:#
+M/?#`00``=3&-A0#X__]0:(.^0`!6:+0W00#_-71>00#_%?`Q00"%P'4/BW44
+M9HD&Q@7RP4$``>L.BW44:/#`00!6Z"OF__]F@SX`=!!H@````%9H$M)!`.A%
+MYO__,\!F.09>#Y7`R<(4`%6+[('L``@``%9H``0``(V%`/C__U#_=0S_=0CH
+MGK#__XV%`/C__U!H.\!``/\U`,)!`&C4-T$`_S5X7D$`_Q7P,4$`@WT(`(OP
+M=!1H`````?]U"(V%`/C__U#HSR4``(-]#`!T#XV%`/C__U#_=0SHD^7__XO&
+M7LG""`!5B^RX0!```.C;1O__4U:+\3/;9CD>#X0;`@``5NA`Y?__/?8#```/
+M@PH"``!7:CQ?5U.-1<!0Z/?A__\/MPZ)?<#'1<3`!0``9H/Y(G4(C48"B470
+MZP.)==`SP&8[RW1/B\YF@SDB=1GK!V:#/$8B=`E`9CD<1G7RZP=J(%EFB0Q&
+M9H,\1B!T$V:#?$8"+W0+0(T,1F8Y&77)ZQ2-!$9F@S@@=04SR6:)"(/``HE%
+MU#A="'409CD=$LI!`'0'QT74$LI!`/]UT,=%W`$```#H!;/__XE%_#O#=!9H
+M2#A!`%#HX"8``(7`=0?'1<PX.$$`_W70Z,B1__^*V(3;=!B-A<#O__]0_W70
+MZ/*M__^-A<#O__^)1="`?0@`=#B$VW4T_W70C87`]___4.A<Y/__:"PX00"-
+MA<#W__]0Z+CD__^-A<#W__]0Z'21__^$P`^$X0```(L]G#%!`(U%P%#_UX7`
+M#Y7`A,!U'8%EQ/_[__^-1<!0B770_]>%P`^5P(3`#X2O````BS5L,D$`,MLX
+M'0C"00!U!3A="'0VH0#"00"%P'074/\5]#%!`(7`=`QJ`/\U`,)!`/_6LP%H
+MT`<``/]U^/\5^#%!`/]U^.CY]O___W7X_Q5\,4$`@WW\`'01:"PX00#_=?SH
+MV"4``(7`=#"`/0C"00``=`V`?0@`=0=H6!L``.L4,\`X10@/E,!()>#\__\%
+MZ`,``%#_%?`P00"$VW00@'T(`'0*:@'_-0#"00#_UE]>6\G"!`!5B^RXV%`!
+M`.B>1/__@WT,``^$$`L``&@`$```C44/4(V%T,?__U#_=0R-3?^-E2AO___H
+M@/7__XE%#(7`#X3D"@``4U97:@:[``0``(V%T,?__XVU**_^_U]64.@9Z/__
+M@<8`(```3W7P,_;_-+6X4$$`C84H;___4.@*)0``A<!T"T:#_@URX^EJ"@``
+M@_X,#X=A"@``_R2U@=A``(-]$`(/A5`*``!3C870]___4.A-6@``C870]___
+M4(V%T.?__U#HA^+__XV%T.?__U#H%*O__XV%T,?__U"-A=#G__]0Z-7B__^-
+MC<B[___HMI/__XV%T.?__U"-C<B[___HU)/__XV-**?__^A+:O__5XV%**?_
+M_U"-C<B[___H1)?__X3`#X1>`0``BSU$,4$`:@"-A2BK__]0_Q74,$$`@+TX
+ML___``^$J````.@6IO__.\,/A)L```"-A=#O__]0C870]___4.@=K/__C870
+M[___4.APJO__C870]___4.BAX?__B_"#_@1R$(V%T.___U#HCN'__SOP=Q:-
+MA=#'__]0:@#HW:G__X3`#X77````C84HJ___4.AHX?__,\EJ'F:)C$4JJ___
+M48U%T%#H(][__VH46&:)1>"-A2BK__^)1=B-1=!0QT74`P```/\5H#%!`(V%
+M**O__U#_UX/X_W1JC84HJ___4/\5;#!!`(7`=5DS]NL!1E:-A2BK__]0:.PX
+M00"-A=#O__]34.@QX___@\04C870[___4/_7@_C_==2-A=#O__]0C84HJ___
+M4/\5<#%!`(7`=!%J!&H`C870[___4/\5^#!!`&H`C84HI___4(V-R+O__^CF
+ME?__A,`/A:C^__^-C<B[___H,I+__^E@"```.7T0#X57"```H1S300"%P`^4
+MPX3;=0MHE#1!`%#H`N'__X!]_P!T"(V]T,?__^L*C7T,Z(WT__^+^(3;=`0S
+M]NL-_S4<TT$`Z$#@__^+\%?H..#__P/&C40`"E#_-1S300#HDMS__Z,<TT$`
+MA-MT!3/)9HD(5U#HJ.#__X!]_P`/A=H'``!7Z$[<___ISP<``#E]$`^%Q@<`
+M`(V%T,?__U#_=0C_%3`R00#IL0<``#E]$`^%J`<``&8Y/1+"00`/A9L'```S
+MP&:#O=#'__\BC;70Q___9HF%T/?__W4&C;72Q___5NBCW___.\,/@VX'```/
+MMP9F@_@N=1EF@WX"7'42C48$9CDX#X12!P``4.G<````9H/X7`^$T0```&8[
+MQW0+9H-^`CH/A,$```"-1?10:@%7:)@X00!H`@``@/\5`#!!`(7`=4B-1?A0
+MC870]___4(U%\%!7:'@X00#_=?3'1?@`"```_Q4,,$$`_W7T_Q48,$$`T6WX
+MN/\#```Y1?AS`XM%^#/)9HF,1=#W__]F.;W0]___="B-A=#W__]0Z.?>__]F
+M@[Q%SO?__UQT$6B(-D$`C870]___4.ABW___5NC%WO__B_B-A=#W__]0Z+?>
+M__\#^('__P,``',<5HV%T/?__U#H-]___^L-5HV%T/?__U#HN][__VHBC870
+M]___4.@4X/__A<!T#&:#>`(`=04SR6:)"(V%T/?__U"_V+!!`%?HB][__U.-
+MA=#W__]0Z*WT__]J9O]U"/\5<#)!`(OPC870]___4%;_%3`R00"+'=`Q00!7
+M:@!H0P$``%;_TXV%T/?__U!7Z-#>__^%P`^$Y@4``(V%T/?__U!J`&A#`0``
+M5O_3Z=`%``"#/0S"00`!#X3#!0``#[>%T,?__U#HKQ<``(3`=!0/MX70Q___
+M@^@PHPS"00#IG@4``,<%#,)!``(```#ICP4```^WA=#'__\KQW0K@^@P=!-(
+M="-(#X5U!0``Q@7GP$$``>L'Q@7GP$$``,8%YL!!``#I604``,8%Y\!!``#&
+M!>;`00`!Z48%```/MX70Q___4.C^V?__@_A&="2#^%5T$\8%Y<!!``#&!>3`
+M00``Z1P%``#&!>3`00`!Z1`%``#&!>7`00`!Z00%``"#?1`$=2%H<#A!`(V%
+MT,?__U#HS]W__X7`=`Q7C8W0Q___Z*CW___&!2C300`!Z=$$``"#?1`!#X6'
+M`0``C870[___4%/_%?0P00"-A=#O__]0Z)VE__\S]E;_-9Q000"-A=#O__]0
+M:&`X00"-A=#G__]34.CVWO__BSU$,4$`ZR%&5O\UG%!!`(V%T.___U!H8#A!
+M`(V%T.?__U-0Z,W>__^#Q!B-A=#G__]0_]>#^/]USHV%T.?__U!J9O]U"/\5
+MU#%!`#/_9CF]T,?__P^$,`0``(`]%M-!```/A2,$```SP&:)A=#[__]J+(V%
+MT,?__U#HG=W__X7`=4<SR68YO=#'__]T/(V%T,?__V:#.$!T#T&-A$W0Q___
+M9CDX=>WK(8TT"8V$-=+'__]0C870^___4.@BW/__,\!FB80UT,?__V8YO=#[
+M__]U)HV%**_^_U"-A=#'__]0Z/S;__^-A2C/_O]0C870^___4.CIV___C870
+MQ___4.@&XO__,\!FB870U___:B2-A=#[__]0C870Q___4/]U"/\5:#)!`(/X
+M!@^$6P,``&H!_W4(Q@45TT$``<8%\L%!``'_%=PQ00`S_X-]$`</A38#```Y
+M/0S"00!U"L<%#,)!``(```#&!0C"00`!Z1@#``"#?1`#=29F.;W0Q___=!"-
+MA=#'__]0_W4(_Q4P,D$`C7T,Z%;O__^C(--!`,8%%]-!``'IX`(``(-]$`4/
+MA?G]__]J`>GG_?__@WT0!@^%Q0(```^WA2BO_O]0Z'W7__^#Z%!T(X/H`W05
+M2'0)QT7X$````.L9QT7X!P```.L0QT7X"P```.L'QT7X`@```#/`9HF%*)?_
+M_V:)A=#G__^-A2C/_O]0C870[___4.B]VO__9H.]T.___R)U0XV%*L_^_U"-
+MA=#O__]0Z*#:__]J(HV%TN___U#HS-O__SO'#X2R````,\EFB0B#P`)0C870
+MY___4.AUVO__Z9@```"-A=#O__]0Z)F'__^$P`^%A````#/;C;70[___9CF=
+MT.___W1S#[<&9H/X('0&9H/X+W53#[?X,\!FB0:-A=#O__]0Z%V'__^$P'0X
+MB]YF@_\O=19J+UAFB870Y___C48"4(V%TN?__^L/1D9F@SX@=/A6C870Y___
+M4.CQV?__9HD[ZP-FB3Y&1F:#/@!UEH7;=`4SP&:)`S/V9CFU*$___W03C84H
+ME___4(V%*$___U#H+J/__XV%*(___U"-A=#O__]0Z!NC____=?B-A=#W__]0
+MZ(??__^-A=#W__]0Z"6B__]F.;4H[_[_=!^-A2CO_O]0C870]___4.C=V?__
+MC870]___4.C]H?__C870]___4(V%T+___U#H4=G__XV%*"___V8YM2@O__]U
+M!HV%*,_^_U#H\:3__U"-A=#W__]0Z);9__^-A=#W__]0Z&JG__\[QG0/:%0X
+M00!0Z$@;``"%P'01:%0X00"-A=#W__]0Z&;9__]J`8V%T/?__U#H"8C__XV%
+M*(___U"-A2B?__]0Z-C8__^-A2B?__]0Z,NG__^-A=#G__]0Z+H1``!0C84H
+ME___4.BM$0``4(V%*`___U#HH!$``%"-A2B?__]0Z),1``!0C870]___4(V%
+M*(___U#H;$\``&8YM="___]T)6H`C870O___4&H%:``0``#_%9@Q00#K#8-]
+M$`=U!\8%$,)!``%H`!```(U%#U"-A=#'__]0_W4,C4W_C94H;___Z)_J__^)
+M10R%P`^%(O7__U]>6\G"#`"0\\U``.W/0`!^T$``G-!``'W20`"^TD``2=-`
+M`'S30``UU4``;=5``'[50`!`V$``!]-``%6+[+CX?0``Z#XY__]3Z+<0```S
+MVU.-C0B"___HW3____]U"(V-"(+__U/H:3[__XU%]%"-1>A0C8T(@O__B5WH
+MB5WLB5WPB5WTB5WXB5W\Z&!!__^$P'0WBT7X5E>--`"+^(U&`E#HC=/__XM-
+M#(D!.\-U!#/_ZQ`SR59FB0P&_W7T4.@ZU/__BT40B3A?7CE=]'0(_W7TZ'73
+M__\Y7>A;=`C_=>CH9]/__XV-"(+__^BW0/__R<(,`%6+[%-7BWT(,]M34VC4
+M.4$`_W44_W40_W4,5^A36/__A,`/A=P```"+10PM$`$``'0>2'4.#[=%$$@/
+MA+L```!(=`<SP.F]````4^FM````H=RX00!6BS70,4$`.\-T"U!J`6B`````
+M5__6H=BX00`[PW004%-H<@$``&IF5_\5Y#%!`%?HA>W__VIE5_\5<#)!`&@`
+M``$`:@"+V&@U!```4__6:@__%0`R00!0:@!H0P0``%/_UFH#_S48TT$`5^@A
+M\___@ST@TT$``%YT+%?_%?PQ00#_-2#300"+#="P00!3_S5T7D$`Z`R9____
+M-2#300#H7]+__^L):@%7_Q7<,4$`,\!`7UM=PA``58OLN%QI``#H=S?__U-6
+MBW4(,]M34VBX.D$`_W44_W40_W4,5N@\5___A,!T"#/`0.FM!P``BT4,+1`!
+M``!7#X0"!0``2'4/#[=%$$AT;TAT/H/H970',\#IA`<``(V%Q/?__U!J9.C.
+MR/__4%;H14W__X3`#X1D!P``C87$]___4&IF5O\5U#%!`.E/!P``B1T`PD$`
+MQ@7RP4$``3D=],%!`'0,.1WXP4$`#X4N!P``4U;_%=PQ00#I(0<``&@`!```
+MC87$]___4&IF5O\5Z#%!`#@=\<%!`'09B1T`PD$`.!WPP4$`=`?&!?+!00`!
+M:@'KOC@=\,%!`'0/,__&!?+!00`!1^G.`P``:FA6_Q5P,D$`B44,.1WXP4$`
+M=2&+/=`Q00!J_U-HL0```%#_UV@T-T$`4VC"````_W4,_]?_=0S_%=@Q00`X
+M'0C"00!T#&BF````Z-_'___K2XV%Q/?__U"-A<#O__]0Z+C4__^-A<#O__]0
+MZ'GL__^-A<#O__]0:*4```#HK<?__U"-A:36__]H@`0``%#HG=;__X/$$(V%
+MI-;__U!3Z+/<__]3C87$]___4(A=#^B'@___BSV$,4$`A,!U$/_7@_@%=`6#
+M^`-U!,9%#P&-A<3W__]0Z.-+``"(11,ZPW4+_]>#^`5U!,9%#P'H1)C__X7`
+M='(X'1'"00!U:CA=$W1^_Q60,$$`4&A\.D$`C87$[___:``$``!0Z!+6__^#
+MQ!"-C:3?___HP7?__S/_1U>-A<3O__]04XV-I-___^@->___B$43.L-U#_\5
+MA#%!`(/X!74$QD4/`8V-I-___^AN>?__ZP,S_T<X71,/A88!```X'1'"00!T
+M"(A=#^L#,_]'.%T/#Y1%#SA=#P^%#`$``&@`!```C87$[___4%/_%:@P00!H
+M$LI!`&@2TD$`C87$]___4&A`.D$`C86,L/__:`P3``!0Z&35__^#Q!AH##I!
+M`&@```(`4V@$```(C87$[___B4744XV%C+#__VK_QT7$/````,=%R$````")
+M=<S'1=``.D$`B478QT7<Y#9!`(E]X(E=Y/\5"#%!`(E%$#O#=#!34U-J`E#_
+M%00Q00")113_%0`Q00`[PW0.:````0!0_W44Z,@,``#_=13_%?PP00"-1<10
+M_Q6<,4$`A<!T(V@0)P``_W7\_Q7X,4$`:/0!``#_%?`P00"+1?RC+--!`.L$
+MQD4/`3E=$'0)_W40_Q5\,4$`.%T/=%1H@@```.B&Q?__4(V%Q/?__U!H\#E!
+M`(V%Q.O__V@`!@``4.AJU/__@\045[E\7D$`Z/%5__]J,&I^Z%'%__]0C87$
+MZ___4%;_%6@R00#_!?C!00!3Z34!``"-A<3W__]0Z,+G__]3:F=6B3WTP4$`
+MZ")3__]3:F96Z!E3__]35U;H\U+__U=J:5;H"%/__V@T-T$`:F56_Q74,4$`
+M:F56_Q5P,D$`B44,.\-T&FKP4/\50#)!``V`````4&KP_W4,_Q4\,D$`:@7_
+M-1C300!6Z%KN__]J`O\U&--!`%;H3.[__VC@N$$`Z(3@__]J!O\U&--!`%;H
+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
+M&(D"C82YN````(L0B1:),(M5](U%\(OR.]`/A7#___]?7EO)PU:+\8"^J@``
+M``!7BWPD#'4?QH:J````_^B#_O__C8R^N````(L!A<!T!HL0B1'K,HO/C82^
+MN````$&#P`2#^29T)8,X`'3R4XV$CK@```"+&(L35U%3B\Z)$.@7]O__B\-;
+M7U["!`#^CJH````/MD0W!&O`#(V67`$``(L*B_DKOE`!```[^'X0*\B)"HV.
+M5`$``"D!BP'KR3/`Z\6+1"0$5@^V=`@IC92QN````(L"A<!T!HL(B0KK-`^V
+M5`X$BX&P````:](,`]")D;`````[D;0```!V%@^V1`X$:\`,*]!6B9&P````
+MZ!+___]>P@0`C9&T````BP([@;````!T!H/`](D"PXV1N````(,Z`'0'BP*+
+M"(D*PVH`Z-_^___#58OL4U:+=0Q7B_D/MEP^*0^V1#XJ.]AU!8M%".LNC48!
+M4.A4____B44,A<!T&VOV#%:+=0A64.@TK?__C82?N````(L(B0Z),(M%#%]>
+M6UW""`!3B]F+3"0(@<&,2@``Z&O___^%P'0>5HMT)!17,\E!9HD(BTPD%(UX
+M`J5FI5^)6`B)00)>6\(,`(O!,\F)B(Q*``")B$0&``")B$P&``")B$@&``##
+M58OL@^P44U97OP`!``!7B_%J`(V&;`8``%#H?*S__XV>C$H``(O+Z$_U__^+
+MAF`&``"#^`Q\`VH,6(/)_RO(B8YH!@``B\OHW/[__XF&3`8``(F&1`8``(-@
+M"`"+AF`&``")AEP&``"+AD0&``!FB3B+AD0&``"Y`0$``&:)2`*_@````%>+
+MR^A&_O__BXY$!@``B4$$BX9$!@``BT`$B890!@``BX9H!@``,\F)AF0&``"(
+MCFT*```SP(N61`8``(M2!(@,$(N61`8``(M2!,9$`@$!BY9$!@``BU($@V0"
+M`@"#P`9!/0`&``!\S8-E_`"-AG`*``")1?"+7?R+1?"#PP*Y)#M!`(E%](M%
+M](E%^,=%[`@````/MP&9]_NZ`$```"O0BT7X@T7X$/]-[&:)$'7D@T7T`D%!
+M@?DT.T$`?,G_1?P!??`Y??Q\K3/2C4X#C4(":A!KP"A>QD'_`V:)0?W&`02#
+MP01.=>]"@_H9?.!?7EO)PXM$)`135HOQ,]M#5XB>;`H``(F&8`8``.AK_O__
+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
+M&V:#.0%T&XM!!#O"=@X[QW<*5NBY^___A,!U#(/(_U]>PU;HFNK__XN.?$H`
+M`(V&>$H``(L0B_H/K_D!OG!*``"+OH!*```K^0^O^HDX@[Y0!@```'0W@[Y<
+M!@```(N&4`8``%,/MA@/A;T```"+0`([AMQ+```/AJX```")ADP&``")AD0&
+M``#IM````(N&<$H``(N.>$H``(T4"#/0@?H````!<A6!^0"```!S-_?8)?]_
+M``")AGA*``"+CHA*``"-OG1*``#H,>___XL/P:9X2@``",'A"`O!P:9P2@``
+M"(D'ZZB+AMQ+``"+CD0&``#_AEP&``"+20B)CD0&```[R`^&$____SN.Y$L`
+M``^'!____P^W$3N65`8``'3,5NBU_/__Z>W^__^+SNAY]___@+YL"@```'4'
+MB\[HK^K__XN&<$H``(N.>$H``(T4"#/0@?H````!<A6!^0"```!S-_?8)?]_
+M``")AGA*``"+CHA*``"-OG1*``#H?>[__XL/P:9X2@``",'A"`O!P:9P2@``
+M"(D'ZZB+PUOI??[__U-65XOQZ%M8__^+5"00BYJ$````)?[_```[1)H$<RAJ
+M$%DKR]/H#[:,$(@````#3@2+^<'O`P$^@^$'B4X$BX2"B`0``.M,:@]?C4L!
+M.\]S%8U<B@0[`W(+08/#!(/Y#W+SZP*+^8M.!`//B]F#X0>)3@3!ZP,!'BL$
+MNFH062O/T^@#1+I$.P)R`C/`BX2"B!0``%]>6\($`%-6B_%7C7X0B\_HF?W_
+M_XO8@_O_=0Z+S^C"_/__@Z8PS````%]>B\-;PU:+\8U.(.B![?__C4X4Z'GM
+M__^+SE[I<>W__U97BWPD#(-_&`"+\79/BX90S```4XE'1(M'%/^V4,P``(/`
+M)(V>`$P``%"+R^A%=?__BX90S```BY94S```L2#H:@#__U"+1Q2#P"A0B\OH
+M(W7__U>+R^@*AO__6U]>P@0`BT0D!%97BWPD$(OQ._AT.\:&2LP```%S,HO(
+M]]F!X?__/P!1BXXTS````\A1B\[HK.K__U?_MC3,``"+SNB>ZO__QH9)S```
+M`>L3BXXTS```*_@#R%=1B\[H@NK__U]>P@@`58OL@>RL`0``5HOQBX:4R@``
+M@^@9.09^#>CEZ?__A,`/A&`"``"+1@3WV(/@!U"+SNBZ5O__B\[HRE;__ZD`
+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
+M1?A0QT7X"````,=%_/\'``#_%2PP00!H*$]"`/\5K#%!`%^+QE[)PU:+\8L&
+M5XL]/#%!`(7`=`-0_]>+=@2%]G0#5O_7H2A/0@"+"%#_40A?7L.Y?%Y!`.ED
+M"___N8A>00#HV7+__VB$*4$`Z+2*__]9P[DXTT$`Z#8$__]HCBE!`.B>BO__
+M6<.Y^$Q"`.D4R___N8A>00#IL'+__[DXTT$`Z38#__\`````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`$!*`0"F20$`ODD!`"Q*`0`:2@$`"$H!`/I)`0#F20$`TDD!`(Y)`0``````
+MU#\!`!$``(``````;$D!`$!)`0!820$``````!9)`0#R2`$`V$@!`,A(`0"Z
+M2`$``$D!`"9)`0"N2`$``````%A!`0!F00$`=$$!`(A!`0"<00$`J$$!`+A!
+M`0#*00$`VD$!`.Q!`0#\00$`$D(!`"!"`0`P0@$`1$(!`%A"`0!N0@$`?D(!
+M`))"`0">0@$`L$(!`+Q"`0#*0@$`W$(!`.I"`0#\0@$`0D$!`"A#`0`Z0P$`
+M3$,!`&1#`0!^0P$`FD,!`+!#`0"X0P$`R$,!`-9#`0#H0P$`^D,!``I$`0`@
+M1`$`-$0!`$Y$`0!@1`$`>D0!`))$`0"B1`$`N$0!`,I$`0#<1`$`Z$0!``!%
+M`0`010$`+$$!`!9!`0``00$`]$`!`.1``0#80`$`&$`!`,I``0"\0`$`KD`!
+M`)Y``0",0`$`@$`!`')``0!>0`$`4$`!`$!``0`P0`$`$$,!```````(``"`
+M`````/!*`0#>2@$`RDH!`+A*`0":2@$`C$H!`'9*`0!>2@$``````/H_`0``
+M````3D<!`%Q'`0!H1P$`<$<!`(!'`0"21P$`GD<!`*I'`0"X1P$`SD<!`.!'
+M`0#P1P$``D@!`!1(`0`H2`$`/D@!`$Q(`0!<2`$`:D@!`'9(`0"$2`$`DD@!
+M`$!'`0"F1@$`E$8!`()&`0!R1@$`8$8!`%)&`0`^1@$`+$8!`!I&`0`(1@$`
+M^$4!`.I%`0#610$`PD4!`+)%`0"B10$`BD4!`'A%`0!J10$`7$4!`$Y%`0`^
+M10$`+$4!`#)'`0`@1P$`$D<!``)'`0#P1@$`W$8!`-!&`0#"1@$`LD8!`)9%
+M`0``````1DL!`%Y+`0`.2P$`-$L!`")+`0````````````T=X4T``````@``
+M`%$```#$2P$`Q#D!`$--5`!.&D``+2`_/S\```!24@``/P`_`#\````J````
+M*@```#X````E`',``````%,`90!2`&4`<P!T`&\`<@!E`%``<@!I`'8`:0!L
+M`&4`9P!E``````!3`&4`4P!E`&,`=0!R`&D`=`!Y`%``<@!I`'8`:0!L`&4`
+M9P!E````+@!<``````!35$T`04-,`$%6``!R87(`)0`N`"H`<P`H`"4`9``I
+M`"4`<P``````)2XJ<R@E9"DE<P``<@!T`&T`<``E`&0``````%E.04Y20P``
+MU%I``"XN```N````8F%D(&%L;&]C871I;VX``'IQ0`#.;4``F'%``#IH0`!6
+M:$``1VA``%YH0`"L<4``Q&U``(YQ0`"P;4``IFU``#IH0``Z:$``.FA``#)H
+M0``R:$``5FA``#IH0`!H9T``.FA``$)H0`"B<4``NFU``(1Q0`!M9T``.FA`
+M`*MG0`"K9T``JV=``+!G0``R:$``.FA``*MG0``J:$``*FA``&AG0`#8;4``
+M4V=``(-N0``J:$``5FA``&!G0`"K9T``:&=``"IH0``F`&X`8@!S`'``.P``
+M````/`!B`'(`/@``````#0`*``T`"@```````````#P`<P!T`'D`;`!E`#X`
+M8@!O`&0`>0![`&8`;P!N`'0`+0!F`&$`;0!I`&P`>0`Z`"(`00!R`&D`80!L
+M`"(`.P!F`&\`;@!T`"T`<P!I`'H`90`Z`#$`,@`[`'T`/``O`',`=`!Y`&P`
+M90`^```````\`"\`:`!T`&T`;``^````=0!T`&8`+0`X`"(`/@`\`"\`:`!E
+M`&$`9``^```````\`&@`90!A`&0`/@`\`&T`90!T`&$`(`!H`'0`=`!P`"T`
+M90!Q`'4`:0!V`#T`(@!C`&\`;@!T`&4`;@!T`"T`=`!Y`'``90`B`"``8P!O
+M`&X`=`!E`&X`=``]`"(`=`!E`'@`=``O`&@`=`!M`&P`.P`@`&,`:`!A`'(`
+M<P!E`'0`/0``````/`!H`'0`;0!L`#X``````&$`8@!O`'4`=``Z`&(`;`!A
+M`&X`:P```#P`+P!S`'0`>0!L`&4`/@``````/`!S`'0`>0!L`&4`/@```#P`
+M+P!P`#X``````%,`:`!E`&P`;``N`$4`>`!P`&P`;P!R`&4`<@``````4@!A
+M`'(`2`!T`&T`;`!#`&P`80!S`',`3@!A`&T`90``````*C\``%]?<F%R7P``
+M*@`_``````!<````)0!C`#H`7```````,``P``````!R`&$`<@```',`9@!X
+M````90!X`&4````N`'(`80!R```````P,```<V9X`&5X90`N<F%R`````#\J
+M/#Y\(@``/RH``"X```!R(1H'`````"H`;0!E`',`<P!A`&<`90!S`"H`*@`J
+M```````J;65S<V%G97,J*BH`````)0`P`#@`>```````<P```"0```!`````
+M`````$P`5`!2````4@!4`$P```!2`&$`<@!3`$8`6```````#0`*```````E
+M`',`(``E`',````E`',`(``E`',`(``E`',``````%(`10!0`$P`00!#`$4`
+M1@!)`$P`10!$`$P`1P``````4@!%`$X`00!-`$4`1`!,`$<```!'`$4`5`!0
+M`$$`4P!3`%<`3P!2`$0`,0``````6````$$`4P!+`$X`10!8`%0`5@!/`$P`
+M`````"X`+@``````4P!O`&8`=`!W`&$`<@!E`%P`5P!I`&X`4@!!`%(`(`!3
+M`$8`6````%,`5`!!`%0`20!#```````N`&4`>`!E``````!)`&X`<P!T`&$`
+M;`!L````+@!I`&X`9@``````+@!L`&X`:P``````)0!S`"4`<P`E`&0`````
+M`#P`/@``````4`!R`&\`9P!R`&$`;0!&`&D`;`!E`',`1`!I`'(```!3`&\`
+M9@!T`'<`80!R`&4`7`!-`&D`8P!R`&\`<P!O`&8`=`!<`%<`:0!N`&0`;P!W
+M`',`7`!#`'4`<@!R`&4`;@!T`%8`90!R`',`:0!O`&X````E`',`+@`E`&0`
+M+@!T`&T`<````$0`90!L`&4`=`!E``````!4`&4`>`!T``````!4`&D`=`!L
+M`&4```!0`&$`=`!H``````!3`&D`;`!E`&X`=```````3P!V`&4`<@!W`'(`
+M:0!T`&4```!3`&4`=`!U`'````!4`&4`;0!P`$T`;P!D`&4``````$P`:0!C
+M`&4`;@!S`&4```!0`'(`90!S`&4`=`!U`'```````%,`:`!O`'(`=`!C`'4`
+M=```````4P!A`'8`90!0`&$`=`!H``````!5`'``9`!A`'0`90``````3`!)
+M`$,`10!.`%,`10!$`$P`1P``````(````"(`)0!S`"(`"@`E`',```!R`'4`
+M;@!A`',```!W`&D`;@!R`&$`<@!S`&8`>`!M`&$`<`!P`&D`;@!G`&8`:0!L
+M`&4`+@!T`&T`<```````+0!E`&P`(``M`',`,@`@`"(`+0!D`"4`<P`B`"``
+M(@`M`'``)0!S`"(`(``B`"T`<P!P`"4`<P`B````7P!?`'0`;0!P`%\`<@!A
+M`'(`7P!S`&8`>`!?`&$`8P!C`&4`<P!S`%\`8P!H`&4`8P!K`%\`)0!U````
+M4P!4`$$`4@!4`$0`3`!'``````!S`&8`>`!N`&$`;0!E````<P!F`'@`8P!M
+M`&0``````%-E=$1L;$1I<F5C=&]R>5<`````:P!E`'(`;@!E`&P`,P`R````
+M```9#@D'!04$!`0#`P,"`@("W3P_'[]9\TBA9+Q:,F918$4`1`!)`%0`````
+M`'(`:0!C`&@`90!D`#(`,``N`&0`;`!L``````!R`&D`8P!H`&4`9``S`#(`
+M+@!D`&P`;```````^10"``````#`````````1H`CU7\'3AL0KBT(`"LNQQ,8
+M`0```````,````````!&$@$```````#`````````1A8!````````P```````
+M`$83`0```````,````````!&&0$```````#`````````1@``````````P```
+M`````$8`!`(``````,````````!&818,TZ_-T!&*/@#`3\GB;@L!````````
+MP````````$8!%`(``````,````````!&0#T!````````````[#\!`"PP`0#0
+M/@$````````````,0`$`O#$!`(`]`0```````````!Y%`0!L,`$`V#X!````
+M````````HD@!`,0Q`0!</0$````````````V20$`2#`!`$P]`0``````````
+M`(!)`0`X,`$`%#T!````````````4$H!```P`0"L/@$````````````"2P$`
+MF#$!`+P_`0```````````&Y+`0"H,@$`I#X!````````````>$L!`)`Q`0``
+M`````````````````````````$!*`0"F20$`ODD!`"Q*`0`:2@$`"$H!`/I)
+M`0#F20$`TDD!`(Y)`0``````U#\!`!$``(``````;$D!`$!)`0!820$`````
+M`!9)`0#R2`$`V$@!`,A(`0"Z2`$``$D!`"9)`0"N2`$``````%A!`0!F00$`
+M=$$!`(A!`0"<00$`J$$!`+A!`0#*00$`VD$!`.Q!`0#\00$`$D(!`"!"`0`P
+M0@$`1$(!`%A"`0!N0@$`?D(!`))"`0">0@$`L$(!`+Q"`0#*0@$`W$(!`.I"
+M`0#\0@$`0D$!`"A#`0`Z0P$`3$,!`&1#`0!^0P$`FD,!`+!#`0"X0P$`R$,!
+M`-9#`0#H0P$`^D,!``I$`0`@1`$`-$0!`$Y$`0!@1`$`>D0!`))$`0"B1`$`
+MN$0!`,I$`0#<1`$`Z$0!``!%`0`010$`+$$!`!9!`0``00$`]$`!`.1``0#8
+M0`$`&$`!`,I``0"\0`$`KD`!`)Y``0",0`$`@$`!`')``0!>0`$`4$`!`$!`
+M`0`P0`$`$$,!```````(``"``````/!*`0#>2@$`RDH!`+A*`0":2@$`C$H!
+M`'9*`0!>2@$``````/H_`0``````3D<!`%Q'`0!H1P$`<$<!`(!'`0"21P$`
+MGD<!`*I'`0"X1P$`SD<!`.!'`0#P1P$``D@!`!1(`0`H2`$`/D@!`$Q(`0!<
+M2`$`:D@!`'9(`0"$2`$`DD@!`$!'`0"F1@$`E$8!`()&`0!R1@$`8$8!`%)&
+M`0`^1@$`+$8!`!I&`0`(1@$`^$4!`.I%`0#610$`PD4!`+)%`0"B10$`BD4!
+M`'A%`0!J10$`7$4!`$Y%`0`^10$`+$4!`#)'`0`@1P$`$D<!``)'`0#P1@$`
+MW$8!`-!&`0#"1@$`LD8!`)9%`0``````1DL!`%Y+`0`.2P$`-$L!`")+`0``
+M````>P!);FET0V]M;6]N0V]N=')O;'-%>```0T]-0U1,,S(N9&QL``"D`%-(
+M075T;T-O;7!L971E``!32$Q705!)+F1L;`"_`4=E=$-U<G)E;G1$:7)E8W1O
+M<GE7```"`D=E=$QA<W1%<G)O<@``<P13971,87-T17)R;W(``%(`0VQO<V5(
+M86YD;&4`P`%'971#=7)R96YT4')O8V5S<P!J!%-E=$9I;&54:6UE`&,#36]V
+M949I;&57`&8$4V5T1FEL95!O:6YT97(``%,$4V5T16YD3V9&:6QE``#S`4=E
+M=$9I;&54>7!E`(@`0W)E871E1FEL94$`CP!#<F5A=&5&:6QE5P#``U)E861&
+M:6QE``!D`D=E=%-T9$AA;F1L90``)057<FET949I;&4`Y0%'971&:6QE071T
+M<FEB=71E<T$``.H!1V5T1FEL94%T=')I8G5T97-7``!>!%-E=$9I;&5!='1R
+M:6)U=&5S00``8013971&:6QE071T<FEB=71E<U<``-8`1&5L971E1FEL95<`
+MTP!$96QE=&5&:6QE00!\`$-R96%T941I<F5C=&]R>4$``($`0W)E871E1&ER
+M96-T;W)Y5P``+@%&:6YD0VQO<V4`0P%&:6YD3F5X=$9I;&5!`#(!1FEN9$9I
+M<G-T1FEL94$``$4!1FEN9$YE>'1&:6QE5P`Y`49I;F1&:7)S=$9I;&57``"3
+M`D=E=%1I8VM#;W5N=```$057:61E0VAA<E1O375L=&E">71E`+,"1VQO8F%L
+M06QL;V,`I`)'971697)S:6]N17A7`/@!1V5T1G5L;%!A=&A.86UE00``^P%'
+M971&=6QL4&%T:$YA;657```4`D=E=$UO9'5L949I;&5.86UE5P``3@%&:6YD
+M4F5S;W5R8V57`!@"1V5T36]D=6QE2&%N9&QE5P``RP)(96%P06QL;V,`2@)'
+M9710<F]C97-S2&5A<```SP)(96%P1G)E90``T@)(96%P4F5!;&QO8P!A`$-O
+M;7!A<F53=')I;F=!```9`45X:710<F]C97-S``8"1V5T3&]C86QE26YF;U<`
+M`#,"1V5T3G5M8F5R1F]R;6%T5P``Y`!$;W-$871E5&EM951O1FEL951I;64`
+MR`%'971$871E1F]R;6%T5P``EP)'9714:6UE1F]R;6%T5P``)0%&:6QE5&EM
+M951O4WES=&5M5&EM90``)`%&:6QE5&EM951O3&]C86Q&:6QE5&EM90`=`45X
+M<&%N9$5N=FER;VYM96YT4W1R:6YG<U<`^01786ET1F]R4VEN9VQE3V)J96-T
+M`+($4VQE97``A0)'971496UP4&%T:%<``&`#36]V949I;&5%>%<`U@15;FUA
+M<%9I97=/9D9I;&4`AP%'971#;VUM86YD3&EN95<`5P--87!6:65W3V9&:6QE
+M`(P`0W)E871E1FEL94UA<'!I;F=7``!Y`T]P96Y&:6QE36%P<&EN9U<``%<$
+M4V5T16YV:7)O;FUE;G1687)I86)L95<`10)'9710<F]C061D<F5S<P``1@-,
+M;V-A;$9I;&54:6UE5&]&:6QE5&EM90"]!%-Y<W1E;51I;654;T9I;&54:6UE
+M``!W`D=E=%-Y<W1E;51I;64`9P--=6QT:4)Y=&54;U=I9&5#:&%R`&0`0V]M
+M<&%R95-T<FEN9U<``/X"27-$0D-33&5A9$)Y=&4``'(!1V5T0U!);F9O`$T$
+M4V5T0W5R<F5N=$1I<F5C=&]R>5<``#\#3&]A9$QI8G)A<GE7``!B`49R965,
+M:6)R87)Y`$M%4DY%3#,R+F1L;```(@)/96U4;T-H87)"=69F00``V`!%;F%B
+M;&57:6YD;W<``"<!1V5T1&QG271E;0``WP)3:&]W5VEN9&]W```5`DUE<W-A
+M9V5";WA7`#<`0VAA<E1O3V5M0G5F9E<``-L!27-7:6YD;W<``%4`0V]P>5)E
+M8W0``!0!1V5T0VQI96YT4F5C=`"F`$1E<W1R;WE7:6YD;W<`KP!$:7-P871C
+M:$UE<W-A9V57``#\`E1R86YS;&%T94UE<W-A9V4``%T!1V5T365S<V%G95<`
+M,P)0965K365S<V%G95<``)P`1&5F5VEN9&]W4')O8U<``)8!1V5T5VEN9&]W
+M3&]N9U<``,0"4V5T5VEN9&]W3&]N9U<``$T"4F5G:7-T97)#;&%S<T5X5P``
+MZP%,;V%D0W5R<V]R5P#+`E-E=%=I;F1O=U1E>'17```1`U5P9&%T95=I;F1O
+M=P``;@!#<F5A=&57:6YD;W=%>%<`"0)-87!7:6YD;W=0;VEN=',`9`%'9710
+M87)E;G0`G`%'9717:6YD;W=296-T`#P`0VAA<E5P<&5R5P``C@%'9717:6YD
+M;W<`?@%'9713>7-T96U-971R:6-S``"C`4=E=%=I;F1O=U1E>'17``#&`E-E
+M=%=I;F1O=U!O<P``^@%,;V%D4W1R:6YG5P`V`$-H87)4;T]E;4)U9F9!```Y
+M`$-H87)5<'!E<D$``#0#=W9S<')I;G1F00``-0-W=G-P<FEN=&97``!E`E)E
+M;&5A<V5$0P`A`4=E=$1#`'P"4V5N9$UE<W-A9V57``"0`E-E=$1L9TET96U4
+M97AT5P"2`E-E=$9O8W5S``#:`$5N9$1I86QO9P"C`$1E<W1R;WE)8V]N`',"
+M4V5N9$1L9TET96U-97-S86=E5P`J`4=E=$1L9TET96U497AT5P`2`4=E=$-L
+M87-S3F%M95<`K`!$:6%L;V=";WA087)A;5<`X`%)<U=I;F1O=U9I<VEB;&4`
+M)@-786ET1F]R26YP=71)9&QE``"3`E-E=$9O<F5G<F]U;F17:6YD;W<`>P%'
+M9713>7-#;VQO<@`V`E!O<W1-97-S86=E5P``YP%,;V%D0FET;6%P5P#M`4QO
+M861)8V]N5P`U`$-H87)4;T]E;4$``"$"3V5M5&]#:&%R00``^0!&:6YD5VEN
+M9&]W17A7`%5315(S,BYD;&P``.,`1&5L971E1$,``+,"4W1R971C:$)L=```
+M=P)396QE8W1/8FIE8W0``"\`0W)E871E0V]M<&%T:6)L94)I=&UA<```_0%'
+M971/8FIE8W17```P`$-R96%T94-O;7!A=&EB;&5$0P``RP%'971$979I8V5#
+M87!S`.8`1&5L971E3V)J96-T``!'1$DS,BYD;&P`!`!#;VUM1&QG17AT96YD
+M961%<G)O<@``#@!'9713879E1FEL94YA;657```,`$=E=$]P96Y&:6QE3F%M
+M95<``$-/341,1S,R+F1L;```'P!!9&IU<W14;VME;E!R:79I;&5G97,`EP%,
+M;V]K=7!0<FEV:6QE9V5686QU95<`]P%/<&5N4')O8V5S<U1O:V5N``"I`E-E
+M=$9I;&5396-U<FET>4$``*H"4V5T1FEL95-E8W5R:71Y5P``,`)296=#;&]S
+M94ME>0!^`E)E9U-E=%9A;'5E17A7```Y`E)E9T-R96%T94ME>45X5P!N`E)E
+M9U%U97)Y5F%L=65%>%<``&$"4F5G3W!E;DME>45X5P!!1%9!4$DS,BYD;&P`
+M`-<`4TA'9710871H1G)O;4E$3&ES=%<``'L`4TA"<F]W<V5&;W)&;VQD97)7
+M``#/`%-(1V5T36%L;&]C`-\`4TA'9713<&5C:6%L1F]L9&5R3&]C871I;VX`
+M`+T`4TA'971&:6QE26YF;U<``*P`4TA&:6QE3W!E<F%T:6]N5P``(0%3:&5L
+M;$5X96-U=&5%>%<`?P!32$-H86YG94YO=&EF>0``4TA%3$PS,BYD;&P`$`!#
+M;T-R96%T94EN<W1A;F-E```(`$-,4TE$1G)O;5-T<FEN9P!)`4]L955N:6YI
+M=&EA;&EZ90"&`$-R96%T95-T<F5A;4]N2$=L;V)A;``R`4]L94EN:71I86QI
+M>F4`;VQE,S(N9&QL`$],14%55#,R+F1L;``````````````````````-'>%-
+M`````+A+`0`!``````````````````````````````!724Y205(N4T98``!2
+M4T13Y=F'&1/$=TB(PEFYXP9LD0$```!D.EQ0<F]J96-T<UQ7:6Y205)<4T98
+M7&)U:6QD7'-F>')A<C,R7%)E;&5A<V5<<V9X<F%R+G!D8@``````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````````````*@S00"\,T$`_____[PS
+M00`&1D9&*2E%10E&1D9&*2DI*2DI`0$1$`5&1D9%```@0`("!@8&9F8`-0``
+M`(=H5ZT!````.0```'[EUSP"````>````#^):3<#````'0```'T'!@X&````
+ME0```,A=+!P$````V`````'GA;P%````*````&#%N48'````!`0&!@``!P<$
+M!```!`0``$@W00````````````,```#D-D$`````````````.4$`$#E!`!PY
+M00`H.4$`-#E!`$0Y00!8.4$`9#E!`'@Y00"(.4$`G#E!`+`Y00#$.4$`'P``
+M`!P````?````'@```!\````>````'P```!\````>````'P```!X````?````
+M`@(#!`4&!@8`!`@0($"`P````````````0$!`0("`@(#`P,#!`0$!`4%!04`
+M`0(#!`4&!P@*#`X0%!@<("@P.$!08'"`H,#@``````0````"`````@````(`
+M```"`````@````(````"`````@````(````"`````@````(````"`````@``
+M``(````.``````````P`````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````1"E!`$XI00!D*4$`>BE!````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M``````````````````````````````````````````````8``@```$```(`#
+M````6```@`4```"(``"`!@```,@``(`.``````$`@!@````8`0"`````````
+M```````````!`&4````P`0"````````````````````$``$```!(`0"``@``
+M`&`!`(`#````>`$`@`0```"0`0"`````````````````!@```'0$`("H`0"`
+M1`0`@,`!`(!>!`"`V`$`@#`$`(#P`0"`$@0`@`@"`(``!`"`(`(`@```````
+M````````````!0`'````.`(`@`@```!0`@"`"0```&@"`(`*````@`(`@`L`
+M``"8`@"````````````````````!`&0```"P`@"````````````````````!
+M``$```#(`@"````````````````````!``D$``#@`@``````````````````
+M```!``D$``#P`@`````````````````````!``D$`````P``````````````
+M```````!``D$```0`P`````````````````````!``D$```@`P``````````
+M```````````!``D$```P`P`````````````````````!``D$``!``P``````
+M```````````````!``D$``!0`P`````````````````````!``D$``!@`P``
+M```````````````````!``D$``!P`P`````````````````````!``D$``"`
+M`P`````````````````````!``D$``"0`P`````````````````````!``D$
+M``"@`P`````````````````````!``D$``"P`P`````````````````````!
+M``D$``#``P`````````````````````!``D$``#0`P``````````````````
+M```!``D$``#@`P`````````````````````!``D$``#P`P``\'8"`+8+````
+M`````````)!D`@`H`0````````````"X90(`:`4`````````````(&L"`.@"
+M``````````````AN`@"H"`````````````"8BP(`A@(`````````````:(D"
+M`#H!`````````````*B*`@#L```````````````XB`(`+@$`````````````
+M`(4"`#@#`````````````*B"`@!2`@````````````#8DP(`+`(`````````
+M````")8"`,X#`````````````-B9`@`2`@````````````#PFP(`"`,`````
+M````````^)X"`'P!`````````````+!V`@`^```````````````@C@(`N`4`
+M````````````"`!3`%0`00!2`%0`1`!,`$<`#@!2`$4`4`!,`$$`0P!%`$8`
+M20!,`$4`1`!,`$<`"0!2`$4`3@!!`$T`10!$`$P`1P`,`$<`10!4`%``00!3
+M`%,`5P!/`%(`1``Q``H`3`!)`$,`10!.`%,`10!$`$P`1P`*`$$`4P!+`$X`
+M10!8`%0`5@!/`$P`````````*````!`````@`````0`$``````#`````````
+M```````0`````````````````(```(````"`@`"`````@`"``("```#`P,``
+M@("`````_P``_P```/__`/\```#_`/\`__\``/___P```````$`````'`P`'
+MAP```']'8@]_)B`']RNJ3_^JH']P```/_P``!P<##____P!P?\=`___\0`?W
+M3V8/_\9@?W````3T```'!P,``(```'!_!Q45%140!_=;W=W=W=!_<!45%145
+M$`<!-S$!`0$`<!-S$!`0$``!`0$!`0$``.`!___``/__@`#__P``__\``?__
+M@`#__P``__\``/__``'__X``__\``/__``#__P``__^``?__``/__P`'__\H
+M````$````"`````!``@``````$`!```````````````!````````(0]4`!L4
+M70`9%&,``!U8``````"FHZ(`&!)4`"`:;P``EI8``-'1``"1D0`L%'0`)Q!K
+M`,S'Q0!+`GH`1@5_`$\#A`!0`H$`.0IW`+&NK0#_^_@`U<_+`&(*F@!H$*``
+M7PB5`%,"A@`F)B8`TL_.`/_]_`#___\`\+[_`.6C_P#>E?\`UX?_`-)]_P#0
+M>?\`RFS_`,!C]`"U6N@`X-O9`![%Q0!:`I(`4P*-````4```@(``%A%-`!(.
+M/P`K*RL`(D-3`'3-]P"U8P8`_\MY`"1'6`!>N.0`I^'U`/^=)0#_KS$`4#(`
+M`*=8``!<M^,`H=ON`-WY_0">W?0`EF(``)]6``"(30``>L[U`-3X_0!4ILX`
+M4!D``&6[Y`"!RNT`4X,!`.'UNP"/RAX``$,5`%FKTP!ANN8`D=<(`)O?%@"2
+MW````#81`$AP````N;D`>;$/`%J*``!2G<(`K.'U`%>GS@!8B```5X<``$)G
+M````3AD`.82E`%JUW@!"A*4`0$!```Q*+@`A4FL`.7N<`"%*8P``````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M``````````````````````````````````````0$!&`$!`0$86)C9`0$!`0$
+M!"\G6RQ<7#!=7E]<7%Q1!"\G'5)35%4P5E=865I(!!H;'`U('4E*2TP]34Y/
+M4%$3%!4O!`0$!`1&'4<$!`0$!`T$)T$L-#M"0QT^/D1%.04$)QTZ*"PT.SP]
+M/CL_0`0:&QP-,ATS+#0U-C4W.#<Y$Q05+P0$!`0$,#$P!`0$!`0-!"<!+"LK
+M+2X$+BTK*RL%!"<=!R@I*2DJ$"HI*2HK&AL<#1D='A\@(2(C)"4F`1,4%086
+M%Q87%A<6%Q88&0($#08."@D(#Q`.$`X1$@8$!08'"`D*!PL,"PP+#`8$!``!
+M`@("`@("`@("`0,$!`3@`?__P`#__X``__\``/__``'__X``__\``/__``#_
+M_P`!__^``/__``#__P``__\``/__@`'__P`#__\`!___*````"````!`````
+M`0`$``````"``@`````````````0`````````````````(```(````"`@`"`
+M````@`"``("```#`P,``@("`````_P``_P```/__`/\```#_`/\`__\``/__
+M_P````````````````````````"#@X,P`#.#@X,`````````>WM[<`![>WM[
+M,````````+>WM[``M[>WNW,```````![>WMP`'M[>WNW,```````M[>WL`"W
+MM[>[>W,``````'M[=W``=WM[>[>W,`````"WMP`````'M[M[>W@`````>WMP
+M````>WM[M[>W`````+>WMP``![>WNWM[>P````![>WMP`'M[>WNWM[<`````
+MM[>WMP>WM[>[>WM[`````'M[>WM[>WM[>[>WMP````!W=W=W=W=W=[MW>WL`
+M`#@X.#@X.#@X.#A[>#>W```#@X.#@X.#@X.#AX.#>P```#@X.#@X.#@X.#@X
+M.#<````#@X.#@X.#@X.#@X.#````"")G)$3,`571$3@X.#```(,B:B1,3`%5
+MU5$#@X.#``@X(FHD1,P!5=45$#@X.#"#@R)J)$S,`575$5$#@X.#"#@GNRQ[
+MN`>[=3@5$#@X,`"#(F)T1,<!574[@5$#@P``""(FI$S.`56S4[,1!3`````G
+M_W1_]U?_=54[@8.``````G_W1_]U?_=54W$X.``````G_W1_]U?_=56%@X.`
+M`````G_W1_]U?_=553@X.``````G_W1_]U?_=54``````````G_W1_]U?_=5
+M```````````G`'1P!U<`=0```/```__P``'_\```__```'_P```_\```'_``
+M``_P```/\```#_````_P```/\```#_````_P```/````#X````_````/X```
+M#^````?````#@````0````"````!P````^````?P```'^````_P```'^````
+M_P``/_^``#__S&,_*````"````!``````0`(``````"`!```````````````
+M`0`````````````U)`<`-B,)`$<]!0!.,PT`<"````!&#@``3`\``%\```!:
+M!0``5P@`)5\&``]P$``/>Q\`/6P``$!P`````'\`8P!C`'``<`!_`'\``$M+
+M``!.7```46```%=H``!;:0``6VP``%]M``!5<```7W```%QX``!C<0``97$`
+M`&-T``!E=0``9W8``&=W``!I=@``8'\``&)_``!K>P``;7L`*V]W`)L```"A
+M````_P```,)0``#/7@``_U,L`.=]+0"03T\`_W!``!"`(``5@R4`7Y```%N6
+M"P!NJ24`,:-#`$#`7P!;SG,`3]YV`&K_:@#UD30`_YLX`/^P0`#_N58``&2"
+M``!I@@``:H(``&^```!L@@``;H<``'&```!WA@``>H<``'.*``!TBP``<XT`
+M`'J(``![B```?8P``'Z-``!XD```>I(``'^0``Q]F0!&>H4`D`"0`)8+F`"6
+M#9@`FQ6?`)P9GP"@$*``KR"O`+!*O@"W5,8`OU_0`,=RU@``@)```("8``"`
+MGP``E98``(^@``";I```H+```*>S``"ML@``J;<``*R[``"TN@``L+\``+;#
+M``"[P```NL<``+W$``#"R@``R<\``,W.``#*TP``S]``'L_5``#0T```UM<`
+M`-C8``#<W0``W=X`(L;0``#?X```WN(`'N+E``#P\```]_<`8-#?`&/?Y@!:
+M\_8`SH/;`-_/SP#___\`````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M``````````````````````````````````````````````````````#^_O[^
+M%!04%!04%!04%!04%!04%!04_O[^_O[^_O[^_O[^_OYD9&1D9&1D!@8&9&1D
+M9&1D9&04_O[^_O[^_O[^_O[^_G)R<G)R<G(!`P)R<G)R<G)R?V04_O[^_O[^
+M_O[^_O[^<G)R<G)R<@`$`'YV<G)R<G*%=F04_O[^_O[^_O[^_OYR<G)R<G)R
+M````?G9R<G)R<X5^=F04_O[^_O[^_O[^_G)R<G)R<G(```!^=G)R<G)S@G]^
+M=F04_O[^_O[^_O[^<G)R<G)M;0```&UM<G)R<G."?WY^=F04_O[^_O[^_OYR
+M<G)R````````````?GER<X)_?GY^=F3^_O[^_O[^_G)R<G)R`````````(%Y
+M<G)S@G]^?GY\=O[^_O[^_O[^<G)R<G)R``````"!>7)R<G."?WY^?GMZ_O[^
+M_O[^_OYR<G)R<G)R````@7ER<G)P<X)_?GY[>GK^_O[^_O[^_G)R<G)R<G)R
+M`(%Y<G)R<'!S@G]^>WIZ>O[^_O[^_O[^<G)R<G)R<G)R<G)R<G!P<'."?W1Z
+M>GIZ_O[^_O[^_OYK:VMK:VMK:VMK:VIH:FIJ;X)T<6UX>GK^_O[^86%A86%A
+M86%A86%A86%A86%A86%F?FQE46UU>/[^_O[^2DI*2DI*2DI*2DI*2DI*2DI*
+M2F%I95%286UU_O[^_O[^)R<G)R<G)R<G)R<G)R<G)R<G1&%*2TA086W^_O[^
+M_O[^&1D9&1D9&1D9&1D9&1D9&1D9&2(H1TQ/8?[^_O[^_OX9!PL.#30`*BTO
+M,``25EM<$A(1%AH?*4Q58?[^_O[^'"(*#S,U.``K+C(]`!)66UT3$Q(1%A@D
+M0T9.8?[^_APB'`D/,S8Y`"LN,CX`$E9<7E83$Q(1%1H?14Q-8?X<)B4A"`\S
+M-CL`,2XR/P`25EQ?5B40$Q(1%AHD0D9)1/X<)24(;8-W.@!G@X!``&>'@(96
+M5%,0$Q(1%QHH1D3^_OX<)0@,,S4\`"LN,D``$EQ<8%9E?6(0$Q(7%QY$_O[^
+M_OX<"`PU-X@`*RPRB``27%^(5EICA&$0$A<;'O[^_O[^_OX(AXB(AP6'B(B'
+M$H>(B(=95EAC?F,2'1PE1/[^_O[^_OX(AXB(AP6'B(B'$H>(B(=95A-C;A)!
+M(R-!1/[^_O[^_OX(AXB(AP6'B(B'$H>(B(=7$Q-3$B`C(R`<'/[^_O[^_OX(
+MAXB(AP6'B(B'$H>(B(=6$Q,2_O[^_O[^_O[^_O[^_OX(AXB(AP6'B(B'$H>(
+MB(=6$Q+^_O[^_O[^_O[^_O[^_OX(AXB(AP6'B(B'$H>(B(<3$O[^_O[^_O[^
+M_O[^_O[^_OX(A_[^AP6'_OZ'$H?^_H<3_O[^_O[^\``#__```?_P``#_\```
+M?_```#_P```?\```#_````_P```/\```#_````_P```/\```#_````\````/
+M@```#\````_@```/X```!\````.````!`````(````'````#X```!_````/X
+M```!_````/X``#__```__X``/__,8S\```$`!``0$!```0`$`"@!```!`!`0
+M```!``@`:`4```(`("`0``$`!`#H`@```P`@(````0`(`*@(```$````*```
+M`%T````N`0```0`$``(```!."P``$PL``!,+`````````````````````&8`
+M*&8G`&````"`````@("``,#`P`#___\`____`/___P#___\`____`/___P#_
+M__\`____`/___P!=,P``73,``%TS``!=,P``73,``%TS``!=,P``73,``%TS
+M``!=,P``73,``%TS``!=,P``73,``%TS``!=,P``73,``%TS``!=,P``73,`
+M`%TS``!=,P``73,``%TS``!=,P``73,``%TS``!=,P``73,``%TS``!=,P``
+M73,``%TS``!=,P``73,``%TS``!=,P``73,``%TS``!=,P``73,``%TS``!=
+M,P``73,``%TS``!=,P``73,``%TS``!=,P``73,``%TS``!=,P``73,``%TS
+M``!=,P``73,``%TS``!=,P``13,$1!0S``!#,P=$$S,``$`S#400,P``/S,/
+M1`\S```\,Q-$#C,``#LS%40-,P``.#,91`PS```W,QM$"S,``#0S'T0*,P``
+M,S,A1`DS```P,R5$"#,``"\S)T0',P``+#,K1`8S```K,RU$!3,``"@S,40$
+M,P``)S,91`$T&40#,P``)#,;1`(S&D0",P``(S,91`4S&T0!,P``(#,;1`8S
+M'$0``!\S&40),QQ$```<,QM$"C,<1```&S,91`TS'$0``!@S&T0.,QQ$```7
+M,QE$$3,<1```%#,;1!(S'$0``!,S&405,QQ$```0,QM$%C,<1```#S,91!DS
+M'$0```PS&T0:,QQ$```+,QE$'3,<1```"#,;1!XS'$0```<S&40A,QQ$```$
+M,QM$(C,<1````S,91"4S'$0``!M$)C,<1```&$0I,QQ$```71"HS'$0``!1$
+M+3,<1```$T0N,QQ$```01#$S'$0```]$,C,<1```#$0U,QQ$```+1#8S'$0`
+M``A$.3,<1```!T0Z,QQ$```$1#TS'$0```-$/C,<1```03,<1```03,<1```
+M03,<1```03,<1```03,<1```03,<1```03,<1```03,<1```03,<1```03,<
+M1```03,<1```03,<1```03,<1```03,<1```03,<1```03,<1```03,<1```
+M03,<1```03,<1```03,<1```03,<1```03,<1```03,<1```03,<1```03,<
+M1```03,<1```03,<1```03,<1```03,<1```03,<1```03,<1```03,<1```
+M03,<1```03,<1```03,<1```03,<1```03,<1```03,<1```03,<1```03,<
+M1```03,<1```03,<1```03,<1```03,<1```03,<1```03,<1```03,<1```
+M03,<1```03,<1```03,<1```03,<1```03,<1```03,<1```03,<1```03,<
+M1```03,<1```03,<1```03,<1```03,<1```03,<1```03,<1```03,<1```
+M03,<1```03,<1```03,<1```03,<1```03,<1```03,<1```03,<1```03,<
+M1```03,<1```03,<1```03,<1```03,<1```03,<1```03,<1```03,<1```
+M03,<1```03,<1```03,<1```03,<1```03,<1```03,<1```03,<1```03,<
+M1```03,<1```03,<1```03,<1```03,<1```03,<1```03,<1```03,<1```
+M03,<1```03,<1```03,<1```03,<1```03,<1```03,<1```03,<1```03,<
+M1```03,<1```03,<1```03,<1```03,<1```03,<1```03,<1```03,<1```
+M03,<1```03,<1```03,<1```03,<1```03,<1```03,<1```03,<1```03,<
+M1```03,<1```03,<1```03,<1```03,<1```$#,]=Q!$```0,SUW$$0``!`S
+M/7<01```$#,]=Q!$```0,P1W-0`$=Q!$```0,P1W-0`$=Q!$```0,P1W)``#
+M9PX`!'<01```$#,$=R(```A7=W4`"P`$=Q!$```0,P1W(```#&=W9W=@``D`
+M!'<01```$#,$=QX```Q7=U,W)W4+``1W$$0``!`S!'<<```09W=3,S<E=V`)
+M``1W$$0``!`S!'<:```(5W=3,P,S``AR)7=0"``$=Q!$```0,P1W&```"&=W
+M4S,%,P`(<B)7=@@`!'<01```$#,$=Q8```A7=U,S!S,`#'(B)7=0``0`!'<0
+M1```$#,$=Q0```AG=U,S"3,!<@8B`G4'``1W$$0``!`S!'<2```(5W=3,PLS
+M`7(&(@)U!P`$=Q!$```0,P1W$```"&=W4S,-,P%R!B("=0<`!'<01```$#,$
+M=PX```A7=U,S#S,!<@8B`G4'``1W$$0``!`S!'<,```(9W=3,Q$S`7(&(@)U
+M!P`$=Q!$```0,P1W"@``"%=W4S,3,P%R!B("=0<`!'<01```$#,$=P@```AG
+M=U,S%3,!<@8B`G4'``1W$$0``!`S!'<'```$9W4:,P%R!B("=0<`!'<01```
+M$#,$=P<``F<<,P%R!B("=0<`!'<01```$#,$=P<``F<<,P%R!B("=0<`!'<0
+M1```$#,$=P<``F<<,P%R!B("=0<`!'<01```$#,$=P<``F<<,P%R!B("=0<`
+M!'<01```$#,$=P<``F<<,P%R!B("=0<`!'<01```$#,$=P<``F<<,P%R!B("
+M=0<`!'<01```$#,$=P<``F<<,P%R!B("=0<`!'<01```$#,$=P<``F<<,P%R
+M!B("=0<`!'<01```$#,$=P<``F<<,P%R!B("=0<`!'<01```$#,$=P<``F<<
+M,P%R!B("=0<`!'<01```$#,$=P<``F<:,P`,5W=2(B=0!@`$=Q!$```0,P1W
+M!P`"9Q@S`!!7=V=U(B=0``0`!'<01```$#,$=P<``F<6,P`05W=1%G=2)U`&
+M``1W$$0``!`S!'<'``)G%#,`%%=W41$15W4G4``$``1W$$0``!`S!'<'``)G
+M$C,`"%=W41$%$0`(9W5U``4`!'<01```$#,$=P<``F<0,P`(5W=1$0@1``A7
+M=U``!``$=Q!$```0,P1W!P`"9PXS``A7=U$1"Q$`!&=U!P`$=P$T#T0``!`S
+M!'<'``)G##,`"%=W41$-$0`$5W4'``1W`C,.1```$#,$=P<``F<*,P`(5W=1
+M$0T1``A7=U``!0`$=P,S#40``!`S!'<'``)G"#,`"%=W41$-$0`(5W=0``<`
+M!'<$,PQ$```0,P1W!P`"9P8S``A7=U$1#1$`"%=W4``)``1W!3,+1```#S,`
+M"$=W<``$```,9S,S5W=1#Q$`"%=W4``+``1W!C,*1```#S,`"$=W<``$```,
+M9S-7=U$1#1$`"%=W4``-``1W!S,)1```#3,#1`1W!P``"&=7=U$/$0`(5W=0
+M``\`!'<(,PA$```*,P9$!'<'```(9W=1$0T1``A7=U``$0`$=PDS!T0```DS
+M!T0$=P<```1G<0\1``A7=U``$P`$=PHS!D0```8S"D0$=P@``V<-$0`(5W=0
+M`!4`!'<+,P5$```%,PM$!'<)```$9U$)$0`(5W=0`!<`!'<,,P1$```#,PU$
+M!'<*``-G!Q$`"%=W4``9``1W#3,#1````30/1`1W"P``#&=1$15W=1X`!'<.
+M,P)$```01`1W#``#9P`(%7=U`!X`!'</,P%$```01`1W#0``"&=W=0`@``1W
+M$#,``!!$!'<.``-G)``$=Q`S```01`1W-0`$=Q`S```01`1W-0`$=Q`S```.
+M1`(S/7<0,P``#40#,SUW$#,```I$!C,]=Q`S```)1`<S/7<0,P``!D17,P``
+M!418,P```D1;,P```4-<,P``73,``%TS``!=,P``73,``%TS``!=,P``73,`
+M`%TS``!=,P``73,``%TS``!=,P``73,``0``P`C*D``````+`!L`+P!;`>``
+M`````%<`:0!N`%(`00!2`"``<P!E`&P`9@`M`&4`>`!T`'(`80!C`'0`:0!N
+M`&<`(`!A`'(`8P!H`&D`=@!E````"`!-`%,`(`!3`&@`90!L`&P`(`!$`&P`
+M9P`@`#(````."`!0``````8`"0`]`+H`;`#__X(``````````(`"4`````!+
+M`),`"`$(`&4`__^"`"8`1`!E`',`=`!I`&X`80!T`&D`;P!N`"``9@!O`&P`
+M9`!E`'(``````$(`(5``````2P"=`,0`&`!F`/__A0````````````%0````
+M`!8!G``\``X`9P#__X``0@!R`&\`)@!W`',`90`N`"X`+@````````!$"*%0
+M`````$L`"0`(`8,`:`!2`&D`8P!H`$4`9`!I`'0`,@`P`%<````````````0
+M``!``````$L`I@`*`0$`:0#__X(````````````"4`````!+`*\`Q``(`&L`
+M__^"`$D`;@!S`'0`80!L`&P`80!T`&D`;P!N`"``<`!R`&\`9P!R`&4`<P!S
+M```````!`(!0`````$L`N0`(`0H`:@!M`',`8P!T`&P`<P!?`'``<@!O`&<`
+M<@!E`',`<P`S`#(````````````0``!0````````R0!=`0$`_____X(`````
+M`````0`!4`````#3`,\`/``.``$`__^``$D`;@!S`'0`80!L`&P`````````
+M`5``````%@'/`#P`#@`"`/__@`!#`&$`;@!C`&4`;```````````````P`#(
+MD``````1`&X`-0#>`*T``````$,`;P!N`&8`:0!R`&T`(`!F`&D`;`!E`"``
+M<@!E`'``;`!A`&,`90````@`30!3`"``4P!H`&4`;`!L`"``1`!L`&<`(``R
+M````!P``4``````$``(`U@"%`/____^``````````````E``````"P`,`,<`
+M"`#_____@@!4`&@`90`@`&8`;P!L`&P`;P!W`&D`;@!G`"``9@!I`&P`90`@
+M`&$`;`!R`&4`80!D`'D`(`!E`'@`:0!S`'0`<P``````!`B!4``````+`!8`
+MQP`>`&4`__^!`````````````E``````"P`Y`,<`"`#_____@@!7`&\`=0!L
+M`&0`(`!Y`&\`=0`@`&P`:0!K`&4`(`!T`&\`(`!R`&4`<`!L`&$`8P!E`"``
+M=`!H`&4`(`!E`'@`:0!S`'0`:0!N`&<`(`!F`&D`;`!E```````#``!0````
+M`!L`1@`2`!0`9@#__X(````````````"4``````V`$<`G``(`&@`__^"````
+M`````````E``````-@!1`)P`"`!J`/__@@````````````)0``````L`7P#'
+M``@`_____X(`=P!I`'0`:``@`'0`:`!I`',`(`!O`&X`90`_``````````,`
+M`%``````&P!L`!(`%`!G`/__@@````````````)0`````#8`;0"<``@`:0#_
+M_X(````````````"4``````V`'<`G``(`&L`__^"``````````$``5``````
+M#P"-`$``#0!L`/__@``F`%D`90!S`````````````5``````3P"-`$``#0!O
+M`/__@`!9`&4`<P`@`'0`;P`@`"8`00!L`&P``````````5``````CP"-`$``
+M#0!N`/__@``F`%(`90!N`&$`;0!E``````````%0``````\`F@!```T`;0#_
+M_X``)@!.`&\``````````5``````3P":`$``#0!P`/__@`!.`&\`(`!T`&\`
+M(`!!`"8`;`!L`````````````5``````CP":`$``#0!Q`/__@``F`$,`80!N
+M`&,`90!L``````#``,B0``````<`8`!2`)X`70``````4@!E`&X`80!M`&4`
+M```(`$T`4P`@`%,`:`!E`&P`;``@`$0`;`!G`"``,@```(``@5``````!@`Q
+M`)$`#`!F`/__@0`````````!``%0`````!8`2@`R``X``0#__X``3P!+````
+M`````````5``````4P!*`#(`#@`"`/__@`!#`&$`;@!C`&4`;```````````
+M``)0``````8`"P"1``@`_____X(`4@!E`&X`80!M`&4`(`!F`&D`;`!E````
+M``"`"(%0``````8`%@"1``P`90#__X$````````````"4``````&`"8`D0`(
+M`/____^"`'0`;P`````````'``!0``````,``@"9`$,`_____X``````````
+MP`C(D``````%`"8`+@"W`$,``````$4`;@!T`&4`<@`@`'``80!S`',`=P!O
+M`'(`9`````@`30!3`"``4P!H`&4`;`!L`"``1`!L`&<`(``R```````"4```
+M```&``@`J@`(`/____^"`"8`10!N`'0`90!R`"``<`!A`',`<P!W`&\`<@!D
+M`"``9@!O`'(`(`!T`&@`90`@`&4`;@!C`'(`>0!P`'0`90!D`"``9@!I`&P`
+M90`Z``````"@`(%0``````8`&@"J``P`90#__X$``````````0`!4``````D
+M`#``,@`.``$`__^``$\`2P````````````%0`````&``,``R``X``@#__X``
+M0P!A`&X`8P!E`&P``````````(`"4``````&`!``J@`(`&8`__^"````````
+M``````#`",J0``````4`&P`O`%L!X```````3`!I`&,`90!N`',`90````@`
+M30!3`"``4P!H`&4`;`!L`"``1`!L`&<`(``R```````."`!0``````8`"0`]
+M`+H`9@#__X(`````````1`@!4`````!+``D`"`&Z`&4`__^!`````````!``
+M`%````````#)`%T!`0#_____@@`````````!``%0`````-,`SP`\``X``0#_
+M_X``00!C`&,`90!P`'0````````````!4``````6`<\`/``.``(`__^``$0`
+M90!C`&P`:0!N`&4```````````#``,B0``````<`.P!+`,(`BP``````3@!E
+M`'@`=``@`'8`;P!L`'4`;0!E`"``:0!S`"``<@!E`'$`=0!I`'(`90!D````
+M"`!-`%,`(`!3`&@`90!L`&P`(`!$`&P`9P`@`#(```````<``%``````!@`$
+M`+8`:P#_____@`````````````)0``````T`$`"H`!``_____X(`60!O`'4`
+M(`!N`&4`90!D`"``=`!O`"``:`!A`'8`90`@`'0`:`!E`"``9@!O`&P`;`!O
+M`'<`:0!N`&<`(`!V`&\`;`!U`&T`90`@`'0`;P`@`&,`;P!N`'0`:0!N`'4`
+M90`@`&4`>`!T`'(`80!C`'0`:0!O`&X`.@``````@`"!4``````-`#4`J``,
+M`&4`__^!`````````````5``````@P`D`#(`#@!F`/__@``F`$(`<@!O`'<`
+M<P!E`"X`+@`N`````````````E``````#0!2`*@`&`#_____@@!)`&X`<P!E
+M`'(`=``@`&$`(`!D`&D`<P!K`"``=P!I`'0`:``@`'0`:`!I`',`(`!V`&\`
+M;`!U`&T`90`@`&$`;@!D`"``<`!R`&4`<P!S`"``(@!/`$L`(@`@`'0`;P`@
+M`'0`<@!Y`"``80!G`&$`:0!N`"``;P!R`"``<`!R`&4`<P!S`"``(@!#`&$`
+M;@!C`&4`;``B`"``=`!O`"``8@!R`&4`80!K`"``90!X`'0`<@!A`&,`=`!I
+M`&\`;@`````````!``%0`````"H`=P`R``X``0#__X``3P!+````````````
+M`5``````9@!W`#(`#@`"`/__@`!#`&$`;@!C`&4`;``````````\/WAM;"!V
+M97)S:6]N/2(Q+C`B(&5N8V]D:6YG/2)55$8M."(@<W1A;F1A;&]N93TB>65S
+M(C\^#0H\87-S96UB;'D@>&UL;G,](G5R;CIS8VAE;6%S+6UI8W)O<V]F="UC
+M;VTZ87-M+G8Q(B!M86YI9F5S=%9E<G-I;VX](C$N,"(^#0H\87-S96UB;'E)
+M9&5N=&ET>0T*("!V97)S:6]N/2(Q+C`N,"XP(@T*("!P<F]C97-S;W)!<F-H
+M:71E8W1U<F4](BHB#0H@(&YA;64](E=I;E)!4B!31E@B#0H@('1Y<&4](G=I
+M;C,R(B\^#0H\9&5S8W)I<'1I;VX^5VEN4D%2(%-&6"!M;V1U;&4\+V1E<V-R
+M:7!T:6]N/@T*/'1R=7-T26YF;R!X;6QN<STB=7)N.G-C:&5M87,M;6EC<F]S
+M;V9T+6-O;3IA<VTN=C(B/@T*("`\<V5C=7)I='D^#0H@("`@/')E<75E<W1E
+M9%!R:79I;&5G97,^#0H@("`@("`\<F5Q=65S=&5D17AE8W5T:6]N3&5V96P@
+M;&5V96P](F%S26YV;VME<B(@("`@("`@("`@("`-"B`@("`@('5I06-C97-S
+M/2)F86QS92(O/@T*("`@(#PO<F5Q=65S=&5D4')I=FEL96=E<SX-"B`@/"]S
+M96-U<FET>3X-"CPO=')U<W1);F9O/@T*/&1E<&5N9&5N8WD^#0H@(#QD97!E
+M;F1E;G1!<W-E;6)L>3X-"B`@("`\87-S96UB;'E)9&5N=&ET>0T*("`@("`@
+M='EP93TB=VEN,S(B#0H@("`@("!N86UE/2)-:6-R;W-O9G0N5VEN9&]W<RY#
+M;VUM;VXM0V]N=')O;',B#0H@("`@("!V97)S:6]N/2(V+C`N,"XP(@T*("`@
+M("`@<')O8V5S<V]R07)C:&ET96-T=7)E/2(J(@T*("`@("`@<'5B;&EC2V5Y
+M5&]K96X](C8U.35B-C0Q-#1C8V8Q9&8B#0H@("`@("!L86YG=6%G93TB*B(O
+M/@T*("`\+V1E<&5N9&5N=$%S<V5M8FQY/@T*/"]D97!E;F1E;F-Y/@T*/&-O
+M;7!A=&EB:6QI='D@>&UL;G,](G5R;CIS8VAE;6%S+6UI8W)O<V]F="UC;VTZ
+M8V]M<&%T:6)I;&ET>2YV,2(^#0H@(#QA<'!L:6-A=&EO;CX-"B`@("`\(2TM
+M5&AE($E$(&)E;&]W(&EN9&EC871E<R!A<'!L:6-A=&EO;B!S=7!P;W)T(&9O
+M<B!7:6YD;W=S(%9I<W1A("TM/@T*("`@("`@/'-U<'!O<G1E9$]3($ED/2)[
+M93(P,3$T-3<M,34T-BTT,V,U+6$U9F4M,#`X9&5E93-D,V8P?2(O/@T*("`@
+M(#PA+2U4:&4@240@8F5L;W<@:6YD:6-A=&5S(&%P<&QI8V%T:6]N('-U<'!O
+M<G0@9F]R(%=I;F1O=W,@-R`M+3X-"B`@("`@(#QS=7!P;W)T961/4R!)9#TB
+M>S,U,3,X8CEA+35D.38M-&9B9"TX93)D+6$R-#0P,C(U9CDS87TB+SX-"B`@
+M/"]A<'!L:6-A=&EO;CX-"CPO8V]M<&%T:6)I;&ET>3X-"CQA<VUV,SIA<'!L
+M:6-A=&EO;B!X;6QN<SIA<VUV,STB=7)N.G-C:&5M87,M;6EC<F]S;V9T+6-O
+M;3IA<VTN=C,B/@T*("`\87-M=C,Z=VEN9&]W<U-E='1I;F=S('AM;&YS/2)H
+M='1P.B\O<V-H96UA<RYM:6-R;W-O9G0N8V]M+U--22\R,#`U+U=I;F1O=W-3
+M971T:6YG<R(^#0H@("`@/&1P:4%W87)E/G1R=64\+V1P:4%W87)E/@T*("`\
+M+V%S;78S.G=I;F1O=W-3971T:6YG<SX-"CPO87-M=C,Z87!P;&EC871I;VX^
+M#0H\+V%S<V5M8FQY/@T*#0H``````````!D`4P!E`&P`90!C`'0`(`!D`&4`
+M<P!T`&D`;@!A`'0`:0!O`&X`(`!F`&\`;`!D`&4`<@`-`$4`>`!T`'(`80!C
+M`'0`:0!N`&<`(``E`',`"P!3`&L`:0!P`'``:0!N`&<`(``E`',`&0!5`&X`
+M90!X`'``90!C`'0`90!D`"``90!N`&0`(`!O`&8`(`!A`'(`8P!H`&D`=@!E
+M`!\`5`!H`&4`(`!F`&D`;`!E`"``(@`E`',`(@`@`&@`90!A`&0`90!R`"``
+M:0!S`"``8P!O`'(`<@!U`'``=``E`%0`:`!E`"``80!R`&,`:`!I`'8`90`@
+M`&,`;P!M`&T`90!N`'0`(`!H`&4`80!D`&4`<@`@`&D`<P`@`&,`;P!R`'(`
+M=0!P`'0`'@!4`&@`90`@`&$`<@!C`&@`:0!V`&4`(`!C`&\`;0!M`&4`;@!T
+M`"``:0!S`"``8P!O`'(`<@!U`'``=``1`$X`;P!T`"``90!N`&\`=0!G`&@`
+M(`!M`&4`;0!O`'(`>0`4`%4`;@!K`&X`;P!W`&X`(`!M`&4`=`!H`&\`9``@
+M`&D`;@`@`"4`<P`.`$,`80!N`&X`;P!T`"``;P!P`&4`;@`@`"4`<P`0`$,`
+M80!N`&X`;P!T`"``8P!R`&4`80!T`&4`(``E`',`%P!#`&$`;@!N`&\`=``@
+M`&,`<@!E`&$`=`!E`"``9@!O`&P`9`!E`'(`(``E`',``````$0`0P!2`$,`
+M(`!F`&$`:0!L`&4`9``@`&D`;@`@`'0`:`!E`"``90!N`&,`<@!Y`'``=`!E
+M`&0`(`!F`&D`;`!E`"``)0!S`"X`(`!#`&\`<@!R`'4`<`!T`"``9@!I`&P`
+M90`@`&\`<@`@`'<`<@!O`&X`9P`@`'``80!S`',`=P!O`'(`9``N`!``0P!2
+M`$,`(`!F`&$`:0!L`&4`9``@`&D`;@`@`"4`<P`<`%``80!C`&L`90!D`"``
+M9`!A`'0`80`@`$,`4@!#`"``9@!A`&D`;`!E`&0`(`!I`&X`(``E`',`%0!7
+M`'(`;P!N`&<`(`!P`&$`<P!S`'<`;P!R`&0`(`!F`&\`<@`@`"4`<P`U`%<`
+M<@!I`'0`90`@`&4`<@!R`&\`<@`@`&D`;@`@`'0`:`!E`"``9@!I`&P`90`@
+M`"4`<P`N`"``4`!R`&\`8@!A`&(`;`!Y`"``=`!H`&4`(`!D`&D`<P!K`"``
+M:0!S`"``9@!U`&P`;``9`%(`90!A`&0`(`!E`'(`<@!O`'(`(`!I`&X`(`!T
+M`&@`90`@`&8`:0!L`&4`(``E`',`$`!&`&D`;`!E`"``8P!L`&\`<P!E`"``
+M90!R`'(`;P!R`!T`5`!H`&4`(`!R`&4`<0!U`&D`<@!E`&0`(`!V`&\`;`!U
+M`&T`90`@`&D`<P`@`&$`8@!S`&4`;@!T`#(`5`!H`&4`(`!A`'(`8P!H`&D`
+M=@!E`"``:0!S`"``90!I`'0`:`!E`'(`(`!I`&X`(`!U`&X`:P!N`&\`=P!N
+M`"``9@!O`'(`;0!A`'0`(`!O`'(`(`!D`&$`;0!A`&<`90!D`!(`10!X`'0`
+M<@!A`&,`=`!I`&X`9P`@`&8`<@!O`&T`(``E`',````+`$X`90!X`'0`(`!V
+M`&\`;`!U`&T`90`=`%0`:`!E`"``80!R`&,`:`!I`'8`90`@`&@`90!A`&0`
+M90!R`"``:0!S`"``8P!O`'(`<@!U`'``=``%`$,`;`!O`',`90`%`$4`<@!R
+M`&\`<@!A`$4`<@!R`&\`<@!S`"``90!N`&,`;P!U`&X`=`!E`'(`90!D`"``
+M=P!H`&D`;`!E`"``<`!E`'(`9@!O`'(`;0!I`&X`9P`@`'0`:`!E`"``;P!P
+M`&4`<@!A`'0`:0!O`&X`"@!,`&\`;P!K`"``80!T`"``=`!H`&4`(`!I`&X`
+M9@!O`'(`;0!A`'0`:0!O`&X`(`!W`&D`;@!D`&\`=P`@`&8`;P!R`"``;0!O
+M`'(`90`@`&0`90!T`&$`:0!L`',````%`&(`>0!T`&4`<P`+`&T`;P!D`&D`
+M9@!I`&4`9``@`&\`;@`8`&8`;P!L`&0`90!R`"``:0!S`"``;@!O`'0`(`!A
+M`&,`8P!E`',`<P!I`&(`;`!E`&P`4P!O`&T`90`@`&8`:0!L`&4`<P`@`&,`
+M;P!U`&P`9``@`&X`;P!T`"``8@!E`"``8P!R`&4`80!T`&4`9``N``H`4`!L
+M`&4`80!S`&4`(`!C`&P`;P!S`&4`(`!A`&P`;``@`&$`<`!P`&P`:0!C`&$`
+M=`!I`&\`;@!S`"P`(`!R`&4`8@!O`&\`=``@`%<`:0!N`&0`;P!W`',`(`!A
+M`&X`9``@`'(`90!S`'0`80!R`'0`(`!T`&@`:0!S`"``:0!N`',`=`!A`&P`
+M;`!A`'0`:0!O`&X`7`!3`&\`;0!E`"``:0!N`',`=`!A`&P`;`!A`'0`:0!O
+M`&X`(`!F`&D`;`!E`',`(`!A`'(`90`@`&,`;P!R`'(`=0!P`'0`+@`*`%``
+M;`!E`&$`<P!E`"``9`!O`'<`;@!L`&\`80!D`"``80`@`&8`<@!E`',`:``@
+M`&,`;P!P`'D`(`!A`&X`9``@`'(`90!T`'(`>0`@`'0`:`!E`"``:0!N`',`
+M=`!A`&P`;`!A`'0`:0!O`&X`"0!!`&P`;``@`&8`:0!L`&4`<P``````````
+M`````````````````````````````````````````$4`/`!U`&P`/@`\`&P`
+M:0`^`%``<@!E`',`<P`@`#P`8@`^`$D`;@!S`'0`80!L`&P`/``O`&(`/@`@
+M`&(`=0!T`'0`;P!N`"``=`!O`"``<P!T`&$`<@!T`"``90!X`'0`<@!A`&,`
+M=`!I`&\`;@`N`#P`+P!L`&D`/@`\`&(`<@`^`#P`8@!R`#X`10`\`'4`;``^
+M`#P`;`!I`#X`4`!R`&4`<P!S`"``/`!B`#X`10!X`'0`<@!A`&,`=``\`"\`
+M8@`^`"``8@!U`'0`=`!O`&X`(`!T`&\`(`!S`'0`80!R`'0`(`!E`'@`=`!R
+M`&$`8P!T`&D`;P!N`"X`/``O`&P`:0`^`#P`8@!R`#X`/`!B`'(`/@`V`#P`
+M;`!I`#X`50!S`&4`(``\`&(`/@!"`'(`;P!W`',`90`\`"\`8@`^`"``8@!U
+M`'0`=`!O`&X`(`!T`&\`(`!S`&4`;`!E`&,`=``@`'0`:`!E`"``9`!E`',`
+M=`!I`&X`80!T`&D`;P!N`#0`9@!O`&P`9`!E`'(`(`!F`'(`;P!M`"``=`!H
+M`&4`(`!F`&\`;`!D`&4`<@!S`"``=`!R`&4`90`N`"``20!T`"``8P!A`&X`
+M(`!B`&4`(`!A`&P`<P!O`"``90!N`'0`90!R`&4`9``6`&T`80!N`'4`80!L
+M`&P`>0`N`#P`+P!L`&D`/@`\`&(`<@`^`#P`8@!R`#X`.``\`&P`:0`^`$D`
+M9@`@`'0`:`!E`"``9`!E`',`=`!I`&X`80!T`&D`;P!N`"``9@!O`&P`9`!E
+M`'(`(`!D`&\`90!S`"``;@!O`'0`(`!E`'@`:0!S`'0`+``@`&D`=``@`'<`
+M:0!L`&P`(`!B`&4`,@!C`'(`90!A`'0`90!D`"``80!U`'0`;P!M`&$`=`!I
+M`&,`80!L`&P`>0`@`&(`90!F`&\`<@!E`"``90!X`'0`<@!A`&,`=`!I`&\`
+M;@`N`#P`+P!L`&D`/@`\`"\`=0!L`#X`````````%@!4`&@`90`@`&$`<@!C
+M`&@`:0!V`&4`(`!I`',`(`!C`&\`<@!R`'4`<`!T````````````'0!%`'@`
+M=`!R`&$`8P!T`&D`;@!G`"``9@!I`&P`90!S`"``=`!O`"``)0!S`"``9@!O
+M`&P`9`!E`'(`)`!%`'@`=`!R`&$`8P!T`&D`;@!G`"``9@!I`&P`90!S`"``
+M=`!O`"``=`!E`&T`<`!O`'(`80!R`'D`(`!F`&\`;`!D`&4`<@`````````'
+M`$4`>`!T`'(`80!C`'0`$P!%`'@`=`!R`&$`8P!T`&D`;P!N`"``<`!R`&\`
+M9P!R`&4`<P!S`````````#T`5`!O`'0`80!L`"``<`!A`'0`:``@`&$`;@!D
+M`"``9@!I`&P`90`@`&X`80!M`&4`(`!L`&4`;@!G`'0`:``@`&T`=0!S`'0`
+M(`!N`&\`=``@`&4`>`!C`&4`90!D`"``)0!D`"``8P!H`&$`<@!A`&,`=`!E
+M`'(`<P``````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M``````````````````````````````````````````````````````!287(A
+M&@<`SY!S```-`````````,B;=""0.P`0````$`````+Q$M:7;&$2/QTP"``@
+M````=&5S="YT>'3POU/A"V-A$C_CG0963R<_1[*6=&5S="!T97AT(&9I;&4-
+M"J/L=""00P!'`0``N0$```(WUUQ;QV$2/QTS$``@````=&5S='-H;W)T8W5T
+M+FQN:[#_XWD7N&$2/[,"!)U3*3\I8@<)V1&0R]7`VWF-"-",24*"IU"$:&01
+MK>H6"P:E!#@11Y_B$[TA"'?P3O8]S9!^#-2"+:U(+2B**@T(-*+:@H-J-K0@
+MI[.G(=TDWWG@:&A^";N;N^&[N?(],I\W,PP,_8;F_"LT/L0D6P5KT0S#,W*Q
+M$8G\W`QTZG:AWY"6T=4_GNV378/<@[G?R@F!C`<MYDK5;`)2-%EE<*[,,(P6
+MX>W.^ZM4XY#Q]B`T,Y8PX9Z7KK6-?Q=AUE.[5KHYHQM/A\\*%BRTE)K$^HL1
+M<K2,Y=5%,A2T5Z#2C#:Y*;^60*16&5/UA<C[*?S[DV"02'/-!BUH%0%A.O70
+M#M"3AI5%4QQE-1&^@(8&P+;&M]:<.^?O4A.]&0U_QQO:,3ZW93<9E*DV(K_C
+M!S_?%P/3.Y?7$Y-OJTL?C\=#?XNSRC[OA<!)NK[K_TY^+Z1P$70@D$,`$```
+M`!`````"\1+6EVQA$C\=,!``(````'1E<W1D:7)<=&5S="YT>'2POU/A"W5A
+M$C_#FG^F3A<_M<$T=&5S="!T97AT(&9I;&4-"OLV=."0.@````````````(`
+M````=6$2/Q0P!P`0````=&5S=&1I<K#_PYI_<6$2/Y-1?!M4*3\T'",XC73@
+MD#\````````````"`````'EA$C\4,`P`$````'1E<W1E;7!T>61I<K#_`\UB
+5>6$2/P/-8AM4*3]41RS$/7L`0`<`
+`
+end
diff --git a/libarchive/test/test_read_format_rar_subblock.rar.uu b/libarchive/test/test_read_format_rar_subblock.rar.uu
new file mode 100644
index 000000000000..5c55ca11dd2a
--- /dev/null
+++ b/libarchive/test/test_read_format_rar_subblock.rar.uu
@@ -0,0 +1,7 @@
+begin 644 -
+M4F%R(1H'`,^0<P``#0`````````##'H`@",`(@```!T````#&WQ`G@`````=
+M,P,``````$--5`@!"+Z0\5[-83@7PT#<+OM\M_$>H5JAD)Q_9XLAN3)VO("$
+M4G0@D#(`%````!0````#0J+(OK=VVCX4,`@`I($``'1E<W0N='AT@`BW=MH^
+?MW;:/G1E<W0@=&5X="!D;V-U;65N=`T*Q#U[`$`'````
+`
+end
diff --git a/libarchive/test/test_read_format_rar_unicode.rar.uu b/libarchive/test/test_read_format_rar_unicode.rar.uu
new file mode 100644
index 000000000000..cfe6e40d51f3
--- /dev/null
+++ b/libarchive/test/test_read_format_rar_unicode.rar.uu
@@ -0,0 +1,17 @@
+begin 644 test_read_format_rar_unicode.rar
+M4F%R(1H'`,^0<P``#0````````"H*70@DI0````````````"`````")IX3X4
+M,&\`(````)5<@KZ"YER05H*U@J*#=(-(@XN#7UR05HM+@V6#3(-8@V<@@VB#
+M3(.%@X&#DX-G+G1X=`"(:&A@,(@P7*JP95<P1##5,*BI,.LPP#!<JK!ECXG&
+M,*TPHKDPR#`@R3"JK3#E,.$P\S"`R#`N='@`=`#P)CF$Y)AT()*3``4````%
+M`````MR=;T*V5'0^%#!N`"````"57(*^@N9<BK^.FI*W@J*#=(-`@T.#BY:\
+M;&]N9RUF:6QE;F%M92UI;BV*OXZ:+G1X=`"(:&A@,(@P7*HB;U=;=Y5$,*K5
+M,*$PI##K,(`-5&QO;@!G+69I`&QE;F$`;64M:0IN+2)O5UL`+G1X=`"P=GIH
+M:V%N:FF4+'3@DE,````````````"`````")IX3X4,"X`$````)5<@KZ"YER0
+M5H*U@J*#=(-(@XN#7P"(:&A@,(@P7*JP95<P1##5,*BI,.LPP#``\"8YA&UX
+M=."2,P````````````(`````#VGA/A0P#@`0````E5R"OH+F`(AH:&`PB#``
+M\.H)?ED.="""2``V````-@````,E@OM=6%0+/Q0P*`#MH0``Z*&HXX&@XX*(
+M7..#E>."H>."I..#JP"(:&A@,(@P7*K5,*$PI##K,.:\HN6ME^F5M^.!A..#
+ME>."H>."I..#J^60C6QO;F<M9FEL96YA;64M:6XMYKRBY:V7+G1X=,0]>P!`
+"!P``
+`
+end
diff --git a/libarchive/test/test_read_format_rar_windows.rar.uu b/libarchive/test/test_read_format_rar_windows.rar.uu
new file mode 100644
index 000000000000..05fa8db85846
--- /dev/null
+++ b/libarchive/test/test_read_format_rar_windows.rar.uu
@@ -0,0 +1,22 @@
+begin 644 -
+M4F%R(1H'`,^0<P``#0````````"6GW0@D$,`$````!`````"\1+6EVQA$C\4
+M,!``(````'1E<W1D:7)<=&5S="YT>'3POU/A"W5A$C_#FG]U81(_PYI_=&5S
+M="!T97AT(&9I;&4-"D."=""0.P`0````$`````+Q$M:7;&$2/Q0P"``@````
+M=&5S="YT>'2POU/A"V-A$C_CG09L81(_4^$+=&5S="!T97AT(&9I;&4-"H[-
+M=""00P"Y`0``N0$```(WUUQ;QV$2/Q0P$``@````=&5S='-H;W)T8W5T+FQN
+M:_#_XWD7N&$2/[,"!%U,%S^RB8E,`````10"``````#`````````1IL````@
+M````8[VJ;\%=S`'3/CJ#P5W,`5/_T7G!7<P!$``````````!````````````
+M````````0@!``#(`$````!(_;8$@`'1E<W0N='AT```H``,`!`#OOA(_9($2
+M/VV!%````'0`90!S`'0`+@!T`'@`=````!@```!?````'`````$````<````
+M+0````````!>````$0````,```!;L.$D$`````!#.EQ$;V-U;65N=',@86YD
+M(%-E='1I;F=S7&]W;F5R7$1E<VMT;W!<=&5S="YT>'0```H`+@!<`'0`90!S
+M`'0`+@!T`'@`=``G`$,`.@!<`$0`;P!C`'4`;0!E`&X`=`!S`"``80!N`&0`
+M(`!3`&4`=`!T`&D`;@!G`',`7`!O`'<`;@!E`'(`7`!$`&4`<P!K`'0`;P!P
+M`&`````#``"@6`````````!W:6YX<"UD978`````````_!Y0^#`=Y$V[[2RY
+ME<)9.;3=5J&SR>`1GM0(`"<.&<7\'E#X,!WD3;OM++F5PEDYM-U6H;/)X!&>
+MU`@`)PX9Q0````#%`73@D#H````````````"`````'5A$C\4,`<`$````'1E
+M<W1D:7+P_\.:?W%A$C^347R!3A<_6$$6*JQTX)`_`````````````@````!Y
+M81(_%#`,`!````!T97-T96UP='ED:7*P_P/-8GEA$C\#S6*F3A<_K1<RQ#U[
+$`$`'````
+`
+end
diff --git a/libarchive/test/test_read_format_raw.c b/libarchive/test/test_read_format_raw.c
index cd5f00ee1bf8..a23b9c55a749 100644
--- a/libarchive/test/test_read_format_raw.c
+++ b/libarchive/test/test_read_format_raw.c
@@ -39,14 +39,14 @@ DEFINE_TEST(test_read_format_raw)
/* First, try pulling data out of an uninterpretable file. */
extract_reference_file(reffile1);
assert((a = archive_read_new()) != NULL);
- assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_raw(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_open_filename(a, reffile1, 512));
/* First (and only!) Entry */
- assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualString("data", archive_entry_pathname(ae));
/* Most fields should be unset (unknown) */
assert(!archive_entry_size_is_set(ae));
@@ -59,20 +59,20 @@ DEFINE_TEST(test_read_format_raw)
/* Test EOF */
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
/* Second, try the same with a compressed file. */
extract_reference_file(reffile2);
assert((a = archive_read_new()) != NULL);
- assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_raw(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_open_filename(a, reffile2, 1));
/* First (and only!) Entry */
- assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualString("data", archive_entry_pathname(ae));
/* Most fields should be unset (unknown) */
assert(!archive_entry_size_is_set(ae));
@@ -85,5 +85,5 @@ DEFINE_TEST(test_read_format_raw)
/* Test EOF */
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_read_format_tar.c b/libarchive/test/test_read_format_tar.c
index 9c197df09464..31e6ae303dae 100644
--- a/libarchive/test/test_read_format_tar.c
+++ b/libarchive/test/test_read_format_tar.c
@@ -66,7 +66,7 @@ static void verifyEmpty(void)
struct archive *a;
assert((a = archive_read_new()) != NULL);
- assertA(0 == archive_read_support_compression_all(a));
+ assertA(0 == archive_read_support_filter_all(a));
assertA(0 == archive_read_support_format_all(a));
assertA(0 == archive_read_open_memory(a, archiveEmpty, 512));
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
@@ -75,12 +75,8 @@ static void verifyEmpty(void)
failure("512 zero bytes should be recognized as a tar archive.");
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR);
- assert(0 == archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assert(0 == archive_read_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
/* Single entry with a hardlink. */
@@ -437,7 +433,7 @@ static void verify(unsigned char *d, size_t s,
memset(buff + s, 0, 2048);
assert((a = archive_read_new()) != NULL);
- assertA(0 == archive_read_support_compression_all(a));
+ assertA(0 == archive_read_support_filter_all(a));
assertA(0 == archive_read_support_format_all(a));
assertA(0 == archive_read_open_memory(a, buff, s + 1024));
assertA(0 == archive_read_next_header(a, &ae));
@@ -447,12 +443,8 @@ static void verify(unsigned char *d, size_t s,
/* Verify the only entry. */
f(ae);
- assert(0 == archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assert(0 == archive_read_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
free(buff);
}
diff --git a/libarchive/test/test_read_format_tar_empty_filename.c b/libarchive/test/test_read_format_tar_empty_filename.c
index 8d917144448d..b83226ba3d80 100644
--- a/libarchive/test/test_read_format_tar_empty_filename.c
+++ b/libarchive/test/test_read_format_tar_empty_filename.c
@@ -35,7 +35,7 @@ DEFINE_TEST(test_read_format_tar_empty_filename)
struct archive *a;
assert((a = archive_read_new()) != NULL);
- assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
extract_reference_file(name);
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240));
@@ -58,9 +58,5 @@ DEFINE_TEST(test_read_format_tar_empty_filename)
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR);
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
-#endif
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_read_format_tar_filename.c b/libarchive/test/test_read_format_tar_filename.c
new file mode 100644
index 000000000000..abec4ec6d6ca
--- /dev/null
+++ b/libarchive/test/test_read_format_tar_filename.c
@@ -0,0 +1,363 @@
+/*-
+ * Copyright (c) 2011 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD");
+
+#include <locale.h>
+
+/*
+ * The sample tar file was made in LANG=KOI8-R and it contains two
+ * files the charset of which are different.
+ * - the filename of first file is stored in BINARY mode.
+ * - the filename of second file is stored in UTF-8.
+ *
+ * Whenever hdrcharset option is specified, we will correctly read the
+ * filename of sencod file, which is stored in UTF-8 by default.
+ */
+
+static void
+test_read_format_tar_filename_KOI8R_CP866(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read filename in ru_RU.CP866 with "hdrcharset=KOI8-R" option.
+ * We should correctly read two filenames.
+ */
+ if (NULL == setlocale(LC_ALL, "Russian_Russia.866") &&
+ NULL == setlocale(LC_ALL, "ru_RU.CP866")) {
+ skipping("ru_RU.CP866 locale not available on this system.");
+ return;
+ }
+
+ /* Test if the platform can convert from UTF-8. */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_tar(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=UTF-8")) {
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+ skipping("This system cannot convert character-set"
+ " from UTF-8 to CP866.");
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) {
+ skipping("This system cannot convert character-set"
+ " from KOI8-R to CP866.");
+ goto next_test;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular first file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\x8f\x90\x88\x82\x85\x92",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular second file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xaf\xe0\xa8\xa2\xa5\xe2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
+ assertEqualIntA(a, ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE,
+ archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+next_test:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+
+ /*
+ * Read filename in ru_RU.CP866 without "hdrcharset=KOI8-R" option.
+ * The filename we can properly read is only second file.
+ */
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /*
+ * Verify regular first file.
+ * The filename is not translated to CP866 because hdrcharset
+ * attribute is BINARY and there is not way to know its charset.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ /* A filename is in KOI8-R. */
+ assertEqualString("\xf0\xf2\xe9\xf7\xe5\xf4",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /*
+ * Verify regular second file.
+ * The filename is translated from UTF-8 to CP866
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xaf\xe0\xa8\xa2\xa5\xe2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
+ assertEqualIntA(a, ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE,
+ archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_tar_filename_KOI8R_UTF8(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read filename in en_US.UTF-8 with "hdrcharset=KOI8-R" option.
+ * We should correctly read two filenames.
+ */
+ if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
+ skipping("en_US.UTF-8 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) {
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+ skipping("This system cannot convert character-set"
+ " from KOI8-R to UTF-8.");
+ return;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xd0\x9f\xd0\xa0\xd0\x98\xd0\x92\xd0\x95\xd0\xa2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
+ assertEqualIntA(a, ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE,
+ archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+ /*
+ * Read filename in en_US.UTF-8 without "hdrcharset=KOI8-R" option.
+ * The filename we can properly read is only second file.
+ */
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /*
+ * Verify regular first file.
+ * The filename is not translated to UTF-8 because hdrcharset
+ * attribute is BINARY and there is not way to know its charset.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ /* A filename is in KOI8-R. */
+ assertEqualString("\xf0\xf2\xe9\xf7\xe5\xf4",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /*
+ * Verify regular second file.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
+ assertEqualIntA(a, ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE,
+ archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_tar_filename_KOI8R_CP1251(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read filename in CP1251 with "hdrcharset=KOI8-R" option.
+ * We should correctly read two filenames.
+ */
+ if (NULL == setlocale(LC_ALL, "Russian_Russia") &&
+ NULL == setlocale(LC_ALL, "ru_RU.CP1251")) {
+ skipping("CP1251 locale not available on this system.");
+ return;
+ }
+
+ /* Test if the platform can convert from UTF-8. */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_tar(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=UTF-8")) {
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+ skipping("This system cannot convert character-set"
+ " from UTF-8 to CP1251.");
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) {
+ skipping("This system cannot convert character-set"
+ " from KOI8-R to CP1251.");
+ goto next_test;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular first file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xcf\xd0\xc8\xc2\xc5\xd2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular second file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
+ assertEqualIntA(a, ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE,
+ archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+next_test:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+ /*
+ * Read filename in CP1251 without "hdrcharset=KOI8-R" option.
+ * The filename we can properly read is only second file.
+ */
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /*
+ * Verify regular first file.
+ * The filename is not translated to CP1251 because hdrcharset
+ * attribute is BINARY and there is not way to know its charset.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ /* A filename is in KOI8-R. */
+ assertEqualString("\xf0\xf2\xe9\xf7\xe5\xf4",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /*
+ * Verify regular second file.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
+ assertEqualIntA(a, ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE,
+ archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+
+DEFINE_TEST(test_read_format_tar_filename)
+{
+ const char *refname = "test_read_format_tar_filename_koi8r.tar.Z";
+
+ extract_reference_file(refname);
+ test_read_format_tar_filename_KOI8R_CP866(refname);
+ test_read_format_tar_filename_KOI8R_UTF8(refname);
+ test_read_format_tar_filename_KOI8R_CP1251(refname);
+}
diff --git a/libarchive/test/test_read_format_tar_filename_koi8r.tar.Z.uu b/libarchive/test/test_read_format_tar_filename_koi8r.tar.Z.uu
new file mode 100644
index 000000000000..80b4568a4958
--- /dev/null
+++ b/libarchive/test/test_read_format_tar_filename_koi8r.tar.Z.uu
@@ -0,0 +1,14 @@
+begin 644 test_read_format_tar_filename_koi8r.tar.Z
+M'YV04,+@05(F#)DR<E[`DY?N7CEZ`")*G$BQHL6+&#-JW%@1AL<;-6J``.`Q
+M!L@8(TN>3.FQ9<D8-$#$B!&2Y@T8-CR"@$%31HT;`$#@X4BTJ-&C2"W6F4,G
+MC!R2,,;4*9,THU2J52^ZU`G5Y<BL8,.*'4N6K`R4:,C(&8/&Z9PR='H(2>(D
+MB)0L"FB"@!.&#IH>"QL^5"`#!H@Q=-*T*=,CQ@P8,F[@L$'C1@S"AOLJ9NP8
+MLF0;-R(K*$NZM.G3J%.K7LVZM>O7%@,[A`B[]L:6($5"-5D#Y>Z57;=ZM"&3
+M9N^?.'7RG/'81E`8MJ,77=KTJ<>KI;&3%L[2J_3OX%/+?AB^O/GSZ-.K7\\^
+M?,"!!0\FA"8MV;5BU-IO_QB2)6_?*O76G7`@%5?33SV)Q%-E-]`0U%#ZV4:=
+M4U!I5Y:%9'$7'%<1=GC>67OU]1<TOT0#"#2X0",+-+5$(PAFAR6V6&./1399
+M#C#!J-F,G=EH0PX\C>;AD$06:>212&)$GWWX)5D6;OW])J"4``K7$G$S'6A9
+M#3[MU!E-SSF)VH361355=F?NYYV&8K9)VGBTN2GGG'36:>>=>.:IYYY\]NGG
+(GX`&*NB@%P$`
+`
+end
diff --git a/libarchive/test/test_read_format_tbz.c b/libarchive/test/test_read_format_tbz.c
index 06d8cad47983..ec38d5a9f8f9 100644
--- a/libarchive/test/test_read_format_tbz.c
+++ b/libarchive/test/test_read_format_tbz.c
@@ -40,20 +40,21 @@ DEFINE_TEST(test_read_format_tbz)
int r;
assert((a = archive_read_new()) != NULL);
- r = archive_read_support_compression_bzip2(a);
+ r = archive_read_support_filter_bzip2(a);
if (r != ARCHIVE_OK) {
skipping("Bzip2 support");
- archive_read_finish(a);
+ archive_read_free(a);
return;
}
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_open_memory(a, archive, sizeof(archive)));
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(1, archive_file_count(a));
assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_BZIP2);
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR);
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_read_format_tgz.c b/libarchive/test/test_read_format_tgz.c
index f411b4338026..f8526771977f 100644
--- a/libarchive/test/test_read_format_tgz.c
+++ b/libarchive/test/test_read_format_tgz.c
@@ -39,22 +39,23 @@ DEFINE_TEST(test_read_format_tgz)
int r;
assert((a = archive_read_new()) != NULL);
- assertEqualInt(ARCHIVE_OK, archive_read_support_compression_all(a));
- r = archive_read_support_compression_gzip(a);
+ assertEqualInt(ARCHIVE_OK, archive_read_support_filter_all(a));
+ r = archive_read_support_filter_gzip(a);
if (r == ARCHIVE_WARN) {
skipping("gzip reading not fully supported on this platform");
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
return;
}
assertEqualInt(ARCHIVE_OK, archive_read_support_format_all(a));
assertEqualInt(ARCHIVE_OK,
archive_read_open_memory(a, archive, sizeof(archive)));
assertEqualInt(ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(1, archive_file_count(a));
assertEqualInt(archive_compression(a),
ARCHIVE_COMPRESSION_GZIP);
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR);
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK,archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK,archive_read_free(a));
}
diff --git a/libarchive/test/test_read_format_tlz.c b/libarchive/test/test_read_format_tlz.c
index 7dd09a0c518e..9054fa6b49dc 100644
--- a/libarchive/test/test_read_format_tlz.c
+++ b/libarchive/test/test_read_format_tlz.c
@@ -42,19 +42,20 @@ DEFINE_TEST(test_read_format_tlz)
int r;
assert((a = archive_read_new()) != NULL);
- assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a));
- r = archive_read_support_compression_lzma(a);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ r = archive_read_support_filter_lzma(a);
if (r == ARCHIVE_WARN) {
skipping("lzma reading not fully supported on this platform");
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
return;
}
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_open_memory(a, archive, sizeof(archive)));
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(1, archive_file_count(a));
assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_LZMA);
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR);
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_read_format_txz.c b/libarchive/test/test_read_format_txz.c
index acff175c56f7..6a9ba2091b7d 100644
--- a/libarchive/test/test_read_format_txz.c
+++ b/libarchive/test/test_read_format_txz.c
@@ -45,19 +45,20 @@ DEFINE_TEST(test_read_format_txz)
int r;
assert((a = archive_read_new()) != NULL);
- assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a));
- r = archive_read_support_compression_xz(a);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ r = archive_read_support_filter_xz(a);
if (r == ARCHIVE_WARN) {
skipping("xz reading not fully supported on this platform");
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
return;
}
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_open_memory(a, archive, sizeof(archive)));
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(1, archive_file_count(a));
assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_XZ);
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR);
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_read_format_tz.c b/libarchive/test/test_read_format_tz.c
index eb066013842c..3a1dcec04666 100644
--- a/libarchive/test/test_read_format_tz.c
+++ b/libarchive/test/test_read_format_tz.c
@@ -40,22 +40,19 @@ DEFINE_TEST(test_read_format_tz)
struct archive *a;
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK,
- archive_read_support_compression_all(a));
+ archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_open_memory(a, archive, sizeof(archive)));
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(1, archive_file_count(a));
failure("archive_compression_name(a)=\"%s\"",
archive_compression_name(a));
assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_COMPRESS);
failure("archive_format_name(a)=\"%s\"", archive_format_name(a));
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR);
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
-#endif
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_read_format_ustar_filename.c b/libarchive/test/test_read_format_ustar_filename.c
new file mode 100644
index 000000000000..f2e577d0a3b9
--- /dev/null
+++ b/libarchive/test/test_read_format_ustar_filename.c
@@ -0,0 +1,512 @@
+/*-
+ * Copyright (c) 2011 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD");
+
+#include <locale.h>
+
+static void
+test_read_format_ustar_filename_eucJP_UTF8(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read eucJP filename in en_US.UTF-8 with "hdrcharset=eucJP" option.
+ */
+ if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
+ skipping("en_US.UTF-8 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=eucJP")) {
+ skipping("This system cannot convert character-set"
+ " from eucJP to UTF-8.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xe6\xbc\xa2\xe5\xad\x97.txt",
+ archive_entry_pathname(ae));
+ assertEqualInt(8, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xe8\xa1\xa8.txt", archive_entry_pathname(ae));
+ assertEqualInt(4, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
+ assertEqualIntA(a, ARCHIVE_FORMAT_TAR_USTAR, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_ustar_filename_CP866_KOI8R(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read CP866 filename in ru_RU.KOI8-R with "hdrcharset=CP866" option.
+ */
+ if (NULL == setlocale(LC_ALL, "Russian_Russia.20866") &&
+ NULL == setlocale(LC_ALL, "ru_RU.KOI8-R")) {
+ skipping("ru_RU.KOI8-R locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP866")) {
+ skipping("This system cannot convert character-set"
+ " from CP866 to KOI8-R.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xf0\xf2\xe9\xf7\xe5\xf4",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xd0\xd2\xc9\xd7\xc5\xd4",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
+ assertEqualIntA(a, ARCHIVE_FORMAT_TAR_USTAR, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_ustar_filename_CP866_UTF8(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read CP866 filename in en_US.UTF-8 with "hdrcharset=CP866" option.
+ */
+ if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
+ skipping("en_US.UTF-8 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP866")) {
+ skipping("This system cannot convert character-set"
+ " from CP866 to UTF-8.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xd0\x9f\xd0\xa0\xd0\x98\xd0\x92\xd0\x95\xd0\xa2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
+ assertEqualIntA(a, ARCHIVE_FORMAT_TAR_USTAR, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_ustar_filename_KOI8R_CP866(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read KOI8-R filename in ru_RU.CP866 with "hdrcharset=KOI8-R" option.
+ */
+ if (NULL == setlocale(LC_ALL, "Russian_Russia.866") &&
+ NULL == setlocale(LC_ALL, "ru_RU.CP866")) {
+ skipping("ru_RU.CP866 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) {
+ skipping("This system cannot convert character-set"
+ " from KOI8-R to CP866.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xaf\xe0\xa8\xa2\xa5\xe2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\x8f\x90\x88\x82\x85\x92",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
+ assertEqualIntA(a, ARCHIVE_FORMAT_TAR_USTAR, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_ustar_filename_KOI8R_UTF8(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read KOI8-R filename in en_US.UTF-8 with "hdrcharset=KOI8-R" option.
+ */
+ if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
+ skipping("en_US.UTF-8 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) {
+ skipping("This system cannot convert character-set"
+ " from KOI8-R to UTF-8.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xd0\x9f\xd0\xa0\xd0\x98\xd0\x92\xd0\x95\xd0\xa2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
+ assertEqualIntA(a, ARCHIVE_FORMAT_TAR_USTAR, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_ustar_filename_eucJP_CP932(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read eucJP filename in CP932/SJIS with "hdrcharset=eucJP" option.
+ */
+ if (NULL == setlocale(LC_ALL, "Japanese_Japan") &&
+ NULL == setlocale(LC_ALL, "ja_JP.SJIS")) {
+ skipping("CP932 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=eucJP")) {
+ skipping("This system cannot convert character-set"
+ " from eucJP.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\x8a\xbf\x8e\x9a.txt", archive_entry_pathname(ae));
+ assertEqualInt(8, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\x95\x5c.txt", archive_entry_pathname(ae));
+ assertEqualInt(4, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
+ assertEqualIntA(a, ARCHIVE_FORMAT_TAR_USTAR, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_ustar_filename_CP866_CP1251(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read CP866 filename in CP1251 with "hdrcharset=CP866" option.
+ */
+ if (NULL == setlocale(LC_ALL, "Russian_Russia") &&
+ NULL == setlocale(LC_ALL, "ru_RU.CP1251")) {
+ skipping("CP1251 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP866")) {
+ skipping("This system cannot convert character-set"
+ " from CP866 to CP1251.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xcf\xd0\xc8\xc2\xc5\xd2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
+ assertEqualIntA(a, ARCHIVE_FORMAT_TAR_USTAR, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+/*
+ * This test only for Windows platform because other archiver
+ * applications on Windows translate CP1251 filenames into CP866
+ * filenames and store it in the ustar file and so we should read
+ * it by default on Windows.
+ */
+static void
+test_read_format_ustar_filename_CP866_CP1251_win(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read CP866 filename in CP1251 without "hdrcharset=CP866" option.
+ */
+ if (NULL == setlocale(LC_ALL, "Russian_Russia")) {
+ skipping("Russian_Russia locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xcf\xd0\xc8\xc2\xc5\xd2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
+ assertEqualIntA(a, ARCHIVE_FORMAT_TAR_USTAR, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_ustar_filename_KOI8R_CP1251(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read KOI8-R filename in CP1251 with "hdrcharset=KOI8-R" option.
+ */
+ if (NULL == setlocale(LC_ALL, "Russian_Russia") &&
+ NULL == setlocale(LC_ALL, "ru_RU.CP1251")) {
+ skipping("CP1251 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) {
+ skipping("This system cannot convert character-set"
+ " from KOI8-R to CP1251.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xcf\xd0\xc8\xc2\xc5\xd2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
+ assertEqualIntA(a, ARCHIVE_FORMAT_TAR_USTAR, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+
+DEFINE_TEST(test_read_format_ustar_filename)
+{
+ const char *refname1 = "test_read_format_ustar_filename_eucjp.tar.Z";
+ const char *refname2 = "test_read_format_ustar_filename_cp866.tar.Z";
+ const char *refname3 = "test_read_format_ustar_filename_koi8r.tar.Z";
+
+ extract_reference_file(refname1);
+ test_read_format_ustar_filename_eucJP_UTF8(refname1);
+ test_read_format_ustar_filename_eucJP_CP932(refname1);
+
+ extract_reference_file(refname2);
+ test_read_format_ustar_filename_CP866_KOI8R(refname2);
+ test_read_format_ustar_filename_CP866_UTF8(refname2);
+ test_read_format_ustar_filename_CP866_CP1251(refname2);
+ test_read_format_ustar_filename_CP866_CP1251_win(refname2);
+
+ extract_reference_file(refname3);
+ test_read_format_ustar_filename_KOI8R_CP866(refname3);
+ test_read_format_ustar_filename_KOI8R_UTF8(refname3);
+ test_read_format_ustar_filename_KOI8R_CP1251(refname3);
+}
diff --git a/libarchive/test/test_read_format_ustar_filename_cp866.tar.Z.uu b/libarchive/test/test_read_format_ustar_filename_cp866.tar.Z.uu
new file mode 100644
index 000000000000..359fc2b342ce
--- /dev/null
+++ b/libarchive/test/test_read_format_ustar_filename_cp866.tar.Z.uu
@@ -0,0 +1,8 @@
+begin 644 test_read_format_ustar_filename_cp866.tar.Z
+M'YV0CR`A$E1($H"#"!,J7,BPH<.'$"-*1`BCXHT:-4``J!CC8@R-'#V"K$BR
+MI`T0,6+4H'%CA@R5,#[&?%E#!@`0,";JW,FSIT\`=>;0"2-G(XPQ=<K\=(A4
+MZ5*&)2N.+*GQJ=6K6+-J_0E/7KI[Y>AM'4NVK-FS:-.J7<NVK=NW5E^!0R6J
+ME#BX>!V2O)C1:,<:'_V*-!J5Y,F4*UO2C(DSA@P;CF_FS$OY8="A12LV';MY
+K:^&I)*M6'DT::]>O84NK7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,K!```
+`
+end
diff --git a/libarchive/test/test_read_format_ustar_filename_eucjp.tar.Z.uu b/libarchive/test/test_read_format_ustar_filename_eucjp.tar.Z.uu
new file mode 100644
index 000000000000..c6ab11043978
--- /dev/null
+++ b/libarchive/test/test_read_format_ustar_filename_eucjp.tar.Z.uu
@@ -0,0 +1,9 @@
+begin 644 test_read_format_ustar_filename_eucjp.tar.Z
+M'YV0M(+MTN>"#AXZ`!(J7,BPH<.'$"-*G$@1`(R+-FC0`&$11HP;-6)PO/@Q
+MY,B+*%'&@`$B1HP:(6O(D"&3I4<9-V;$```"1L6?0(,*'0J@SAPZ8>1T'%.G
+M#%&(3)T^=9CRXLF4'*=JW<JUJU>BBGXYTB0HE2!D7].J7<NVK=NW<./*G4NW
+M[M-DO0H>M,L7(LJ,&SN6%"D8).&J53>ZA/ER9LV>,63`N.&S9]_+$HTB57HQ
+M:EK/7Q%?19D5L^G37-FD.8JZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'T[<
+!(0``
+`
+end
diff --git a/libarchive/test/test_read_format_ustar_filename_koi8r.tar.Z.uu b/libarchive/test/test_read_format_ustar_filename_koi8r.tar.Z.uu
new file mode 100644
index 000000000000..15e0d6316307
--- /dev/null
+++ b/libarchive/test/test_read_format_ustar_filename_koi8r.tar.Z.uu
@@ -0,0 +1,8 @@
+begin 644 test_read_format_ustar_filename_koi8r.tar.Z
+M'YV0T*0ENU:,&H"#"!,J7,BPH<.'$"-*1`BCXHT:-4``J!CC8@R-'#V"K$BR
+MI`T0,6+4H'%CAHR*,T["B#'#(@`0,";JW,FSIT\`=>;0"2-G(XPQ=<K\=(A4
+MZ5*&)2N.+*GQJ=6K6+-J_0E/7KI[Y>AM'4NVK-FS:-.J7<NVK=NW5KM^#0NW
+MKD.2%S,:[5CCXUZ11J.2/)ER9<N7,&+BI%GSQLV<=B,_##JT:,6F8S%O%3R5
+G9%7)H$-CE0M6K.C3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^^$
+`
+end
diff --git a/libarchive/test/test_read_format_xar.c b/libarchive/test/test_read_format_xar.c
index a69667760819..4dc55c21d7e0 100644
--- a/libarchive/test/test_read_format_xar.c
+++ b/libarchive/test/test_read_format_xar.c
@@ -83,7 +83,7 @@ static void verify0(struct archive *a, struct archive_entry *ae)
{
const void *p;
size_t size;
- off_t offset;
+ int64_t offset;
assert(archive_entry_filetype(ae) == AE_IFREG);
assertEqualInt(archive_entry_mode(ae) & 0777, 0644);
@@ -99,7 +99,7 @@ static void verify0(struct archive *a, struct archive_entry *ae)
assertEqualInt(archive_read_data_block(a, &p, &size, &offset), 0);
assertEqualInt((int)size, 16);
assertEqualInt((int)offset, 0);
- assertEqualInt(memcmp(p, "hellohellohello\n", 16), 0);
+ assertEqualMem(p, "hellohellohello\n", 16);
}
static void verify1(struct archive *a, struct archive_entry *ae)
@@ -634,9 +634,9 @@ static void verify(unsigned char *d, size_t s,
case BZIP2:
/* This is only check whether bzip is supported or not.
* This filter won't be used this test. */
- if (ARCHIVE_OK != archive_read_support_compression_bzip2(a)) {
+ if (ARCHIVE_OK != archive_read_support_filter_bzip2(a)) {
skipping("Unsupported bzip2");
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
return;
}
break;
@@ -645,11 +645,11 @@ static void verify(unsigned char *d, size_t s,
* will return a warning if gzip is unsupported. */
break;
}
- assertA(0 == archive_read_support_compression_all(a));
+ assertA(0 == archive_read_support_filter_all(a));
r = archive_read_support_format_xar(a);
if (r == ARCHIVE_WARN) {
skipping("xar reading not fully supported on this platform");
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
return;
}
assert((buff = malloc(100000)) != NULL);
@@ -671,12 +671,15 @@ static void verify(unsigned char *d, size_t s,
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_XAR);
/* Verify the only entry. */
f2(a, ae);
+ assertEqualInt(2, archive_file_count(a));
+ } else {
+ assertEqualInt(1, archive_file_count(a));
}
/* End of archive. */
assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae));
- assertA(0 == archive_read_close(a));
- assertA(0 == archive_read_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
free(buff);
}
diff --git a/libarchive/test/test_read_format_zip.c b/libarchive/test/test_read_format_zip.c
index 680e7ede360f..8c8c92ae4545 100644
--- a/libarchive/test/test_read_format_zip.c
+++ b/libarchive/test/test_read_format_zip.c
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2011 Michihiro NAKAJIMA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,68 +26,274 @@
#include "test.h"
__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_zip.c 189482 2009-03-07 03:30:35Z kientzle $");
+#ifdef HAVE_LIBZ
+static const int libz_enabled = 1;
+#else
+static const int libz_enabled = 0;
+#endif
+
/*
* The reference file for this has been manually tweaked so that:
* * file2 has length-at-end but file1 does not
* * file2 has an invalid CRC
*/
-
-DEFINE_TEST(test_read_format_zip)
+static void
+verify_basic(struct archive *a, int seek_checks)
{
- const char *refname = "test_read_format_zip.zip";
struct archive_entry *ae;
- struct archive *a;
char *buff[128];
const void *pv;
size_t s;
- off_t o;
- int r;
+ int64_t o;
- extract_reference_file(refname);
- assert((a = archive_read_new()) != NULL);
- assertA(0 == archive_read_support_compression_all(a));
- assertA(0 == archive_read_support_format_all(a));
- assertA(0 == archive_read_open_filename(a, refname, 10240));
- assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualString("dir/", archive_entry_pathname(ae));
assertEqualInt(1179604249, archive_entry_mtime(ae));
assertEqualInt(0, archive_entry_size(ae));
+ if (seek_checks)
+ assertEqualInt(AE_IFDIR | 0755, archive_entry_mode(ae));
assertEqualIntA(a, ARCHIVE_EOF,
archive_read_data_block(a, &pv, &s, &o));
assertEqualInt((int)s, 0);
- assertA(0 == archive_read_next_header(a, &ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualString("file1", archive_entry_pathname(ae));
assertEqualInt(1179604289, archive_entry_mtime(ae));
+ if (seek_checks)
+ assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae));
assertEqualInt(18, archive_entry_size(ae));
failure("archive_read_data() returns number of bytes read");
- r = archive_read_data(a, buff, 19);
- if (r < ARCHIVE_OK) {
- if (strcmp(archive_error_string(a),
- "libarchive compiled without deflate support (no libz)") == 0) {
- skipping("Skipping ZIP compression check: %s",
- archive_error_string(a));
- goto finish;
- }
+ if (libz_enabled) {
+ assertEqualInt(18, archive_read_data(a, buff, 19));
+ assertEqualMem(buff, "hello\nhello\nhello\n", 18);
+ } else {
+ assertEqualInt(ARCHIVE_FAILED, archive_read_data(a, buff, 19));
+ assertEqualString(archive_error_string(a),
+ "Unsupported ZIP compression method (deflation)");
+ assert(archive_errno(a) != 0);
}
- assertEqualInt(18, r);
- assert(0 == memcmp(buff, "hello\nhello\nhello\n", 18));
- assertA(0 == archive_read_next_header(a, &ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualString("file2", archive_entry_pathname(ae));
assertEqualInt(1179605932, archive_entry_mtime(ae));
- failure("file2 has length-at-end, so we shouldn't see a valid size");
- assertEqualInt(0, archive_entry_size_is_set(ae));
- failure("file2 has a bad CRC, so reading to end should fail");
- assertEqualInt(ARCHIVE_WARN, archive_read_data(a, buff, 19));
- assert(0 == memcmp(buff, "hello\nhello\nhello\n", 18));
- assertA(archive_compression(a) == ARCHIVE_COMPRESSION_NONE);
- assertA(archive_format(a) == ARCHIVE_FORMAT_ZIP);
- assert(0 == archive_read_close(a));
-finish:
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assert(0 == archive_read_finish(a));
-#endif
+ if (seek_checks) {
+ assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae));
+ assertEqualInt(64, archive_entry_size_is_set(ae));
+ } else {
+ failure("file2 has length-at-end, so we shouldn't see a valid size when streaming");
+ assertEqualInt(0, archive_entry_size_is_set(ae));
+ }
+ if (libz_enabled) {
+ failure("file2 has a bad CRC, so read should fail and not change buff");
+ memset(buff, 'a', 19);
+ assertEqualInt(ARCHIVE_WARN, archive_read_data(a, buff, 19));
+ assertEqualMem(buff, "aaaaaaaaaaaaaaaaaaa", 19);
+ } else {
+ assertEqualInt(ARCHIVE_FAILED, archive_read_data(a, buff, 19));
+ assertEqualString(archive_error_string(a),
+ "Unsupported ZIP compression method (deflation)");
+ assert(archive_errno(a) != 0);
+ }
+ assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae));
+ /* Verify the number of files read. */
+ failure("the archive file has three files");
+ assertEqualInt(3, archive_file_count(a));
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_basic(void)
+{
+ const char *refname = "test_read_format_zip.zip";
+ struct archive *a;
+ char *p;
+ size_t s;
+
+ extract_reference_file(refname);
+
+ /* Verify with seeking reader. */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240));
+ verify_basic(a, 1);
+
+ /* Verify with streaming reader. */
+ p = slurpfile(&s, refname);
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 31));
+ verify_basic(a, 0);
+}
+
+/*
+ * Read Info-ZIP New Unix Extra Field 0x7875 "ux".
+ * Currently stores Unix UID/GID up to 32 bits.
+ */
+static void
+verify_info_zip_ux(struct archive *a, int seek_checks)
+{
+ struct archive_entry *ae;
+ char *buff[128];
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("file1", archive_entry_pathname(ae));
+ assertEqualInt(1300668680, archive_entry_mtime(ae));
+ assertEqualInt(18, archive_entry_size(ae));
+ if (seek_checks)
+ assertEqualInt(AE_IFREG | 0644, archive_entry_mode(ae));
+ failure("zip reader should read Info-ZIP New Unix Extra Field");
+ assertEqualInt(1001, archive_entry_uid(ae));
+ assertEqualInt(1001, archive_entry_gid(ae));
+ if (libz_enabled) {
+ failure("archive_read_data() returns number of bytes read");
+ assertEqualInt(18, archive_read_data(a, buff, 19));
+ assertEqualMem(buff, "hello\nhello\nhello\n", 18);
+ } else {
+ assertEqualInt(ARCHIVE_FAILED, archive_read_data(a, buff, 19));
+ assertEqualString(archive_error_string(a),
+ "Unsupported ZIP compression method (deflation)");
+ assert(archive_errno(a) != 0);
+ }
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify the number of files read. */
+ failure("the archive file has just one file");
+ assertEqualInt(1, archive_file_count(a));
+
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_info_zip_ux(void)
+{
+ const char *refname = "test_read_format_zip_ux.zip";
+ struct archive *a;
+ char *p;
+ size_t s;
+
+ extract_reference_file(refname);
+
+ /* Verify with seeking reader. */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240));
+ verify_info_zip_ux(a, 1);
+
+ /* Verify with streaming reader. */
+ p = slurpfile(&s, refname);
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 108));
+ verify_info_zip_ux(a, 0);
}
+/*
+ * Verify that test_read_extract correctly works with
+ * Zip entries that use length-at-end.
+ */
+static void
+verify_extract_length_at_end(struct archive *a, int seek_checks)
+{
+ struct archive_entry *ae;
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+
+ assertEqualString("hello.txt", archive_entry_pathname(ae));
+ if (seek_checks) {
+ assertEqualInt(AE_IFREG | 0644, archive_entry_mode(ae));
+ assert(archive_entry_size_is_set(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+ } else {
+ assert(!archive_entry_size_is_set(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ }
+
+ if (libz_enabled) {
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_extract(a, ae, 0));
+ assertFileContents("hello\x0A", 6, "hello.txt");
+ } else {
+ assertEqualIntA(a, ARCHIVE_FAILED, archive_read_extract(a, ae, 0));
+ assertEqualString(archive_error_string(a),
+ "Unsupported ZIP compression method (deflation)");
+ assert(archive_errno(a) != 0);
+ }
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_extract_length_at_end(void)
+{
+ const char *refname = "test_read_format_zip_length_at_end.zip";
+ char *p;
+ size_t s;
+ struct archive *a;
+
+ extract_reference_file(refname);
+ /* Verify extraction with seeking reader. */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240));
+ verify_extract_length_at_end(a, 1);
+
+ /* Verify extraction with streaming reader. */
+ p = slurpfile(&s, refname);
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 108));
+ verify_extract_length_at_end(a, 0);
+}
+
+static void
+test_symlink(void)
+{
+ const char *refname = "test_read_format_zip_symlink.zip";
+ char *p;
+ size_t s;
+ struct archive *a;
+ struct archive_entry *ae;
+
+ extract_reference_file(refname);
+ p = slurpfile(&s, refname);
+
+ /* Symlinks can only be extracted with the seeking reader. */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
+ assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, p, s, 1));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("file", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("symlink", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFLNK, archive_entry_filetype(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualString("file", archive_entry_symlink(ae));
+
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
+}
+
+DEFINE_TEST(test_read_format_zip)
+{
+ test_basic();
+ test_info_zip_ux();
+ test_extract_length_at_end();
+ test_symlink();
+}
diff --git a/libarchive/test/test_read_format_zip.zip.uu b/libarchive/test/test_read_format_zip.zip.uu
index b1f04c4fea00..4fb534833f85 100644
--- a/libarchive/test/test_read_format_zip.zip.uu
+++ b/libarchive/test/test_read_format_zip.zip.uu
@@ -1,4 +1,3 @@
-$FreeBSD: src/lib/libarchive/test/test_read_format_zip.zip.uu,v 1.3 2008/10/21 05:08:35 kientzle Exp $
begin 644 test_read_format_zip.zip
M4$L#!`H`"````%EFLS8````````````````$`!4`9&ER+U54"0`#&55/1M19
M_4A5>`0`Z`/H`U!+!P@```````````````!02P,$%`````@`;V:S-CHW9CT*
@@ -8,7 +7,7 @@ M1L!9_4A5>`0`Z`/H`\M(S<G)Y\I`(@%02P<(.C=F$@H````2````4$L!`A<#
M"@`(````66:S-@````````````````0`#0`````````0`.U!`````&1I<B]5
M5`4``QE53T95>```4$L!`A<#%``(``@`;V:S-CHW9CT*````$@````4`#0``
M`````0```.V!1P```&9I;&4Q550%``-!54]&57@``%!+`0(7`Q0`"``(`%IJ
-MLS8Z-V8]"@```!(````%``T```````$```#M@8D```!F:6QE,E54!0`#K%M/
+MLS9X>'AX"@```!(````%``T```````$```#M@8D```!F:6QE,E54!0`#K%M/
;1E5X``!02P4&``````,``P"_````VP``````
`
end
diff --git a/libarchive/test/test_read_format_zip_filename.c b/libarchive/test/test_read_format_zip_filename.c
new file mode 100644
index 000000000000..701fe05e8300
--- /dev/null
+++ b/libarchive/test/test_read_format_zip_filename.c
@@ -0,0 +1,1162 @@
+/*-
+ * Copyright (c) 2011 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD");
+
+#include <locale.h>
+
+static void
+test_read_format_zip_filename_CP932_eucJP(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read CP932 filename in ja_JP.eucJP with "hdrcharset=CP932" option.
+ */
+ if (NULL == setlocale(LC_ALL, "ja_JP.eucJP")) {
+ skipping("ja_JP.eucJP locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP932")) {
+ skipping("This system cannot convert character-set"
+ " from CP932 to eucJP.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(
+ "\xc9\xbd\xa4\xc0\xa4\xe8\x2f\xb0\xec\xcd\xf7\xc9\xbd\x2e\x74\x78\x74",
+ archive_entry_pathname(ae));
+ assertEqualInt(5, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(
+ "\xc9\xbd\xa4\xc0\xa4\xe8\x2f\xb4\xc1\xbb\xfa\x2e\x74\x78\x74",
+ archive_entry_pathname(ae));
+ assertEqualInt(5, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_zip_filename_CP932_UTF8(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read CP932 filename in en_US.UTF-8 with "hdrcharset=CP932" option.
+ */
+ if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
+ skipping("en_US.UTF-8 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP932")) {
+ skipping("This system cannot convert character-set"
+ " from CP932 to UTF-8.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+#if defined(__APPLE__)
+ /* Compare NFD string. */
+ assertEqualUTF8String(
+ "\xe8\xa1\xa8\xe3\x81\x9f\xe3\x82\x99\xe3\x82\x88\x2f"
+ "\xe4\xb8\x80\xe8\xa6\xa7\xe8\xa1\xa8\x2e\x74\x78\x74",
+ archive_entry_pathname(ae));
+#else
+ /* Compare NFC string. */
+ assertEqualUTF8String(
+ "\xe8\xa1\xa8\xe3\x81\xa0\xe3\x82\x88\x2f"
+ "\xe4\xb8\x80\xe8\xa6\xa7\xe8\xa1\xa8\x2e\x74\x78\x74",
+ archive_entry_pathname(ae));
+#endif
+ assertEqualInt(5, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+#if defined(__APPLE__)
+ /* Compare NFD string. */
+ assertEqualUTF8String(
+ "\xe8\xa1\xa8\xe3\x81\x9f\xe3\x82\x99\xe3\x82\x88\x2f"
+ "\xe6\xbc\xa2\xe5\xad\x97\x2e\x74\x78\x74",
+ archive_entry_pathname(ae));
+#else
+ /* Compare NFC string. */
+ assertEqualUTF8String(
+ "\xe8\xa1\xa8\xe3\x81\xa0\xe3\x82\x88\x2f"
+ "\xe6\xbc\xa2\xe5\xad\x97\x2e\x74\x78\x74",
+ archive_entry_pathname(ae));
+#endif
+ assertEqualInt(5, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_zip_filename_UTF8_eucJP(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read UTF-8 filename in ja_JP.eucJP without charset option
+ * because the file name in the sample file is UTF-8 and
+ * Bit 11 of its general purpose bit flag is set.
+ */
+ if (NULL == setlocale(LC_ALL, "ja_JP.eucJP")) {
+ skipping("ja_JP.eucJP locale not availablefilename_ on this system.");
+ return;
+ }
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=UTF-8")) {
+ skipping("This system cannot convert character-set"
+ " from UTF-8 to eucJP.");
+ goto cleanup;
+ }
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify directory file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
+ assertEqualString("\xc9\xbd\xa4\xc0\xa4\xe8\x2f",
+ archive_entry_pathname(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualString(
+ "\xc9\xbd\xa4\xc0\xa4\xe8\x2f\xb0\xec\xcd\xf7\xc9\xbd\x2e\x74\x78\x74",
+ archive_entry_pathname(ae));
+ assertEqualInt(5, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualString(
+ "\xc9\xbd\xa4\xc0\xa4\xe8\x2f\xb4\xc1\xbb\xfa\x2e\x74\x78\x74",
+ archive_entry_pathname(ae));
+ assertEqualInt(5, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_zip_filename_UTF8_UTF8(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read UTF-8 filename in en_US.UTF-8 without charset option
+ * because the file name in the sample file is UTF-8 and
+ * Bit 11 of its general purpose bit flag is set.
+ */
+ if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
+ skipping("en_US.UTF-8 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify directory file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
+#if defined(__APPLE__)
+ /* Compare NFD string. */
+ assertEqualUTF8String(
+ "\xe8\xa1\xa8\xe3\x81\x9f\xe3\x82\x99\xe3\x82\x88\x2f",
+ archive_entry_pathname(ae));
+#else
+ /* Compare NFC string. */
+ assertEqualUTF8String(
+ "\xe8\xa1\xa8\xe3\x81\xa0\xe3\x82\x88\x2f",
+ archive_entry_pathname(ae));
+#endif
+ assertEqualInt(0, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+#if defined(__APPLE__)
+ /* Compare NFD string. */
+ assertEqualUTF8String(
+ "\xe8\xa1\xa8\xe3\x81\x9f\xe3\x82\x99\xe3\x82\x88\x2f"
+ "\xe4\xb8\x80\xe8\xa6\xa7\xe8\xa1\xa8\x2e\x74\x78\x74",
+ archive_entry_pathname(ae));
+#else
+ /* Compare NFC string. */
+ assertEqualUTF8String(
+ "\xe8\xa1\xa8\xe3\x81\xa0\xe3\x82\x88\x2f"
+ "\xe4\xb8\x80\xe8\xa6\xa7\xe8\xa1\xa8\x2e\x74\x78\x74",
+ archive_entry_pathname(ae));
+#endif
+ assertEqualInt(5, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+#if defined(__APPLE__)
+ /* Compare NFD string. */
+ assertEqualUTF8String(
+ "\xe8\xa1\xa8\xe3\x81\x9f\xe3\x82\x99\xe3\x82\x88\x2f"
+ "\xe6\xbc\xa2\xe5\xad\x97\x2e\x74\x78\x74",
+ archive_entry_pathname(ae));
+#else
+ /* Compare NFC string. */
+ assertEqualUTF8String(
+ "\xe8\xa1\xa8\xe3\x81\xa0\xe3\x82\x88\x2f"
+ "\xe6\xbc\xa2\xe5\xad\x97\x2e\x74\x78\x74",
+ archive_entry_pathname(ae));
+#endif
+ assertEqualInt(5, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_zip_filename_CP866_KOI8R(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read CP866 filename in ru_RU.KOI8-R with "hdrcharset=CP866" option.
+ */
+ if (NULL == setlocale(LC_ALL, "Russian_Russia.20866") &&
+ NULL == setlocale(LC_ALL, "ru_RU.KOI8-R")) {
+ skipping("ru_RU.KOI8-R locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP866")) {
+ skipping("This system cannot convert character-set"
+ " from CP866 to KOI8-R.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xf0\xf2\xe9\xf7\xe5\xf4",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xd0\xd2\xc9\xd7\xc5\xd4",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_zip_filename_CP866_UTF8(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read CP866 filename in en_US.UTF-8 with "hdrcharset=CP866" option.
+ */
+ if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
+ skipping("en_US.UTF-8 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP866")) {
+ skipping("This system cannot convert character-set"
+ " from CP866 to UTF-8.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xd0\x9f\xd0\xa0\xd0\x98\xd0\x92\xd0\x95\xd0\xa2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_zip_filename_KOI8R_CP866(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read KOI8-R filename in ru_RU.CP866 with "hdrcharset=KOI8-R" option.
+ */
+ if (NULL == setlocale(LC_ALL, "Russian_Russia.866") &&
+ NULL == setlocale(LC_ALL, "ru_RU.CP866")) {
+ skipping("ru_RU.CP866 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) {
+ skipping("This system cannot convert character-set"
+ " from KOI8-R to CP866.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xaf\xe0\xa8\xa2\xa5\xe2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\x8f\x90\x88\x82\x85\x92",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_zip_filename_KOI8R_UTF8(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read KOI8-R filename in en_US.UTF-8 with "hdrcharset=KOI8-R" option.
+ */
+ if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
+ skipping("en_US.UTF-8 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) {
+ skipping("This system cannot convert character-set"
+ " from KOI8-R to UTF-8.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xd0\x9f\xd0\xa0\xd0\x98\xd0\x92\xd0\x95\xd0\xa2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_zip_filename_UTF8_KOI8R(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read UTF-8 filename in ru_RU.KOI8-R with "hdrcharset=UTF-8" option.
+ */
+ if (NULL == setlocale(LC_ALL, "Russian_Russia.20866") &&
+ NULL == setlocale(LC_ALL, "ru_RU.KOI8-R")) {
+ skipping("ru_RU.KOI8-R locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=UTF-8")) {
+ skipping("This system cannot convert character-set"
+ " from UTF-8 to KOI8-R.");
+ goto cleanup;
+ }
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+ /* Re-create a read archive object. */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xf0\xf2\xe9\xf7\xe5\xf4",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xd0\xd2\xc9\xd7\xc5\xd4",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_zip_filename_UTF8_CP866(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read UTF-8 filename in ru_RU.CP866 without charset option
+ * because the file name in the sample file is UTF-8 and
+ * Bit 11 of its general purpose bit flag is set.
+ */
+ if (NULL == setlocale(LC_ALL, "Russian_Russia.866") &&
+ NULL == setlocale(LC_ALL, "ru_RU.CP866")) {
+ skipping("ru_RU.CP866 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=UTF-8")) {
+ skipping("This system cannot convert character-set"
+ " from UTF-8 to CP866.");
+ goto cleanup;
+ }
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+ /* Re-create a read archive object. */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\x8f\x90\x88\x82\x85\x92",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xaf\xe0\xa8\xa2\xa5\xe2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_zip_filename_UTF8_UTF8_ru(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read UTF-8 filename in en_US.UTF-8 without charset option
+ * because the file name in the sample file is UTF-8 and
+ * Bit 11 of its general purpose bit flag is set.
+ */
+ if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
+ skipping("en_US.UTF-8 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xd0\x9f\xd0\xa0\xd0\x98\xd0\x92\xd0\x95\xd0\xa2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_zip_filename_CP932_CP932(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read CP932 filename in CP932/SJIS with "hdrcharset=CP932" option.
+ */
+ if (NULL == setlocale(LC_ALL, "Japanese_Japan") &&
+ NULL == setlocale(LC_ALL, "ja_JP.SJIS")) {
+ skipping("CP932 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP932")) {
+ skipping("This system cannot convert character-set"
+ " from CP932.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(
+ "\x95\x5c\x82\xbe\x82\xe6\x2f\x88\xea\x97\x97\x95\x5c.txt",
+ archive_entry_pathname(ae));
+ assertEqualInt(5, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(
+ "\x95\x5c\x82\xbe\x82\xe6\x2f\x8a\xbf\x8e\x9a.txt",
+ archive_entry_pathname(ae));
+ assertEqualInt(5, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_zip_filename_UTF8_CP932(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read UTF-8 filename in CP932/SJIS without charset option
+ * because the file name in the sample file is UTF-8 and
+ * Bit 11 of its general purpose bit flag is set.
+ */
+ if (NULL == setlocale(LC_ALL, "Japanese_Japan") &&
+ NULL == setlocale(LC_ALL, "ja_JP.SJIS")) {
+ skipping("CP932 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=UTF-8")) {
+ skipping("This system cannot convert character-set"
+ " from UTF-8 to CP932.");
+ goto cleanup;
+ }
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+ /* Re-create a read archive object. */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
+ assertEqualString(
+ "\x95\x5c\x82\xbe\x82\xe6\x2f",
+ archive_entry_pathname(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+
+ /* Verify directory file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualString(
+ "\x95\x5c\x82\xbe\x82\xe6\x2f\x88\xea\x97\x97\x95\x5c.txt",
+ archive_entry_pathname(ae));
+ assertEqualInt(5, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualString(
+ "\x95\x5c\x82\xbe\x82\xe6\x2f\x8a\xbf\x8e\x9a.txt",
+ archive_entry_pathname(ae));
+ assertEqualInt(5, archive_entry_size(ae));
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_zip_filename_CP866_CP1251(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read CP866 filename in CP1251 with "hdrcharset=CP866" option.
+ */
+ if (NULL == setlocale(LC_ALL, "Russian_Russia") &&
+ NULL == setlocale(LC_ALL, "ru_RU.CP1251")) {
+ skipping("CP1251 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP866")) {
+ skipping("This system cannot convert character-set"
+ " from CP866 to CP1251.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xcf\xd0\xc8\xc2\xc5\xd2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+/*
+ * This test only for Windows platform because other archiver
+ * applications on Windows translate CP1251 filenames into CP866
+ * filenames and store it in the zip file and so we should read
+ * it by default on Windows.
+ */
+static void
+test_read_format_zip_filename_CP866_CP1251_win(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read CP866 filename in CP1251 without "hdrcharset=CP866" option.
+ */
+ if (NULL == setlocale(LC_ALL, "Russian_Russia")) {
+ skipping("Russian_Russia locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xcf\xd0\xc8\xc2\xc5\xd2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_zip_filename_KOI8R_CP1251(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read KOI8-R filename in CP1251 with "hdrcharset=KOI8-R" option.
+ */
+ if (NULL == setlocale(LC_ALL, "Russian_Russia") &&
+ NULL == setlocale(LC_ALL, "ru_RU.CP1251")) {
+ skipping("CP1251 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) {
+ skipping("This system cannot convert character-set"
+ " from KOI8-R to CP1251.");
+ goto cleanup;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xcf\xd0\xc8\xc2\xc5\xd2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+static void
+test_read_format_zip_filename_UTF8_CP1251(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read UTF-8 filename in CP1251 without charset option
+ * because the file name in the sample file is UTF-8 and
+ * Bit 11 of its general purpose bit flag is set.
+ */
+ if (NULL == setlocale(LC_ALL, "Russian_Russia") &&
+ NULL == setlocale(LC_ALL, "ru_RU.CP1251")) {
+ skipping("CP1251 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=UTF-8")) {
+ skipping("This system cannot convert character-set"
+ " from UTF-8 to CP1251.");
+ goto cleanup;
+ }
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+ /* Re-create a read archive object. */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xcf\xd0\xc8\xc2\xc5\xd2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+cleanup:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+/*
+ * The sample zip file was made in LANG=KOI8-R and it contains two
+ * files the charset of which are different.
+ * - the filename of first file is stored in KOI8-R.
+ * - the filename of second file is stored in UTF-8.
+ *
+ * Whenever hdrcharset option is specified, we will correctly read the
+ * filename of sencod file, which is stored in UTF-8.
+ */
+
+static void
+test_read_format_zip_filename_KOI8R_UTF8_2(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+
+ /*
+ * Read filename in en_US.UTF-8 with "hdrcharset=KOI8-R" option.
+ */
+ if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
+ skipping("en_US.UTF-8 locale not available on this system.");
+ return;
+ }
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) {
+ skipping("This system cannot convert character-set"
+ " from KOI8-R to UTF-8.");
+ goto next_test;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular first file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xd0\x9f\xd0\xa0\xd0\x98\xd0\x92\xd0\x95\xd0\xa2",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /*
+ * Verify regular second file.
+ * The filename is not translated because Bit 11 of its general
+ * purpose bit flag is set and so we know the conversion is unneeded.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+next_test:
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+ /*
+ * Read filename in en_US.UTF-8 without "hdrcharset=KOI8-R" option.
+ * The filename we can properly read is only second file.
+ */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /*
+ * Verify regular first file.
+ * The filename is not translated to UTF-8 because Bit 11 of
+ * its general purpose bit flag is *not* set and so there is
+ * not way to know its charset.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ /* A filename is in KOI8-R. */
+ assertEqualString("\xf0\xf2\xe9\xf7\xe5\xf4",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+ /* Verify regular file. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82",
+ archive_entry_pathname(ae));
+ assertEqualInt(6, archive_entry_size(ae));
+
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+DEFINE_TEST(test_read_format_zip_filename)
+{
+ const char *refname1 = "test_read_format_zip_filename_cp932.zip";
+ const char *refname2 = "test_read_format_zip_filename_utf8_jp.zip";
+ const char *refname3 = "test_read_format_zip_filename_cp866.zip";
+ const char *refname4 = "test_read_format_zip_filename_koi8r.zip";
+ const char *refname5 = "test_read_format_zip_filename_utf8_ru.zip";
+ const char *refname6 = "test_read_format_zip_filename_utf8_ru2.zip";
+
+ extract_reference_file(refname1);
+ test_read_format_zip_filename_CP932_eucJP(refname1);
+ test_read_format_zip_filename_CP932_UTF8(refname1);
+ test_read_format_zip_filename_CP932_CP932(refname1);
+
+ extract_reference_file(refname2);
+ test_read_format_zip_filename_UTF8_eucJP(refname2);
+ test_read_format_zip_filename_UTF8_UTF8(refname2);
+ test_read_format_zip_filename_UTF8_CP932(refname2);
+
+ extract_reference_file(refname3);
+ test_read_format_zip_filename_CP866_KOI8R(refname3);
+ test_read_format_zip_filename_CP866_UTF8(refname3);
+ test_read_format_zip_filename_CP866_CP1251(refname3);
+ test_read_format_zip_filename_CP866_CP1251_win(refname3);
+
+ extract_reference_file(refname4);
+ test_read_format_zip_filename_KOI8R_CP866(refname4);
+ test_read_format_zip_filename_KOI8R_UTF8(refname4);
+ test_read_format_zip_filename_KOI8R_CP1251(refname4);
+
+ extract_reference_file(refname5);
+ test_read_format_zip_filename_UTF8_KOI8R(refname5);
+ test_read_format_zip_filename_UTF8_CP866(refname5);
+ test_read_format_zip_filename_UTF8_UTF8_ru(refname5);
+ test_read_format_zip_filename_UTF8_CP1251(refname5);
+
+ /* The filenames contained in refname6 are different charset. */
+ extract_reference_file(refname6);
+ test_read_format_zip_filename_KOI8R_UTF8_2(refname6);
+}
diff --git a/libarchive/test/test_read_format_zip_filename_cp866.zip.uu b/libarchive/test/test_read_format_zip_filename_cp866.zip.uu
new file mode 100644
index 000000000000..52c6770609e1
--- /dev/null
+++ b/libarchive/test/test_read_format_zip_filename_cp866.zip.uu
@@ -0,0 +1,10 @@
+begin 644 test_read_format_zip_cp866.zip
+M4$L#!`H``````%VEAS[,X8$4!@````8````&`!P`CY"(@H62550)``-!HYU-
+M0:.=375X"P`!!.D#```$Z0,``/#RZ??E]%!+`P0*``````!=I8<^S.&!%`8`
+M```&````!@`<`*_@J**EXE54"0`#0:.=34&CG4UU>`L``03I`P``!.D#``#P
+M\NGWY?102P$"'@,*``````!=I8<^S.&!%`8````&````!@`8```````!````
+M[8$`````CY"(@H62550%``-!HYU-=7@+``$$Z0,```3I`P``4$L!`AX#"@``
+M````7:6'/LSA@10&````!@````8`&````````0```.V!1@```*_@J**EXE54
+L!0`#0:.=375X"P`!!.D#```$Z0,``%!+!08``````@`"`)@```",````````
+`
+end
diff --git a/libarchive/test/test_read_format_zip_filename_cp932.zip.uu b/libarchive/test/test_read_format_zip_filename_cp932.zip.uu
new file mode 100644
index 000000000000..90c22f2d5c45
--- /dev/null
+++ b/libarchive/test/test_read_format_zip_filename_cp932.zip.uu
@@ -0,0 +1,9 @@
+begin 644 test_read_format_zip_cp932.zip
+M4$L#!`H``````/94=#Z"B='W!0````4````1````E5R"OH+F+XCJEY>57"YT
+M>'1(96QL;U!+`P0*``````"W5'0^W)UO0@4````%````#P```)5<@KZ"YB^*
+MOXZ:+G1X=&MA;FII4$L!`A0+"@``````]E1T/H*)T?<%````!0```!$`````
+M`````0`@`````````)5<@KZ"YB^(ZI>7E5PN='AT4$L!`A0+"@``````MU1T
+M/MR=;T(%````!0````\``````````0`@````-````)5<@KZ"YB^*OXZ:+G1X
+7=%!+!08``````@`"`'P```!F````````
+`
+end
diff --git a/libarchive/test/test_read_format_zip_filename_koi8r.zip.uu b/libarchive/test/test_read_format_zip_filename_koi8r.zip.uu
new file mode 100644
index 000000000000..05c669560270
--- /dev/null
+++ b/libarchive/test/test_read_format_zip_filename_koi8r.zip.uu
@@ -0,0 +1,10 @@
+begin 644 test_read_format_zip_koi8r.zip
+M4$L#!`H``````+&CAS[,X8$4!@````8````&`!P`T-+)U\74550)``,>H)U-
+M'J"=375X"P`!!.D#```$Z0,``/#RZ??E]%!+`P0*``````"QHX<^S.&!%`8`
+M```&````!@`<`/#RZ??E]%54"0`#'J"=31Z@G4UU>`L``03I`P``!.D#``#P
+M\NGWY?102P$"'@,*``````"QHX<^S.&!%`8````&````!@`8```````!````
+M[8$`````T-+)U\74550%``,>H)U-=7@+``$$Z0,```3I`P``4$L!`AX#"@``
+M````L:.'/LSA@10&````!@````8`&````````0```.V!1@```/#RZ??E]%54
+L!0`#'J"=375X"P`!!.D#```$Z0,``%!+!08``````@`"`)@```",````````
+`
+end
diff --git a/libarchive/test/test_read_format_zip_filename_utf8_jp.zip.uu b/libarchive/test/test_read_format_zip_filename_utf8_jp.zip.uu
new file mode 100644
index 000000000000..00c2af33723a
--- /dev/null
+++ b/libarchive/test/test_read_format_zip_filename_utf8_jp.zip.uu
@@ -0,0 +1,15 @@
+begin 644 test_read_format_zip_utf8.zip
+M4$L#!`H```@``,E4=#X````````````````*`!P`Z*&HXX&@XX*(+U54"0`#
+MBEJ%3;[UBDUU>`L``03M`P``!`$"``!02P,$"@``"```]51T/H*)T?<%````
+M!0```!<`'`#HH:CC@:#C@H@OY+B`Z*:GZ*&H+G1X=%54"0`#WEJ%31KLBDUU
+M>`L``03M`P``!`$"``!(96QL;U!+`P0*```(``"V5'0^W)UO0@4````%````
+M%``<`.BAJ..!H.."B"_FO*+EK9<N='AT550)``-H6H5-&NR*375X"P`!!.T#
+M```$`0(``&MA;FII4$L!`AX#"@``"```R51T/@````````````````H`&```
+M```````0`.U!`````.BAJ..!H.."B"]55`4``XI:A4UU>`L``03M`P``!`$"
+M``!02P$"'@,*```(``#U5'0^@HG1]P4````%````%P`8```````!````[8%$
+M````Z*&HXX&@XX*(+^2X@.BFI^BAJ"YT>'155`4``]Y:A4UU>`L``03M`P``
+M!`$"``!02P$"'@,*```(``"V5'0^W)UO0@4````%````%``8```````!````
+M[8&:````Z*&HXX&@XX*(+^:\HN6MERYT>'155`4``VA:A4UU>`L``03M`P``
+;!`$"``!02P4&``````,``P`'`0``[0``````
+`
+end
diff --git a/libarchive/test/test_read_format_zip_filename_utf8_ru.zip.uu b/libarchive/test/test_read_format_zip_filename_utf8_ru.zip.uu
new file mode 100644
index 000000000000..9241776d7fdf
--- /dev/null
+++ b/libarchive/test/test_read_format_zip_filename_utf8_ru.zip.uu
@@ -0,0 +1,11 @@
+begin 644 test_read_format_zip_utf8_ru.zip
+M4$L#!`H```@``,NC/S[,X8$4!@````8````,`!P`T)_0H-"8T)+0E="B550)
+M``-.G49-'J"=375X"P`!!.D#```$Z0,``/#RZ??E]%!+`P0*```(``!KI3\^
+MS.&!%`8````&````#``<`-"_T8#0N-"RT+71@E54"0`#6J!&31Z@G4UU>`L`
+M`03I`P``!.D#``#P\NGWY?102P$"'@,*```(``#+HS\^S.&!%`8````&````
+M#``8```````!````[8$`````T)_0H-"8T)+0E="B550%``-.G49-=7@+``$$
+MZ0,```3I`P``4$L!`AX#"@``"```:Z4_/LSA@10&````!@````P`&```````
+M`0```.V!3````-"_T8#0N-"RT+71@E54!0`#6J!&375X"P`!!.D#```$Z0,`
+7`%!+!08``````@`"`*0```"8````````
+`
+end
diff --git a/libarchive/test/test_read_format_zip_filename_utf8_ru2.zip.uu b/libarchive/test/test_read_format_zip_filename_utf8_ru2.zip.uu
new file mode 100644
index 000000000000..651f8b1f8b10
--- /dev/null
+++ b/libarchive/test/test_read_format_zip_filename_utf8_ru2.zip.uu
@@ -0,0 +1,11 @@
+begin 644 test_read_format_zip_utf8_ru2.zip
+M4$L#!`H``````.:PCC[,X8$4!@````8````&`!P`\/+I]^7T550)``.`\:9-
+MI6>G375X"P`!!.D#```$Z0,``/#RZ??E]%!+`P0*```(``!KI3\^S.&!%`8`
+M```&````#``<`-"_T8#0N-"RT+71@E54"0`#6J!&357SIDUU>`L``03I`P``
+M!.D#``#P\NGWY?102P$"'@,*``````#FL(X^S.&!%`8````&````!@`8````
+M```!````[8$`````\/+I]^7T550%``.`\:9-=7@+``$$Z0,```3I`P``4$L!
+M`AX#"@``"```:Z4_/LSA@10&````!@````P`&````````0```.V!1@```-"_
+MT8#0N-"RT+71@E54!0`#6J!&375X"P`!!.D#```$Z0,``%!+!08``````@`"
++`)X```"2````````
+`
+end
diff --git a/libarchive/test/test_read_format_zip_length_at_end.zip.uu b/libarchive/test/test_read_format_zip_length_at_end.zip.uu
new file mode 100644
index 000000000000..41eda31354ec
--- /dev/null
+++ b/libarchive/test/test_read_format_zip_length_at_end.zip.uu
@@ -0,0 +1,8 @@
+begin 644 test_read_format_zip_length_at_end.zip
+M4$L#!!0`"``(`,NJ,C\````````````````)`!P`:&5L;&\N='AT550)``-^
+MPW9.A<-V3G5X"P`!!/4!```$%````,M(S<G)YP(`4$L'""`P.C8(````!@``
+M`%!+`0(>`Q0`"``(`,NJ,C\@,#HV"`````8````)`!@```````$```"D@0``
+M``!H96QL;RYT>'155`4``W[#=DYU>`L``03U`0``!!0```!02P4&``````$`
+,`0!/````6P``````
+`
+end
diff --git a/libarchive/test/test_read_format_zip_symlink.zip.uu b/libarchive/test/test_read_format_zip_symlink.zip.uu
new file mode 100644
index 000000000000..f573565c6cd7
--- /dev/null
+++ b/libarchive/test/test_read_format_zip_symlink.zip.uu
@@ -0,0 +1,10 @@
+begin 644 test_read_format_zip_symlink.zip
+M4$L#!`H``````-BDE3_!B>PO!0````4````$`!P`9FEL9554"0`#6+3R3G>T
+M\DYU>`L``03U`0``!!0```!F:6QE"E!+`P0*``````#<I)4_$#:?C`0````$
+M````!P`<`'-Y;6QI;FM55`D``V"T\DY@M/).=7@+``$$]0$```04````9FEL
+M95!+`0(>`PH``````-BDE3_!B>PO!0````4````$`!@```````$```"D@0``
+M``!F:6QE550%``-8M/).=7@+``$$]0$```04````4$L!`AX#"@``````W*25
+M/Q`VGXP$````!`````<`&````````````.VA0P```'-Y;6QI;FM55`4``V"T
+G\DYU>`L``03U`0``!!0```!02P4&``````(``@"7````B```````
+`
+end
diff --git a/libarchive/test/test_read_format_zip_ux.zip.uu b/libarchive/test/test_read_format_zip_ux.zip.uu
new file mode 100644
index 000000000000..7bfe7966a156
--- /dev/null
+++ b/libarchive/test/test_read_format_zip_ux.zip.uu
@@ -0,0 +1,7 @@
+begin 644 test_read_format_zip_ux.zip
+M4$L#!!0````(`&I.=3XZ-V8]"@```!(````%`!P`9FEL93%55`D``PBAADT4
+MH89-=7@+``$$Z0,```3I`P``RTC-R<GGRD`B`5!+`0(>`Q0````(`&I.=3XZ
+M-V8]"@```!(````%`!@```````$```"D@0````!F:6QE,554!0`#"*&&375X
+C"P`!!.D#```$Z0,``%!+!08``````0`!`$L```!)````````
+`
+end
diff --git a/libarchive/test/test_read_large.c b/libarchive/test/test_read_large.c
index a2be60178655..6966ccbe1916 100644
--- a/libarchive/test/test_read_large.c
+++ b/libarchive/test/test_read_large.c
@@ -58,21 +58,22 @@ DEFINE_TEST(test_read_large)
assertA(0 == archive_write_header(a, entry));
archive_entry_free(entry);
assertA((int)sizeof(testdata) == archive_write_data(a, testdata, sizeof(testdata)));
- assertA(0 == archive_write_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
assert(NULL != (a = archive_read_new()));
assertA(0 == archive_read_support_format_all(a));
- assertA(0 == archive_read_support_compression_all(a));
+ assertA(0 == archive_read_support_filter_all(a));
assertA(0 == archive_read_open_memory(a, buff, sizeof(buff)));
assertA(0 == archive_read_next_header(a, &entry));
- assertA(0 == archive_read_data_into_buffer(a, testdatacopy, sizeof(testdatacopy)));
- assertA(0 == archive_read_finish(a));
- assert(0 == memcmp(testdata, testdatacopy, sizeof(testdata)));
+ assertEqualIntA(a, sizeof(testdatacopy),
+ archive_read_data(a, testdatacopy, sizeof(testdatacopy)));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+ assertEqualMem(testdata, testdatacopy, sizeof(testdata));
assert(NULL != (a = archive_read_new()));
assertA(0 == archive_read_support_format_all(a));
- assertA(0 == archive_read_support_compression_all(a));
+ assertA(0 == archive_read_support_filter_all(a));
assertA(0 == archive_read_open_memory(a, buff, sizeof(buff)));
assertA(0 == archive_read_next_header(a, &entry));
#if defined(__BORLANDC__)
@@ -83,11 +84,11 @@ DEFINE_TEST(test_read_large)
assert(0 < tmpfilefd);
assertA(0 == archive_read_data_into_fd(a, tmpfilefd));
close(tmpfilefd);
- assertA(0 == archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
f = fopen(tmpfilename, "rb");
assertEqualInt(sizeof(testdatacopy),
fread(testdatacopy, 1, sizeof(testdatacopy), f));
fclose(f);
- assert(0 == memcmp(testdata, testdatacopy, sizeof(testdata)));
+ assertEqualMem(testdata, testdatacopy, sizeof(testdata));
}
diff --git a/libarchive/test/test_read_pax_truncated.c b/libarchive/test/test_read_pax_truncated.c
index 4e2a8134ec24..7350c58a185c 100644
--- a/libarchive/test/test_read_pax_truncated.c
+++ b/libarchive/test/test_read_pax_truncated.c
@@ -37,8 +37,8 @@ DEFINE_TEST(test_read_pax_truncated)
/* Create a new archive in memory. */
assert((a = archive_write_new()) != NULL);
- assertA(0 == archive_write_set_format_pax(a));
- assertA(0 == archive_write_set_compression_none(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_pax(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_none(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_write_open_memory(a, buff, buff_size, &used));
@@ -54,27 +54,30 @@ DEFINE_TEST(test_read_pax_truncated)
archive_entry_set_ctime(ae, 3, 4);
archive_entry_set_mtime(ae, 5, 6);
archive_entry_set_size(ae, filedata_size);
- assertA(0 == archive_write_header(a, ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
archive_entry_free(ae);
- assertA((ssize_t)filedata_size
- == archive_write_data(a, filedata, filedata_size));
+ assertEqualIntA(a, (int)filedata_size,
+ (int)archive_write_data(a, filedata, filedata_size));
/* Close out the archive. */
- assertA(0 == archive_write_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_write_finish(a);
-#else
- assertA(0 == archive_write_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/* Now, read back a truncated version of the archive and
* verify that we get an appropriate error. */
for (i = 1; i < used + 100; i += 100) {
assert((a = archive_read_new()) != NULL);
- assertA(0 == archive_read_support_format_all(a));
- assertA(0 == archive_read_support_compression_all(a));
- assertA(0 == read_open_memory2(a, buff, i, 13));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ /* If it's truncated very early, the file type detection should fail. */
+ if (i < 512) {
+ assertEqualIntA(a, ARCHIVE_FATAL, read_open_memory2(a, buff, i, 13));
+ goto wrap_up;
+ } else {
+ assertEqualIntA(a, ARCHIVE_OK, read_open_memory2(a, buff, i, 13));
+ }
+ /* If it's truncated in a header, the header read should fail. */
if (i < 1536) {
assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae));
goto wrap_up;
@@ -83,8 +86,9 @@ DEFINE_TEST(test_read_pax_truncated)
assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
}
+ /* If it's truncated in the body, the body read should fail. */
if (i < 1536 + filedata_size) {
- assertA(ARCHIVE_FATAL == archive_read_data(a, filedata, filedata_size));
+ assertEqualIntA(a, ARCHIVE_FATAL, archive_read_data(a, filedata, filedata_size));
goto wrap_up;
} else {
failure("Archive truncated to %d bytes", i);
@@ -108,12 +112,8 @@ DEFINE_TEST(test_read_pax_truncated)
archive_read_next_header(a, &ae));
}
wrap_up:
- assert(0 == archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assert(0 == archive_read_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
@@ -121,22 +121,28 @@ DEFINE_TEST(test_read_pax_truncated)
/* Same as above, except skip the body instead of reading it. */
for (i = 1; i < used + 100; i += 100) {
assert((a = archive_read_new()) != NULL);
- assertA(0 == archive_read_support_format_all(a));
- assertA(0 == archive_read_support_compression_all(a));
- assertA(0 == read_open_memory(a, buff, i, 7));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ /* If it's truncated very early, file type detection should fail. */
+ if (i < 512) {
+ assertEqualIntA(a, ARCHIVE_FATAL, read_open_memory(a, buff, i, 7));
+ goto wrap_up2;
+ } else {
+ assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, buff, i, 7));
+ }
if (i < 1536) {
- assertA(ARCHIVE_FATAL == archive_read_next_header(a, &ae));
+ assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae));
goto wrap_up2;
} else {
assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
}
if (i < 1536 + 512*((filedata_size+511)/512)) {
- assertA(ARCHIVE_FATAL == archive_read_data_skip(a));
+ assertEqualIntA(a, ARCHIVE_FATAL, archive_read_data_skip(a));
goto wrap_up2;
} else {
- assertA(ARCHIVE_OK == archive_read_data_skip(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a));
}
/* Verify the end of the archive. */
@@ -153,12 +159,8 @@ DEFINE_TEST(test_read_pax_truncated)
archive_read_next_header(a, &ae));
}
wrap_up2:
- assert(0 == archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assert(0 == archive_read_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
/* Now, damage the archive in various ways and test the responses. */
@@ -169,31 +171,23 @@ DEFINE_TEST(test_read_pax_truncated)
buff2[513] = '9';
buff2[514] = 'A'; /* Non-digit in size. */
assert((a = archive_read_new()) != NULL);
- assertA(0 == archive_read_support_format_all(a));
- assertA(0 == archive_read_support_compression_all(a));
- assertA(0 == archive_read_open_memory(a, buff2, used));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff2, used));
assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae));
- assert(0 == archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assert(0 == archive_read_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
/* Damage the size field in the pax attributes. */
memcpy(buff2, buff, buff_size);
buff2[512] = 'A'; /* First character not a digit. */
assert((a = archive_read_new()) != NULL);
- assertA(0 == archive_read_support_format_all(a));
- assertA(0 == archive_read_support_compression_all(a));
- assertA(0 == archive_read_open_memory(a, buff2, used));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff2, used));
assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae));
- assert(0 == archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assert(0 == archive_read_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
/* Damage the size field in the pax attributes. */
memcpy(buff2, buff, buff_size);
@@ -201,16 +195,12 @@ DEFINE_TEST(test_read_pax_truncated)
buff2[i] = '9';
buff2[i] = ' ';
assert((a = archive_read_new()) != NULL);
- assertA(0 == archive_read_support_format_all(a));
- assertA(0 == archive_read_support_compression_all(a));
- assertA(0 == archive_read_open_memory(a, buff2, used));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff2, used));
assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae));
- assert(0 == archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assert(0 == archive_read_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
/* Damage the size field in the pax attributes. */
memcpy(buff2, buff, buff_size);
@@ -219,62 +209,46 @@ DEFINE_TEST(test_read_pax_truncated)
buff2[514] = '9';
buff2[515] = ' ';
assert((a = archive_read_new()) != NULL);
- assertA(0 == archive_read_support_format_all(a));
- assertA(0 == archive_read_support_compression_all(a));
- assertA(0 == archive_read_open_memory(a, buff2, used));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff2, used));
assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae));
- assert(0 == archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assert(0 == archive_read_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
/* Damage the size field in the pax attributes. */
memcpy(buff2, buff, buff_size);
buff2[512] = '1'; /* Too small. */
buff2[513] = ' ';
assert((a = archive_read_new()) != NULL);
- assertA(0 == archive_read_support_format_all(a));
- assertA(0 == archive_read_support_compression_all(a));
- assertA(0 == archive_read_open_memory(a, buff2, used));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff2, used));
assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae));
- assert(0 == archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assert(0 == archive_read_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
/* Damage the size field in the pax attributes. */
memcpy(buff2, buff, buff_size);
buff2[512] = ' '; /* No size given. */
assert((a = archive_read_new()) != NULL);
- assertA(0 == archive_read_support_format_all(a));
- assertA(0 == archive_read_support_compression_all(a));
- assertA(0 == archive_read_open_memory(a, buff2, used));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff2, used));
assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae));
- assert(0 == archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assert(0 == archive_read_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
/* Damage the ustar header. */
memcpy(buff2, buff, buff_size);
buff2[1024]++; /* Break the checksum. */
assert((a = archive_read_new()) != NULL);
- assertA(0 == archive_read_support_format_all(a));
- assertA(0 == archive_read_support_compression_all(a));
- assertA(0 == archive_read_open_memory(a, buff2, used));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff2, used));
assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae));
- assert(0 == archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assert(0 == archive_read_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
/*
* TODO: Damage the ustar header in various ways and fixup the
diff --git a/libarchive/test/test_read_position.c b/libarchive/test/test_read_position.c
index 85b796721424..80838b5a3e52 100644
--- a/libarchive/test/test_read_position.c
+++ b/libarchive/test/test_read_position.c
@@ -25,8 +25,42 @@
#include "test.h"
__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_position.c 189389 2009-03-05 02:19:42Z kientzle $");
-static unsigned char nulls[10000];
-static unsigned char buff[10000000];
+static unsigned char nulls[1000];
+static unsigned char tmp[1000];
+static unsigned char buff[10000];
+size_t data_sizes[] = {0, 5, 511, 512, 513};
+
+void
+verify_read_positions(struct archive *a)
+{
+ struct archive_entry *ae;
+ intmax_t read_position = 0;
+ size_t j;
+
+ /* Initial header position is zero. */
+ assert(read_position == (intmax_t)archive_read_header_position(a));
+ for (j = 0; j < sizeof(data_sizes)/sizeof(data_sizes[0]); ++j) {
+ assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualInt(read_position,
+ (intmax_t)archive_read_header_position(a));
+ /* Every other entry: read, then skip */
+ if (j & 1)
+ assertEqualInt(1,
+ archive_read_data(a, tmp, 1));
+ assertA(0 == archive_read_data_skip(a));
+ /* read_data_skip() doesn't change header_position */
+ assertEqualInt(read_position,
+ (intmax_t)archive_read_header_position(a));
+
+ read_position += 512; /* Size of header. */
+ read_position += (data_sizes[j] + 511) & ~511;
+ }
+
+ assertA(1 == archive_read_next_header(a, &ae));
+ assertEqualInt(read_position, (intmax_t)archive_read_header_position(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(read_position, (intmax_t)archive_read_header_position(a));
+}
/* Check that header_position tracks correctly on read. */
DEFINE_TEST(test_read_position)
@@ -34,9 +68,7 @@ DEFINE_TEST(test_read_position)
struct archive *a;
struct archive_entry *ae;
size_t write_pos;
- intmax_t read_position;
- size_t i, j;
- size_t data_sizes[] = {0, 5, 511, 512, 513};
+ size_t i;
/* Sanity test */
assert(sizeof(nulls) + 512 + 1024 <= sizeof(buff));
@@ -58,37 +90,21 @@ DEFINE_TEST(test_read_position)
assertA(data_sizes[i]
== (size_t)archive_write_data(a, nulls, sizeof(nulls)));
}
- assertA(0 == archive_write_close(a));
- assertA(0 == archive_write_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
- /* Read the archive back. */
+ /* Read the archive back with a skip function. */
assert(NULL != (a = archive_read_new()));
assertA(0 == archive_read_support_format_tar(a));
- assertA(0 == archive_read_open_memory2(a, buff, sizeof(buff), 512));
-
- read_position = 0;
- /* Initial header position is zero. */
- assert(read_position == (intmax_t)archive_read_header_position(a));
- for (j = 0; j < i; ++j) {
- assertA(0 == archive_read_next_header(a, &ae));
- assert(read_position
- == (intmax_t)archive_read_header_position(a));
- /* Every other entry: read, then skip */
- if (j & 1)
- assertEqualInt(ARCHIVE_OK,
- archive_read_data_into_buffer(a, buff, 1));
- assertA(0 == archive_read_data_skip(a));
- /* read_data_skip() doesn't change header_position */
- assert(read_position
- == (intmax_t)archive_read_header_position(a));
+ assertA(0 == read_open_memory(a, buff, sizeof(buff), 512));
+ verify_read_positions(a);
+ archive_read_free(a);
- read_position += 512; /* Size of header. */
- read_position += (data_sizes[j] + 511) & ~511;
- }
+ /* Read the archive back without a skip function. */
+ assert(NULL != (a = archive_read_new()));
+ assertA(0 == archive_read_support_format_tar(a));
+ assertA(0 == read_open_memory2(a, buff, sizeof(buff), 512));
+ verify_read_positions(a);
+ archive_read_free(a);
- assertA(1 == archive_read_next_header(a, &ae));
- assert(read_position == (intmax_t)archive_read_header_position(a));
- assertA(0 == archive_read_close(a));
- assert(read_position == (intmax_t)archive_read_header_position(a));
- archive_read_finish(a);
}
diff --git a/libarchive/test/test_read_truncated.c b/libarchive/test/test_read_truncated.c
index 9b26b59818a9..306834127972 100644
--- a/libarchive/test/test_read_truncated.c
+++ b/libarchive/test/test_read_truncated.c
@@ -37,9 +37,9 @@ DEFINE_TEST(test_read_truncated)
/* Create a new archive in memory. */
assert((a = archive_write_new()) != NULL);
- assertA(0 == archive_write_set_format_ustar(a));
- assertA(0 == archive_write_set_compression_none(a));
- assertA(0 == archive_write_open_memory(a, buff, sizeof(buff), &used));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_none(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff), &used));
/*
* Write a file to it.
@@ -50,38 +50,33 @@ DEFINE_TEST(test_read_truncated)
for (i = 0; i < sizeof(buff2); i++)
buff2[i] = (unsigned char)rand();
archive_entry_set_size(ae, sizeof(buff2));
- assertA(0 == archive_write_header(a, ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
archive_entry_free(ae);
- assertA((int)sizeof(buff2) == archive_write_data(a, buff2, sizeof(buff2)));
+ assertEqualIntA(a, sizeof(buff2), archive_write_data(a, buff2, sizeof(buff2)));
/* Close out the archive. */
- assertA(0 == archive_write_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_write_finish(a);
-#else
- assertA(0 == archive_write_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/* Now, read back a truncated version of the archive and
* verify that we get an appropriate error. */
for (i = 1; i < used + 100; i += 100) {
assert((a = archive_read_new()) != NULL);
- assertA(0 == archive_read_support_format_all(a));
- assertA(0 == archive_read_support_compression_all(a));
- assertA(0 == archive_read_open_memory(a, buff, i));
-
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
if (i < 512) {
- assertA(ARCHIVE_FATAL == archive_read_next_header(a, &ae));
+ assertEqualIntA(a, ARCHIVE_FATAL, archive_read_open_memory(a, buff, i));
goto wrap_up;
} else {
- assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, i));
}
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
if (i < 512 + sizeof(buff2)) {
- assertA(ARCHIVE_FATAL == archive_read_data(a, buff2, sizeof(buff2)));
+ assertEqualIntA(a, ARCHIVE_FATAL, archive_read_data(a, buff2, sizeof(buff2)));
goto wrap_up;
} else {
- assertA((int)sizeof(buff2) == archive_read_data(a, buff2, sizeof(buff2)));
+ assertEqualIntA(a, sizeof(buff2), archive_read_data(a, buff2, sizeof(buff2)));
}
/* Verify the end of the archive. */
@@ -91,17 +86,13 @@ DEFINE_TEST(test_read_truncated)
* does not return an error if it can't consume
* it.) */
if (i < 512 + 512*((sizeof(buff2) + 511)/512) + 512) {
- assertA(ARCHIVE_FATAL == archive_read_next_header(a, &ae));
+ assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae));
} else {
- assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
}
wrap_up:
- assert(0 == archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assert(0 == archive_read_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
@@ -109,22 +100,21 @@ DEFINE_TEST(test_read_truncated)
/* Same as above, except skip the body instead of reading it. */
for (i = 1; i < used + 100; i += 100) {
assert((a = archive_read_new()) != NULL);
- assertA(0 == archive_read_support_format_all(a));
- assertA(0 == archive_read_support_compression_all(a));
- assertA(0 == archive_read_open_memory(a, buff, i));
-
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
if (i < 512) {
- assertA(ARCHIVE_FATAL == archive_read_next_header(a, &ae));
+ assertEqualIntA(a, ARCHIVE_FATAL, archive_read_open_memory(a, buff, i));
goto wrap_up2;
} else {
- assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, i));
}
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
if (i < 512 + 512*((sizeof(buff2)+511)/512)) {
- assertA(ARCHIVE_FATAL == archive_read_data_skip(a));
+ assertEqualIntA(a, ARCHIVE_FATAL, archive_read_data_skip(a));
goto wrap_up2;
} else {
- assertA(ARCHIVE_OK == archive_read_data_skip(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a));
}
/* Verify the end of the archive. */
@@ -134,16 +124,12 @@ DEFINE_TEST(test_read_truncated)
* does not return an error if it can't consume
* it.) */
if (i < 512 + 512*((sizeof(buff2) + 511)/512) + 512) {
- assertA(ARCHIVE_FATAL == archive_read_next_header(a, &ae));
+ assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae));
} else {
- assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
}
wrap_up2:
- assert(0 == archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assert(0 == archive_read_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
}
diff --git a/libarchive/test/test_read_truncated_filter.c b/libarchive/test/test_read_truncated_filter.c
new file mode 100644
index 000000000000..cb7611ec4c82
--- /dev/null
+++ b/libarchive/test/test_read_truncated_filter.c
@@ -0,0 +1,132 @@
+/*-
+ * Copyright (c) 2007-2010 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+/*
+ * Check that we generate an error message when reading a truncated
+ * gzip, bzip2, compress, xz, lzma, or lzip file.
+ */
+
+static void
+test_truncation(const char *compression, int (*set_compression)(struct archive *))
+{
+ struct archive_entry *ae;
+ struct archive* a;
+ char path[16];
+ char *buff, *data;
+ size_t buffsize, datasize, used1;
+ int i, j, r;
+
+ buffsize = 2000000;
+ assert(NULL != (buff = (char *)malloc(buffsize)));
+
+ datasize = 10000;
+ assert(NULL != (data = (char *)malloc(datasize)));
+ memset(data, 0, datasize);
+
+ /*
+ * Write a bunch of files with semi-random data.
+ */
+ assert((a = archive_write_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_compression_compress(a));
+ r = (*set_compression)(a);
+ if (r == ARCHIVE_FATAL) {
+ skipping("%s writing not supported on this platform", compression);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+ return;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_bytes_per_block(a, 10));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used1));
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_filetype(ae, AE_IFREG);
+ archive_entry_set_size(ae, datasize);
+ for (i = 0; i < 100; i++) {
+ sprintf(path, "%s%d", compression, i);
+ archive_entry_copy_pathname(ae, path);
+ failure(path);
+ if (!assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae))) {
+ archive_write_free(a);
+ free(data);
+ free(buff);
+ return;
+ }
+ for (j = 0; j < (int)datasize; ++j) {
+ data[j] = (char)(rand() % 256);
+ }
+ failure(path);
+ if (!assertEqualIntA(a, datasize, archive_write_data(a, data, datasize))) {
+ archive_write_free(a);
+ free(data);
+ free(buff);
+ return;
+ }
+ }
+ archive_entry_free(ae);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used1 - used1/64));
+ for (i = 0; i < 100; i++) {
+ if (ARCHIVE_OK != archive_read_next_header(a, &ae)) {
+ failure("Should have non-NULL error message for %s",
+ compression);
+ assert(NULL != archive_error_string(a));
+ break;
+ }
+ sprintf(path, "%s%d", compression, i);
+ assertEqualString(path, archive_entry_pathname(ae));
+ if (datasize != (size_t)archive_read_data(a, data, datasize)) {
+ failure("Should have non-NULL error message for %s",
+ compression);
+ assert(NULL != archive_error_string(a));
+ break;
+ }
+ }
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+ free(data);
+ free(buff);
+}
+
+DEFINE_TEST(test_read_truncated_filter)
+{
+ test_truncation("bzip2", archive_write_set_compression_bzip2);
+ test_truncation("compress", archive_write_set_compression_compress);
+ test_truncation("gzip", archive_write_set_compression_gzip);
+ test_truncation("lzip", archive_write_set_compression_lzip);
+ test_truncation("lzma", archive_write_set_compression_lzma);
+ test_truncation("xz", archive_write_set_compression_xz);
+}
diff --git a/libarchive/test/test_read_uu.c b/libarchive/test/test_read_uu.c
index a5de09af7406..f4169e3256d2 100644
--- a/libarchive/test/test_read_uu.c
+++ b/libarchive/test/test_read_uu.c
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
- * Copyright (c) 2009 Michihiro NAKAJIMA
+ * Copyright (c) 2009-2011 Michihiro NAKAJIMA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -70,14 +70,28 @@ static const char extradata[] = {
};
static void
-test_read_uu_sub(const char *uudata, size_t uusize)
+test_read_uu_sub(const char *uudata, size_t uusize, int no_nl)
{
struct archive_entry *ae;
struct archive *a;
char *buff;
+ char extradata_no_nl[sizeof(extradata)];
+ const char *extradata_ptr;
int extra;
+ size_t size;
- assert(NULL != (buff = malloc(uusize + 64 * 1024)));
+ if (no_nl) {
+ /* Remove '\n' from extra data to make a very long line. */
+ char *p;
+ memcpy(extradata_no_nl, extradata, sizeof(extradata));
+ extradata_ptr = extradata_no_nl;
+ for (p = extradata_no_nl;
+ *p && (p = strchr(p, '\n')) != NULL; p++)
+ *p = ' ';/* Replace '\n' with ' ' a space character. */
+ } else
+ extradata_ptr = extradata;
+
+ assert(NULL != (buff = malloc(uusize + 1024 * 1024)));
if (buff == NULL)
return;
for (extra = 0; extra <= 64; extra = extra==0?1:extra*2) {
@@ -88,11 +102,11 @@ test_read_uu_sub(const char *uudata, size_t uusize)
* 64Kbytes before uuencoded data. */
while (size) {
if (size > sizeof(extradata)-1) {
- memcpy(p, extradata, sizeof(extradata)-1);
+ memcpy(p, extradata_ptr, sizeof(extradata)-1);
p += sizeof(extradata)-1;
size -= sizeof(extradata)-1;
} else {
- memcpy(p, extradata, size-1);
+ memcpy(p, extradata_ptr, size-1);
p += size-1;
*p++ = '\n';/* the last of extra text must have
* '\n' character. */
@@ -104,31 +118,58 @@ test_read_uu_sub(const char *uudata, size_t uusize)
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK,
- archive_read_support_compression_all(a));
+ archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK,
read_open_memory(a, buff, size, 2));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_next_header(a, &ae));
- failure("archive_compression_name(a)=\"%s\"",
- archive_compression_name(a));
+ failure("archive_compression_name(a)=\"%s\""
+ "extra %d, NL %d",
+ archive_compression_name(a), extra, !no_nl);
assertEqualInt(archive_compression(a),
ARCHIVE_COMPRESSION_COMPRESS);
- failure("archive_format_name(a)=\"%s\"",
- archive_format_name(a));
- assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR);
+ failure("archive_format_name(a)=\"%s\""
+ "extra %d, NL %d",
+ archive_format_name(a), extra, !no_nl);
+ assertEqualInt(archive_format(a),
+ ARCHIVE_FORMAT_TAR_USTAR);
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
+
+ /* UUdecode bidder shouldn't scan too much data; make sure it
+ * fails if we put 512k of data before the start. */
+ size = 512 * 1024;
+ for (extra = 0; (size_t)extra < size; ++extra)
+ buff[extra + 1024] = buff[extra];
+ buff[size - 1] = '\n';
+ memcpy(buff + size, uudata, uusize);
+ size += uusize;
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_FATAL,
+ read_open_memory(a, buff, size, 2));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
free(buff);
}
DEFINE_TEST(test_read_uu)
{
/* Read the traditional uuencoded data. */
- test_read_uu_sub(archive, sizeof(archive)-1);
+ test_read_uu_sub(archive, sizeof(archive)-1, 0);
/* Read the Base64 uuencoded data. */
- test_read_uu_sub(archive64, sizeof(archive64)-1);
+ test_read_uu_sub(archive64, sizeof(archive64)-1, 0);
+ /* Read the traditional uuencoded data with very long line extra
+ * data in front of it. */
+ test_read_uu_sub(archive, sizeof(archive)-1, 1);
+ /* Read the Base64 uuencoded data with very long line extra data
+ * in front of it. */
+ test_read_uu_sub(archive64, sizeof(archive64)-1, 1);
}
diff --git a/libarchive/test/test_sparse_basic.c b/libarchive/test/test_sparse_basic.c
new file mode 100644
index 000000000000..52d76c6013df
--- /dev/null
+++ b/libarchive/test/test_sparse_basic.c
@@ -0,0 +1,462 @@
+/*-
+ * Copyright (c) 2010 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_LINUX_FIEMAP_H
+#include <linux/fiemap.h>
+#endif
+#ifdef HAVE_LINUX_FS_H
+#include <linux/fs.h>
+#endif
+
+/*
+ * NOTE: On FreeBSD and Solaris, this test needs ZFS.
+ * You may should perfom this test as
+ * 'TMPDIR=<a directory on the ZFS> libarchive_test'.
+ */
+
+struct sparse {
+ enum { DATA, HOLE, END } type;
+ size_t size;
+};
+
+static void create_sparse_file(const char *, const struct sparse *);
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#include <winioctl.h>
+/*
+ * Create a sparse file on Windows.
+ */
+
+#if !defined(PATH_MAX)
+#define PATH_MAX MAX_PATH
+#endif
+#if !defined(__BORLANDC__)
+#define getcwd _getcwd
+#endif
+
+static int
+is_sparse_supported(const char *path)
+{
+ char root[MAX_PATH+1];
+ char vol[MAX_PATH+1];
+ char sys[MAX_PATH+1];
+ DWORD flags;
+ BOOL r;
+
+ strncpy(root, path, sizeof(root)-1);
+ if (((root[0] >= 'c' && root[0] <= 'z') ||
+ (root[0] >= 'C' && root[0] <= 'Z')) &&
+ root[1] == ':' &&
+ (root[2] == '\\' || root[2] == '/'))
+ root[3] = '\0';
+ else
+ return (0);
+ assertEqualInt((r = GetVolumeInformation(root, vol,
+ sizeof(vol), NULL, NULL, &flags, sys, sizeof(sys))), 1);
+ return (r != 0 && (flags & FILE_SUPPORTS_SPARSE_FILES) != 0);
+}
+
+static void
+create_sparse_file(const char *path, const struct sparse *s)
+{
+ char buff[1024];
+ HANDLE handle;
+ DWORD dmy;
+
+ memset(buff, ' ', sizeof(buff));
+
+ handle = CreateFileA(path, GENERIC_WRITE, 0,
+ NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ assert(handle != INVALID_HANDLE_VALUE);
+ assert(DeviceIoControl(handle, FSCTL_SET_SPARSE, NULL, 0,
+ NULL, 0, &dmy, NULL) != 0);
+ while (s->type != END) {
+ if (s->type == HOLE) {
+ LARGE_INTEGER distance;
+
+ distance.QuadPart = s->size;
+ assert(SetFilePointerEx(handle, distance,
+ NULL, FILE_CURRENT) != 0);
+ } else {
+ DWORD w, wr, size;
+
+ size = s->size;
+ while (size) {
+ if (size > sizeof(buff))
+ w = sizeof(buff);
+ else
+ w = size;
+ assert(WriteFile(handle, buff, w, &wr, NULL) != 0);
+ size -= wr;
+ }
+ }
+ s++;
+ }
+ assertEqualInt(CloseHandle(handle), 1);
+}
+
+#else
+
+#if defined(_PC_MIN_HOLE_SIZE)
+
+/*
+ * FreeBSD and Solaris can detect 'hole' of a sparse file
+ * through lseek(HOLE) on ZFS. (UFS does not support yet)
+ */
+
+static int
+is_sparse_supported(const char *path)
+{
+ return (pathconf(path, _PC_MIN_HOLE_SIZE) > 0);
+}
+
+#elif defined(__linux__)&& defined(HAVE_LINUX_FIEMAP_H)
+
+/*
+ * FIEMAP, which can detect 'hole' of a sparse file, has
+ * been supported from 2.6.28
+ */
+
+static int
+is_sparse_supported(const char *path)
+{
+ const struct sparse sparse_file[] = {
+ /* This hole size is too small to create a sparse
+ * files for almost filesystem. */
+ { HOLE, 1024 }, { DATA, 10240 },
+ { END, 0 }
+ };
+ struct utsname ut;
+ char *p, *e;
+ long d;
+ int fd, r;
+ struct fiemap *fm;
+ char buff[1024];
+ const char *testfile = "can_sparse";
+
+ memset(&ut, 0, sizeof(ut));
+ assertEqualInt(uname(&ut), 0);
+ p = ut.release;
+ d = strtol(p, &e, 10);
+ if (d < 2 || *e != '.')
+ return (0);
+ if (d == 2) {
+ p = e + 1;
+ d = strtol(p, &e, 10);
+ if (d < 6 || *e != '.')
+ return (0);
+ p = e + 1;
+ d = strtol(p, NULL, 10);
+ if (d < 28)
+ return (0);
+ }
+ create_sparse_file(testfile, sparse_file);
+ fd = open(testfile, O_RDWR);
+ if (fd < 0)
+ return (0);
+ fm = (struct fiemap *)buff;
+ fm->fm_start = 0;
+ fm->fm_length = ~0ULL;;
+ fm->fm_flags = FIEMAP_FLAG_SYNC;
+ fm->fm_extent_count = (sizeof(buff) - sizeof(*fm))/
+ sizeof(struct fiemap_extent);
+ r = ioctl(fd, FS_IOC_FIEMAP, fm);
+ if (r < 0 && (errno == ENOTTY || errno == EOPNOTSUPP))
+ return (0);/* Not supported. */
+ close(fd);
+ unlink(testfile);
+ return (1);
+}
+
+#else
+
+/*
+ * Other system may do not have the API such as lseek(HOLE),
+ * which detect 'hole' of a sparse file.
+ */
+
+static int
+is_sparse_supported(const char *path)
+{
+ return (0);
+}
+
+#endif
+
+/*
+ * Create a sparse file on POSIX like system.
+ */
+
+static void
+create_sparse_file(const char *path, const struct sparse *s)
+{
+ char buff[1024];
+ int fd;
+
+ memset(buff, ' ', sizeof(buff));
+ assert((fd = open(path, O_CREAT | O_WRONLY, 0600)) != -1);
+ while (s->type != END) {
+ if (s->type == HOLE) {
+ assert(lseek(fd, s->size, SEEK_CUR) != (off_t)-1);
+ } else {
+ size_t w, size;
+
+ size = s->size;
+ while (size) {
+ if (size > sizeof(buff))
+ w = sizeof(buff);
+ else
+ w = size;
+ assert(write(fd, buff, w) != (ssize_t)-1);
+ size -= w;
+ }
+ }
+ s++;
+ }
+ close(fd);
+}
+
+#endif
+
+/*
+ * Sparse test with directory traversals.
+ */
+static void
+verify_sparse_file(struct archive *a, const char *path,
+ const struct sparse *sparse, int blocks)
+{
+ struct archive_entry *ae;
+ const void *buff;
+ size_t bytes_read;
+ int64_t offset;
+ int64_t total;
+ int data_blocks, hole;
+
+ create_sparse_file(path, sparse);
+ assert((ae = archive_entry_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, path));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
+ /* Verify the number of holes only, not its offset nor its
+ * length because those alignments are deeply dependence on
+ * its filesystem. */
+ assertEqualInt(blocks, archive_entry_sparse_count(ae));
+ total = 0;
+ data_blocks = 0;
+ hole = 0;
+ while (ARCHIVE_OK == archive_read_data_block(a, &buff, &bytes_read,
+ &offset)) {
+ if (offset > total || offset == 0) {
+ if (offset > total)
+ hole = 1;
+ data_blocks++;
+ }
+ total = offset + bytes_read;
+ }
+ if (!hole && data_blocks == 1)
+ data_blocks = 0;/* There are no holes */
+ assertEqualInt(blocks, data_blocks);
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ archive_entry_free(ae);
+}
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#define close _close
+#define open _open
+#endif
+
+/*
+ * Sparse test without directory traversals.
+ */
+static void
+verify_sparse_file2(struct archive *a, const char *path,
+ const struct sparse *sparse, int blocks, int preopen)
+{
+ struct archive_entry *ae;
+ int fd;
+
+ (void)sparse; /* UNUSED */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_pathname(ae, path);
+ if (preopen)
+ fd = open(path, O_RDONLY | O_BINARY);
+ else
+ fd = -1;
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_disk_entry_from_file(a, ae, fd, NULL));
+ if (fd >= 0)
+ close(fd);
+ /* Verify the number of holes only, not its offset nor its
+ * length because those alignments are deeply dependence on
+ * its filesystem. */
+ assertEqualInt(blocks, archive_entry_sparse_count(ae));
+ archive_entry_free(ae);
+}
+
+static void
+test_sparse_whole_file_data()
+{
+ struct archive_entry *ae;
+ int64_t offset;
+ int i;
+
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_size(ae, 1024*10);
+
+ /*
+ * Add sparse block data up to the file size.
+ */
+ offset = 0;
+ for (i = 0; i < 10; i++) {
+ archive_entry_sparse_add_entry(ae, offset, 1024);
+ offset += 1024;
+ }
+
+ failure("There should be no sparse");
+ assertEqualInt(0, archive_entry_sparse_count(ae));
+ archive_entry_free(ae);
+}
+
+DEFINE_TEST(test_sparse_basic)
+{
+ char *cwd;
+ struct archive *a;
+ /*
+ * The alignment of the hole of sparse files deeply depends
+ * on filesystem. In my experience, sparse_file2 test with
+ * 204800 bytes hole size did not pass on ZFS and the result
+ * of that test seemed the size was too small, thus you should
+ * keep a hole size more than 409600 bytes to pass this test
+ * on all platform.
+ */
+ const struct sparse sparse_file0[] = {
+ { DATA, 1024 }, { HOLE, 2048000 },
+ { DATA, 2048 }, { HOLE, 2048000 },
+ { DATA, 4096 }, { HOLE, 20480000 },
+ { DATA, 8192 }, { HOLE, 204800000 },
+ { DATA, 1 }, { END, 0 }
+ };
+ const struct sparse sparse_file1[] = {
+ { HOLE, 409600 }, { DATA, 1 },
+ { HOLE, 409600 }, { DATA, 1 },
+ { HOLE, 409600 }, { END, 0 }
+ };
+ const struct sparse sparse_file2[] = {
+ { HOLE, 409600 * 1 }, { DATA, 1024 },
+ { HOLE, 409600 * 2 }, { DATA, 1024 },
+ { HOLE, 409600 * 3 }, { DATA, 1024 },
+ { HOLE, 409600 * 4 }, { DATA, 1024 },
+ { HOLE, 409600 * 5 }, { DATA, 1024 },
+ { HOLE, 409600 * 6 }, { DATA, 1024 },
+ { HOLE, 409600 * 7 }, { DATA, 1024 },
+ { HOLE, 409600 * 8 }, { DATA, 1024 },
+ { HOLE, 409600 * 9 }, { DATA, 1024 },
+ { HOLE, 409600 * 10}, { DATA, 1024 },/* 10 */
+ { HOLE, 409600 * 1 }, { DATA, 1024 * 1 },
+ { HOLE, 409600 * 2 }, { DATA, 1024 * 2 },
+ { HOLE, 409600 * 3 }, { DATA, 1024 * 3 },
+ { HOLE, 409600 * 4 }, { DATA, 1024 * 4 },
+ { HOLE, 409600 * 5 }, { DATA, 1024 * 5 },
+ { HOLE, 409600 * 6 }, { DATA, 1024 * 6 },
+ { HOLE, 409600 * 7 }, { DATA, 1024 * 7 },
+ { HOLE, 409600 * 8 }, { DATA, 1024 * 8 },
+ { HOLE, 409600 * 9 }, { DATA, 1024 * 9 },
+ { HOLE, 409600 * 10}, { DATA, 1024 * 10},/* 20 */
+ { END, 0 }
+ };
+ const struct sparse sparse_file3[] = {
+ /* This hole size is too small to create a sparse
+ * files for almost filesystem. */
+ { HOLE, 1024 }, { DATA, 10240 },
+ { END, 0 }
+ };
+
+ /*
+ * Test for the case that sparse data indicates just the whole file
+ * data.
+ */
+ test_sparse_whole_file_data();
+
+ /* Check if the filesystem where CWD on can
+ * report the number of the holes of a sparse file. */
+#ifdef PATH_MAX
+ cwd = getcwd(NULL, PATH_MAX);/* Solaris getcwd needs the size. */
+#else
+ cwd = getcwd(NULL, 0);
+#endif
+ if (!assert(cwd != NULL))
+ return;
+ if (!is_sparse_supported(cwd)) {
+ free(cwd);
+ skipping("This filesystem or platform do not support "
+ "the reporting of the holes of a sparse file through "
+ "API such as lseek(HOLE)");
+ return;
+ }
+
+ /*
+ * Get sparse data through directory traversals.
+ */
+ assert((a = archive_read_disk_new()) != NULL);
+
+ verify_sparse_file(a, "file0", sparse_file0, 5);
+ verify_sparse_file(a, "file1", sparse_file1, 2);
+ verify_sparse_file(a, "file2", sparse_file2, 20);
+ verify_sparse_file(a, "file3", sparse_file3, 0);
+
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+ /*
+ * Get sparse data through archive_read_disk_entry_from_file().
+ */
+ assert((a = archive_read_disk_new()) != NULL);
+
+ verify_sparse_file2(a, "file0", sparse_file0, 5, 0);
+ verify_sparse_file2(a, "file0", sparse_file0, 5, 1);
+
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+ free(cwd);
+}
diff --git a/libarchive/test/test_tar_filenames.c b/libarchive/test/test_tar_filenames.c
index b08373819dfc..de423bbe9787 100644
--- a/libarchive/test/test_tar_filenames.c
+++ b/libarchive/test/test_tar_filenames.c
@@ -100,28 +100,20 @@ test_filename(const char *prefix, int dlen, int flen)
archive_entry_free(ae);
/* Close out the archive. */
- assertA(0 == archive_write_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_write_finish(a);
-#else
- assertA(0 == archive_write_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/*
* Now, read the data back.
*/
assert((a = archive_read_new()) != NULL);
assertA(0 == archive_read_support_format_all(a));
- assertA(0 == archive_read_support_compression_all(a));
+ assertA(0 == archive_read_support_filter_all(a));
assertA(0 == archive_read_open_memory(a, buff, used));
/* Read the file and check the filename. */
assertA(0 == archive_read_next_header(a, &ae));
-#if ARCHIVE_VERSION_NUMBER < 1009000
- skipping("Leading '/' preserved on long filenames");
-#else
assertEqualString(filename, archive_entry_pathname(ae));
-#endif
assertEqualInt((S_IFREG | 0755), archive_entry_mode(ae));
/*
@@ -133,29 +125,17 @@ test_filename(const char *prefix, int dlen, int flen)
* here.
*/
assertA(0 == archive_read_next_header(a, &ae));
-#if ARCHIVE_VERSION_NUMBER < 1009000
- skipping("Trailing '/' preserved on dirnames");
-#else
assertEqualString(dirname, archive_entry_pathname(ae));
-#endif
assert((S_IFDIR | 0755) == archive_entry_mode(ae));
assertA(0 == archive_read_next_header(a, &ae));
-#if ARCHIVE_VERSION_NUMBER < 1009000
- skipping("Trailing '/' added to dir names");
-#else
assertEqualString(dirname, archive_entry_pathname(ae));
-#endif
assert((S_IFDIR | 0755) == archive_entry_mode(ae));
/* Verify the end of the archive. */
assert(1 == archive_read_next_header(a, &ae));
- assert(0 == archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assert(0 == archive_read_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
DEFINE_TEST(test_tar_filenames)
diff --git a/libarchive/test/test_tar_large.c b/libarchive/test/test_tar_large.c
index adc81551cecd..626f9f0878bc 100644
--- a/libarchive/test/test_tar_large.c
+++ b/libarchive/test/test_tar_large.c
@@ -73,11 +73,7 @@ struct memdata {
#define GB ((int64_t)1024 * MB)
#define TB ((int64_t)1024 * GB)
-#if ARCHIVE_VERSION_NUMBER < 2000000
-static ssize_t memory_read_skip(struct archive *, void *, size_t request);
-#else
-static off_t memory_read_skip(struct archive *, void *, off_t request);
-#endif
+static int64_t memory_read_skip(struct archive *, void *, int64_t request);
static ssize_t memory_read(struct archive *, void *, const void **buff);
static ssize_t memory_write(struct archive *, void *, const void *, size_t);
@@ -167,18 +163,8 @@ memory_read(struct archive *a, void *_private, const void **buff)
}
-#if ARCHIVE_VERSION_NUMBER < 2000000
-static ssize_t
-memory_read_skip(struct archive *a, void *private, size_t skip)
-{
- (void)a; /* UNUSED */
- (void)private; /* UNUSED */
- (void)skip; /* UNUSED */
- return (0);
-}
-#else
-static off_t
-memory_read_skip(struct archive *a, void *_private, off_t skip)
+static int64_t
+memory_read_skip(struct archive *a, void *_private, int64_t skip)
{
struct memdata *private = _private;
@@ -197,7 +183,6 @@ memory_read_skip(struct archive *a, void *_private, off_t skip)
}
return (skip);
}
-#endif
DEFINE_TEST(test_tar_large)
{
@@ -270,12 +255,8 @@ DEFINE_TEST(test_tar_large)
/* Close out the archive. */
- assertA(0 == archive_write_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_write_finish(a);
-#else
- assertA(0 == archive_write_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/*
* Open the same archive for reading.
@@ -300,12 +281,8 @@ DEFINE_TEST(test_tar_large)
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
/* Close out the archive. */
- assertA(0 == archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assertA(0 == archive_read_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
free(memdata.buff);
free(filedata);
diff --git a/libarchive/test/test_ustar_filename_encoding.c b/libarchive/test/test_ustar_filename_encoding.c
new file mode 100644
index 000000000000..17b7e4a22764
--- /dev/null
+++ b/libarchive/test/test_ustar_filename_encoding.c
@@ -0,0 +1,414 @@
+/*-
+ * Copyright (c) 2011 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+#include <locale.h>
+
+static void
+test_ustar_filename_encoding_UTF8_CP866(void)
+{
+ struct archive *a;
+ struct archive_entry *entry;
+ char buff[4096];
+ size_t used;
+
+ if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
+ skipping("en_US.UTF-8 locale not available on this system.");
+ return;
+ }
+
+ /*
+ * Verify that UTF-8 filenames are correctly translated into CP866
+ * and stored with hdrcharset=CP866 option.
+ */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_ustar(a));
+ if (archive_write_set_options(a, "hdrcharset=CP866") != ARCHIVE_OK) {
+ skipping("This system cannot convert character-set"
+ " from UTF-8 to CP866.");
+ archive_write_free(a);
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set a UTF-8 filename. */
+ archive_entry_set_pathname(entry, "\xD0\xBF\xD1\x80\xD0\xB8");
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* Above three characters in UTF-8 should translate to the following
+ * three characters in CP866. */
+ assertEqualMem(buff, "\xAF\xE0\xA8", 3);
+}
+
+static void
+test_ustar_filename_encoding_KOI8R_UTF8(void)
+{
+ struct archive *a;
+ struct archive_entry *entry;
+ char buff[4096];
+ size_t used;
+
+ if (NULL == setlocale(LC_ALL, "ru_RU.KOI8-R")) {
+ skipping("KOI8-R locale not available on this system.");
+ return;
+ }
+
+ /*
+ * Verify that KOI8-R filenames are correctly translated into UTF-8
+ * and stored with hdrcharset=UTF-8 option.
+ */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_ustar(a));
+ if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) {
+ skipping("This system cannot convert character-set"
+ " from KOI8-R to UTF-8.");
+ archive_write_free(a);
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set a KOI8-R filename. */
+ archive_entry_set_pathname(entry, "\xD0\xD2\xC9");
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* Above three characters in KOI8-R should translate to the following
+ * three characters (two bytes each) in UTF-8. */
+ assertEqualMem(buff, "\xD0\xBF\xD1\x80\xD0\xB8", 6);
+}
+
+static void
+test_ustar_filename_encoding_KOI8R_CP866(void)
+{
+ struct archive *a;
+ struct archive_entry *entry;
+ char buff[4096];
+ size_t used;
+
+ if (NULL == setlocale(LC_ALL, "ru_RU.KOI8-R")) {
+ skipping("KOI8-R locale not available on this system.");
+ return;
+ }
+
+ /*
+ * Verify that KOI8-R filenames are correctly translated into CP866
+ * and stored with hdrcharset=CP866 option.
+ */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_ustar(a));
+ if (archive_write_set_options(a, "hdrcharset=CP866") != ARCHIVE_OK) {
+ skipping("This system cannot convert character-set"
+ " from KOI8-R to CP866.");
+ archive_write_free(a);
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set a KOI8-R filename. */
+ archive_entry_set_pathname(entry, "\xD0\xD2\xC9");
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* Above three characters in KOI8-R should translate to the following
+ * three characters in CP866. */
+ assertEqualMem(buff, "\xAF\xE0\xA8", 3);
+}
+
+static void
+test_ustar_filename_encoding_CP1251_UTF8(void)
+{
+ struct archive *a;
+ struct archive_entry *entry;
+ char buff[4096];
+ size_t used;
+
+ if (NULL == setlocale(LC_ALL, "Russian_Russia") &&
+ NULL == setlocale(LC_ALL, "ru_RU.CP1251")) {
+ skipping("KOI8-R locale not available on this system.");
+ return;
+ }
+
+ /*
+ * Verify that CP1251 filenames are correctly translated into UTF-8
+ * and stored with hdrcharset=UTF-8 option.
+ */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_ustar(a));
+ if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) {
+ skipping("This system cannot convert character-set"
+ " from KOI8-R to UTF-8.");
+ archive_write_free(a);
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set a KOI8-R filename. */
+ archive_entry_set_pathname(entry, "\xEF\xF0\xE8");
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* Above three characters in CP1251 should translate to the following
+ * three characters (two bytes each) in UTF-8. */
+ assertEqualMem(buff, "\xD0\xBF\xD1\x80\xD0\xB8", 6);
+}
+
+/*
+ * Do not translate CP1251 into CP866 if non Windows platform.
+ */
+static void
+test_ustar_filename_encoding_ru_RU_CP1251(void)
+{
+ struct archive *a;
+ struct archive_entry *entry;
+ char buff[4096];
+ size_t used;
+
+ if (NULL == setlocale(LC_ALL, "ru_RU.CP1251")) {
+ skipping("KOI8-R locale not available on this system.");
+ return;
+ }
+
+ /*
+ * Verify that CP1251 filenames are not translated into any
+ * other character-set, in particular, CP866.
+ */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_ustar(a));
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set a KOI8-R filename. */
+ archive_entry_set_pathname(entry, "\xEF\xF0\xE8");
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* Above three characters in CP1251 should not translate to
+ * any other character-set. */
+ assertEqualMem(buff, "\xEF\xF0\xE8", 3);
+}
+
+/*
+ * Other archiver applications on Windows translate CP1251 filenames
+ * into CP866 filenames and store it in the ustar file.
+ * Test above behavior works well.
+ */
+static void
+test_ustar_filename_encoding_Russian_Russia(void)
+{
+ struct archive *a;
+ struct archive_entry *entry;
+ char buff[4096];
+ size_t used;
+
+ if (NULL == setlocale(LC_ALL, "Russian_Russia")) {
+ skipping("Russian_Russia locale not available on this system.");
+ return;
+ }
+
+ /*
+ * Verify that Russian_Russia(CP1251) filenames are correctly translated
+ * to CP866.
+ */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_ustar(a));
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set a CP1251 filename. */
+ archive_entry_set_pathname(entry, "\xEF\xF0\xE8");
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* Above three characters in CP1251 should translate to the following
+ * three characters in CP866. */
+ assertEqualMem(buff, "\xAF\xE0\xA8", 3);
+}
+
+static void
+test_ustar_filename_encoding_EUCJP_UTF8(void)
+{
+ struct archive *a;
+ struct archive_entry *entry;
+ char buff[4096];
+ size_t used;
+
+ if (NULL == setlocale(LC_ALL, "ja_JP.eucJP")) {
+ skipping("eucJP locale not available on this system.");
+ return;
+ }
+
+ /*
+ * Verify that EUC-JP filenames are correctly translated to UTF-8.
+ */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_ustar(a));
+ if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) {
+ skipping("This system cannot convert character-set"
+ " from eucJP to UTF-8.");
+ archive_write_free(a);
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set an EUC-JP filename. */
+ archive_entry_set_pathname(entry, "\xC9\xBD.txt");
+ /* Check the Unicode version. */
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* Check UTF-8 version. */
+ assertEqualMem(buff, "\xE8\xA1\xA8.txt", 7);
+}
+
+static void
+test_ustar_filename_encoding_EUCJP_CP932(void)
+{
+ struct archive *a;
+ struct archive_entry *entry;
+ char buff[4096];
+ size_t used;
+
+ if (NULL == setlocale(LC_ALL, "ja_JP.eucJP")) {
+ skipping("eucJP locale not available on this system.");
+ return;
+ }
+
+ /*
+ * Verify that EUC-JP filenames are correctly translated to CP932.
+ */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_ustar(a));
+ if (archive_write_set_options(a, "hdrcharset=CP932") != ARCHIVE_OK) {
+ skipping("This system cannot convert character-set"
+ " from eucJP to CP932.");
+ archive_write_free(a);
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set an EUC-JP filename. */
+ archive_entry_set_pathname(entry, "\xC9\xBD.txt");
+ /* Check the Unicode version. */
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* Check CP932 version. */
+ assertEqualMem(buff, "\x95\x5C.txt", 6);
+}
+
+static void
+test_ustar_filename_encoding_CP932_UTF8(void)
+{
+ struct archive *a;
+ struct archive_entry *entry;
+ char buff[4096];
+ size_t used;
+
+ if (NULL == setlocale(LC_ALL, "Japanese_Japan") &&
+ NULL == setlocale(LC_ALL, "ja_JP.SJIS")) {
+ skipping("CP932/SJIS locale not available on this system.");
+ return;
+ }
+
+ /*
+ * Verify that CP932/SJIS filenames are correctly translated to UTF-8.
+ */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_ustar(a));
+ if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) {
+ skipping("This system cannot convert character-set"
+ " from CP932/SJIS to UTF-8.");
+ archive_write_free(a);
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set a CP932/SJIS filename. */
+ archive_entry_set_pathname(entry, "\x95\x5C.txt");
+ /* Check the Unicode version. */
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* Check UTF-8 version. */
+ assertEqualMem(buff, "\xE8\xA1\xA8.txt", 7);
+}
+
+DEFINE_TEST(test_ustar_filename_encoding)
+{
+ test_ustar_filename_encoding_UTF8_CP866();
+ test_ustar_filename_encoding_KOI8R_UTF8();
+ test_ustar_filename_encoding_KOI8R_CP866();
+ test_ustar_filename_encoding_CP1251_UTF8();
+ test_ustar_filename_encoding_ru_RU_CP1251();
+ test_ustar_filename_encoding_Russian_Russia();
+ test_ustar_filename_encoding_EUCJP_UTF8();
+ test_ustar_filename_encoding_EUCJP_CP932();
+ test_ustar_filename_encoding_CP932_UTF8();
+}
diff --git a/libarchive/test/test_ustar_filenames.c b/libarchive/test/test_ustar_filenames.c
index e3ebf3c92f04..55665bb610a4 100644
--- a/libarchive/test/test_ustar_filenames.c
+++ b/libarchive/test/test_ustar_filenames.c
@@ -110,19 +110,15 @@ test_filename(const char *prefix, int dlen, int flen)
archive_entry_free(ae);
/* Close out the archive. */
- assertA(0 == archive_write_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_write_finish(a);
-#else
- assertEqualInt(0, archive_write_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/*
* Now, read the data back.
*/
assert((a = archive_read_new()) != NULL);
assertA(0 == archive_read_support_format_all(a));
- assertA(0 == archive_read_support_compression_all(a));
+ assertA(0 == archive_read_support_filter_all(a));
assertA(0 == archive_read_open_memory(a, buff, used));
if (flen <= 100) {
@@ -156,12 +152,8 @@ test_filename(const char *prefix, int dlen, int flen)
/* Verify the end of the archive. */
failure("This fails if entries were written that should not have been written. dlen=%d, flen=%d", dlen, flen);
assertEqualInt(1, archive_read_next_header(a, &ae));
- assert(0 == archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assertEqualInt(0, archive_read_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
DEFINE_TEST(test_ustar_filenames)
diff --git a/libarchive/test/test_write_compress.c b/libarchive/test/test_write_compress.c
index aa590de8a911..bb81c4f311bf 100644
--- a/libarchive/test/test_write_compress.c
+++ b/libarchive/test/test_write_compress.c
@@ -51,9 +51,12 @@ DEFINE_TEST(test_write_compress)
memset(data, 0, datasize);
assert((a = archive_write_new()) != NULL);
- assertA(0 == archive_write_set_format_ustar(a));
- assertA(0 == archive_write_set_compression_compress(a));
- assertA(0 == archive_write_open_memory(a, buff, buffsize, &used));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_format_ustar(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_compression_compress(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_open_memory(a, buff, buffsize, &used));
for (i = 0; i < 100; i++) {
sprintf(path, "file%03d", i);
@@ -61,26 +64,22 @@ DEFINE_TEST(test_write_compress)
archive_entry_copy_pathname(ae, path);
archive_entry_set_size(ae, datasize);
archive_entry_set_filetype(ae, AE_IFREG);
- assertA(0 == archive_write_header(a, ae));
- assertA(datasize == (size_t)archive_write_data(a, data, datasize));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ assertEqualInt(datasize,
+ archive_write_data(a, data, datasize));
archive_entry_free(ae);
}
-
- archive_write_close(a);
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_write_finish(a);
-#else
- assert(0 == archive_write_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/*
* Now, read the data back.
*/
assert((a = archive_read_new()) != NULL);
- assertA(0 == archive_read_support_format_all(a));
- assertA(0 == archive_read_support_compression_all(a));
- assertA(0 == archive_read_open_memory(a, buff, used));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used));
for (i = 0; i < 100; i++) {
@@ -90,12 +89,8 @@ DEFINE_TEST(test_write_compress)
assertEqualString(path, archive_entry_pathname(ae));
assertEqualInt((int)datasize, archive_entry_size(ae));
}
- assert(0 == archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assert(0 == archive_read_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
free(data);
free(buff);
diff --git a/libarchive/test/test_write_compress_bzip2.c b/libarchive/test/test_write_compress_bzip2.c
index ee6954022aa2..b9e92369a9c2 100644
--- a/libarchive/test/test_write_compress_bzip2.c
+++ b/libarchive/test/test_write_compress_bzip2.c
@@ -54,18 +54,18 @@ DEFINE_TEST(test_write_compress_bzip2)
* Write a 100 files and read them all back.
*/
assert((a = archive_write_new()) != NULL);
- assertA(0 == archive_write_set_format_ustar(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
r = archive_write_set_compression_bzip2(a);
if (r == ARCHIVE_FATAL) {
skipping("bzip2 writing not supported on this platform");
- assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
return;
}
assertEqualIntA(a, ARCHIVE_OK,
archive_write_set_bytes_per_block(a, 10));
assertEqualInt(ARCHIVE_COMPRESSION_BZIP2, archive_compression(a));
assertEqualString("bzip2", archive_compression_name(a));
- assertA(0 == archive_write_open_memory(a, buff, buffsize, &used1));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used1));
assertEqualInt(ARCHIVE_COMPRESSION_BZIP2, archive_compression(a));
assertEqualString("bzip2", archive_compression_name(a));
assert((ae = archive_entry_new()) != NULL);
@@ -74,18 +74,18 @@ DEFINE_TEST(test_write_compress_bzip2)
for (i = 0; i < 999; i++) {
sprintf(path, "file%03d", i);
archive_entry_copy_pathname(ae, path);
- assertA(0 == archive_write_header(a, ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
assertA(datasize
== (size_t)archive_write_data(a, data, datasize));
}
archive_entry_free(ae);
- archive_write_close(a);
- assert(0 == archive_write_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
assert((a = archive_read_new()) != NULL);
- assertA(0 == archive_read_support_format_all(a));
- assertA(0 == archive_read_support_compression_all(a));
- assertA(0 == archive_read_open_memory(a, buff, used1));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used1));
for (i = 0; i < 999; i++) {
sprintf(path, "file%03d", i);
if (!assertEqualInt(0, archive_read_next_header(a, &ae)))
@@ -93,39 +93,39 @@ DEFINE_TEST(test_write_compress_bzip2)
assertEqualString(path, archive_entry_pathname(ae));
assertEqualInt((int)datasize, archive_entry_size(ae));
}
- assert(0 == archive_read_close(a));
- assert(0 == archive_read_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
/*
* Repeat the cycle again, this time setting some compression
* options.
*/
assert((a = archive_write_new()) != NULL);
- assertA(0 == archive_write_set_format_ustar(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_write_set_bytes_per_block(a, 10));
- assertA(0 == archive_write_set_compression_bzip2(a));
- assertEqualIntA(a, ARCHIVE_WARN,
- archive_write_set_compressor_options(a, "nonexistent-option=0"));
- assertEqualIntA(a, ARCHIVE_WARN,
- archive_write_set_compressor_options(a, "compression-level=abc"));
- assertEqualIntA(a, ARCHIVE_WARN,
- archive_write_set_compressor_options(a, "compression-level=99"));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_bzip2(a));
+ assertEqualIntA(a, ARCHIVE_FAILED,
+ archive_write_set_filter_option(a, NULL, "nonexistent-option", "0"));
+ assertEqualIntA(a, ARCHIVE_FAILED,
+ archive_write_set_filter_option(a, NULL, "compression-level", "abc"));
+ assertEqualIntA(a, ARCHIVE_FAILED,
+ archive_write_set_filter_option(a, NULL, "compression-level", "99"));
assertEqualIntA(a, ARCHIVE_OK,
- archive_write_set_compressor_options(a, "compression-level=9"));
- assertA(0 == archive_write_open_memory(a, buff, buffsize, &used2));
+ archive_write_set_filter_option(a, NULL, "compression-level", "9"));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2));
for (i = 0; i < 999; i++) {
sprintf(path, "file%03d", i);
assert((ae = archive_entry_new()) != NULL);
archive_entry_copy_pathname(ae, path);
archive_entry_set_size(ae, datasize);
archive_entry_set_filetype(ae, AE_IFREG);
- assertA(0 == archive_write_header(a, ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
assertA(datasize == (size_t)archive_write_data(a, data, datasize));
archive_entry_free(ae);
}
- archive_write_close(a);
- assert(0 == archive_write_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/* Curiously, this test fails; the test data above compresses
* better at default compression than at level 9. */
@@ -136,9 +136,9 @@ DEFINE_TEST(test_write_compress_bzip2)
*/
assert((a = archive_read_new()) != NULL);
- assertA(0 == archive_read_support_format_all(a));
- assertA(0 == archive_read_support_compression_all(a));
- assertA(0 == archive_read_open_memory(a, buff, used2));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used2));
for (i = 0; i < 999; i++) {
sprintf(path, "file%03d", i);
if (!assertEqualInt(0, archive_read_next_header(a, &ae)))
@@ -146,34 +146,34 @@ DEFINE_TEST(test_write_compress_bzip2)
assertEqualString(path, archive_entry_pathname(ae));
assertEqualInt((int)datasize, archive_entry_size(ae));
}
- assert(0 == archive_read_close(a));
- assert(0 == archive_read_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
/*
* Repeat again, with much lower compression.
*/
assert((a = archive_write_new()) != NULL);
- assertA(0 == archive_write_set_format_ustar(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_write_set_bytes_per_block(a, 10));
- assertA(0 == archive_write_set_compression_bzip2(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_bzip2(a));
assertEqualIntA(a, ARCHIVE_OK,
- archive_write_set_compressor_options(a, "compression-level=1"));
- assertA(0 == archive_write_open_memory(a, buff, buffsize, &used2));
+ archive_write_set_filter_option(a, NULL, "compression-level", "1"));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2));
for (i = 0; i < 999; i++) {
sprintf(path, "file%03d", i);
assert((ae = archive_entry_new()) != NULL);
archive_entry_copy_pathname(ae, path);
archive_entry_set_size(ae, datasize);
archive_entry_set_filetype(ae, AE_IFREG);
- assertA(0 == archive_write_header(a, ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
failure("Writing file %s", path);
assertEqualIntA(a, datasize,
(size_t)archive_write_data(a, data, datasize));
archive_entry_free(ae);
}
- archive_write_close(a);
- assert(0 == archive_write_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/* Level 0 really does result in larger data. */
failure("Compression-level=0 wrote %d bytes; default wrote %d bytes",
@@ -181,9 +181,9 @@ DEFINE_TEST(test_write_compress_bzip2)
assert(used2 > used1);
assert((a = archive_read_new()) != NULL);
- assertA(0 == archive_read_support_format_all(a));
- assertA(0 == archive_read_support_compression_all(a));
- assertA(0 == archive_read_open_memory(a, buff, used2));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used2));
for (i = 0; i < 999; i++) {
sprintf(path, "file%03d", i);
if (!assertEqualInt(0, archive_read_next_header(a, &ae)))
@@ -191,8 +191,8 @@ DEFINE_TEST(test_write_compress_bzip2)
assertEqualString(path, archive_entry_pathname(ae));
assertEqualInt((int)datasize, archive_entry_size(ae));
}
- assert(0 == archive_read_close(a));
- assert(0 == archive_read_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
/*
* Test various premature shutdown scenarios to make sure we
@@ -200,25 +200,25 @@ DEFINE_TEST(test_write_compress_bzip2)
*/
assert((a = archive_write_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_bzip2(a));
- assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
assert((a = archive_write_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_bzip2(a));
assertEqualInt(ARCHIVE_OK, archive_write_close(a));
- assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
assert((a = archive_write_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_bzip2(a));
assertEqualInt(ARCHIVE_OK, archive_write_close(a));
- assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
assert((a = archive_write_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_bzip2(a));
- assertA(0 == archive_write_open_memory(a, buff, buffsize, &used2));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2));
assertEqualInt(ARCHIVE_OK, archive_write_close(a));
- assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/*
* Clean up.
diff --git a/libarchive/test/test_write_compress_gzip.c b/libarchive/test/test_write_compress_gzip.c
index ec55c8db6467..c8281e7b6f23 100644
--- a/libarchive/test/test_write_compress_gzip.c
+++ b/libarchive/test/test_write_compress_gzip.c
@@ -54,18 +54,20 @@ DEFINE_TEST(test_write_compress_gzip)
* Write a 100 files and read them all back.
*/
assert((a = archive_write_new()) != NULL);
- assertA(0 == archive_write_set_format_ustar(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_compression_compress(a));
r = archive_write_set_compression_gzip(a);
if (r == ARCHIVE_FATAL) {
skipping("gzip writing not supported on this platform");
- assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
return;
}
assertEqualIntA(a, ARCHIVE_OK,
archive_write_set_bytes_per_block(a, 10));
assertEqualInt(ARCHIVE_COMPRESSION_GZIP, archive_compression(a));
assertEqualString("gzip", archive_compression_name(a));
- assertA(0 == archive_write_open_memory(a, buff, buffsize, &used1));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used1));
assertEqualInt(ARCHIVE_COMPRESSION_GZIP, archive_compression(a));
assertEqualString("gzip", archive_compression_name(a));
assert((ae = archive_entry_new()) != NULL);
@@ -74,24 +76,22 @@ DEFINE_TEST(test_write_compress_gzip)
for (i = 0; i < 100; i++) {
sprintf(path, "file%03d", i);
archive_entry_copy_pathname(ae, path);
- assertA(0 == archive_write_header(a, ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
assertA(datasize
== (size_t)archive_write_data(a, data, datasize));
}
archive_entry_free(ae);
- archive_write_close(a);
- assert(0 == archive_write_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
assert((a = archive_read_new()) != NULL);
- assertA(0 == archive_read_support_format_all(a));
- r = archive_read_support_compression_gzip(a);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ r = archive_read_support_filter_gzip(a);
if (r == ARCHIVE_WARN) {
skipping("Can't verify gzip writing by reading back;"
" gzip reading not fully supported on this platform");
} else {
assertEqualIntA(a, ARCHIVE_OK,
- archive_read_support_compression_all(a));
- assertEqualIntA(a, ARCHIVE_OK,
archive_read_open_memory(a, buff, used1));
for (i = 0; i < 100; i++) {
sprintf(path, "file%03d", i);
@@ -103,38 +103,42 @@ DEFINE_TEST(test_write_compress_gzip)
}
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
}
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
/*
* Repeat the cycle again, this time setting some compression
* options.
*/
assert((a = archive_write_new()) != NULL);
- assertA(0 == archive_write_set_format_ustar(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_write_set_bytes_per_block(a, 10));
- assertA(0 == archive_write_set_compression_gzip(a));
- assertEqualIntA(a, ARCHIVE_WARN,
- archive_write_set_compressor_options(a, "nonexistent-option=0"));
- assertEqualIntA(a, ARCHIVE_WARN,
- archive_write_set_compressor_options(a, "compression-level=abc"));
- assertEqualIntA(a, ARCHIVE_WARN,
- archive_write_set_compressor_options(a, "compression-level=99"));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_gzip(a));
+ assertEqualIntA(a, ARCHIVE_FAILED,
+ archive_write_set_options(a, "gzip:nonexistent-option=0"));
assertEqualIntA(a, ARCHIVE_OK,
- archive_write_set_compressor_options(a, "compression-level=9"));
- assertA(0 == archive_write_open_memory(a, buff, buffsize, &used2));
+ archive_write_set_options(a, "gzip:compression-level=0"));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_filter_option(a, NULL, "compression-level", "9"));
+ assertEqualIntA(a, ARCHIVE_FAILED,
+ archive_write_set_filter_option(a, NULL, "compression-level", "abc"));
+ assertEqualIntA(a, ARCHIVE_FAILED,
+ archive_write_set_filter_option(a, NULL, "compression-level", "99"));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_options(a, "gzip:compression-level=9"));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2));
for (i = 0; i < 100; i++) {
sprintf(path, "file%03d", i);
assert((ae = archive_entry_new()) != NULL);
archive_entry_copy_pathname(ae, path);
archive_entry_set_size(ae, datasize);
archive_entry_set_filetype(ae, AE_IFREG);
- assertA(0 == archive_write_header(a, ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
assertA(datasize == (size_t)archive_write_data(a, data, datasize));
archive_entry_free(ae);
}
- archive_write_close(a);
- assert(0 == archive_write_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/* Curiously, this test fails; the test data above compresses
* better at default compression than at level 9. */
@@ -146,12 +150,12 @@ DEFINE_TEST(test_write_compress_gzip)
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
- r = archive_read_support_compression_gzip(a);
+ r = archive_read_support_filter_gzip(a);
if (r == ARCHIVE_WARN) {
skipping("gzip reading not fully supported on this platform");
} else {
assertEqualIntA(a, ARCHIVE_OK,
- archive_read_support_compression_all(a));
+ archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_open_memory(a, buff, used2));
for (i = 0; i < 100; i++) {
@@ -164,33 +168,33 @@ DEFINE_TEST(test_write_compress_gzip)
}
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
}
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
/*
* Repeat again, with much lower compression.
*/
assert((a = archive_write_new()) != NULL);
- assertA(0 == archive_write_set_format_ustar(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_write_set_bytes_per_block(a, 10));
- assertA(0 == archive_write_set_compression_gzip(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_gzip(a));
assertEqualIntA(a, ARCHIVE_OK,
- archive_write_set_compressor_options(a, "compression-level=0"));
- assertA(0 == archive_write_open_memory(a, buff, buffsize, &used2));
+ archive_write_set_filter_option(a, NULL, "compression-level", "0"));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2));
for (i = 0; i < 100; i++) {
sprintf(path, "file%03d", i);
assert((ae = archive_entry_new()) != NULL);
archive_entry_copy_pathname(ae, path);
archive_entry_set_size(ae, datasize);
archive_entry_set_filetype(ae, AE_IFREG);
- assertA(0 == archive_write_header(a, ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
failure("Writing file %s", path);
assertEqualIntA(a, datasize,
(size_t)archive_write_data(a, data, datasize));
archive_entry_free(ae);
}
- archive_write_close(a);
- assert(0 == archive_write_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/* Level 0 really does result in larger data. */
failure("Compression-level=0 wrote %d bytes; default wrote %d bytes",
@@ -198,9 +202,9 @@ DEFINE_TEST(test_write_compress_gzip)
assert(used2 > used1);
assert((a = archive_read_new()) != NULL);
- assertA(0 == archive_read_support_format_all(a));
- assertA(0 == archive_read_support_compression_all(a));
- r = archive_read_support_compression_gzip(a);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ r = archive_read_support_filter_gzip(a);
if (r == ARCHIVE_WARN) {
skipping("gzip reading not fully supported on this platform");
} else {
@@ -216,7 +220,7 @@ DEFINE_TEST(test_write_compress_gzip)
}
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
}
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
/*
* Test various premature shutdown scenarios to make sure we
@@ -224,25 +228,25 @@ DEFINE_TEST(test_write_compress_gzip)
*/
assert((a = archive_write_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_gzip(a));
- assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
assert((a = archive_write_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_gzip(a));
assertEqualInt(ARCHIVE_OK, archive_write_close(a));
- assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
assert((a = archive_write_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_gzip(a));
assertEqualInt(ARCHIVE_OK, archive_write_close(a));
- assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
assert((a = archive_write_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_gzip(a));
- assertA(0 == archive_write_open_memory(a, buff, buffsize, &used2));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2));
assertEqualInt(ARCHIVE_OK, archive_write_close(a));
- assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/*
* Clean up.
diff --git a/libarchive/test/test_write_compress_lzip.c b/libarchive/test/test_write_compress_lzip.c
new file mode 100644
index 000000000000..7dd8bcf24a25
--- /dev/null
+++ b/libarchive/test/test_write_compress_lzip.c
@@ -0,0 +1,247 @@
+/*-
+ * Copyright (c) 2010 Michihiro NAKAJIMA
+ * Copyright (c) 2007-2009 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+/*
+ * A basic exercise of lzip reading and writing.
+ *
+ */
+
+DEFINE_TEST(test_write_compress_lzip)
+{
+ struct archive_entry *ae;
+ struct archive* a;
+ char *buff, *data;
+ size_t buffsize, datasize;
+ char path[16];
+ size_t used1, used2;
+ int i, r;
+
+ buffsize = 2000000;
+ assert(NULL != (buff = (char *)malloc(buffsize)));
+
+ datasize = 10000;
+ assert(NULL != (data = (char *)malloc(datasize)));
+ memset(data, 0, datasize);
+
+ /*
+ * Write a 100 files and read them all back.
+ */
+ assert((a = archive_write_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
+ r = archive_write_set_compression_lzip(a);
+ if (r == ARCHIVE_FATAL) {
+ skipping("lzip writing not supported on this platform");
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+ return;
+ }
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_bytes_per_block(a, 10));
+ assertEqualInt(ARCHIVE_COMPRESSION_LZIP, archive_compression(a));
+ assertEqualString("lzip", archive_compression_name(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_open_memory(a, buff, buffsize, &used1));
+ assertEqualInt(ARCHIVE_COMPRESSION_LZIP, archive_compression(a));
+ assertEqualString("lzip", archive_compression_name(a));
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_filetype(ae, AE_IFREG);
+ archive_entry_set_size(ae, datasize);
+ for (i = 0; i < 100; i++) {
+ sprintf(path, "file%03d", i);
+ archive_entry_copy_pathname(ae, path);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ assertA(datasize
+ == (size_t)archive_write_data(a, data, datasize));
+ }
+ archive_entry_free(ae);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ r = archive_read_support_filter_lzip(a);
+ if (r == ARCHIVE_WARN) {
+ skipping("Can't verify lzip writing by reading back;"
+ " lzip reading not fully supported on this platform");
+ } else {
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_memory(a, buff, used1));
+ for (i = 0; i < 100; i++) {
+ sprintf(path, "file%03d", i);
+ if (!assertEqualInt(ARCHIVE_OK,
+ archive_read_next_header(a, &ae)))
+ break;
+ assertEqualString(path, archive_entry_pathname(ae));
+ assertEqualInt((int)datasize, archive_entry_size(ae));
+ }
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ }
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+ /*
+ * Repeat the cycle again, this time setting some compression
+ * options.
+ */
+ assert((a = archive_write_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_bytes_per_block(a, 10));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_lzip(a));
+ assertEqualIntA(a, ARCHIVE_FAILED,
+ archive_write_set_filter_option(a, NULL, "nonexistent-option", "0"));
+ assertEqualIntA(a, ARCHIVE_FAILED,
+ archive_write_set_filter_option(a, NULL, "compression-level", "abc"));
+ assertEqualIntA(a, ARCHIVE_FAILED,
+ archive_write_set_filter_option(a, NULL, "compression-level", "99"));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_filter_option(a, NULL, "compression-level", "9"));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2));
+ for (i = 0; i < 100; i++) {
+ sprintf(path, "file%03d", i);
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_copy_pathname(ae, path);
+ archive_entry_set_size(ae, datasize);
+ archive_entry_set_filetype(ae, AE_IFREG);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ assertA(datasize == (size_t)archive_write_data(a, data, datasize));
+ archive_entry_free(ae);
+ }
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ r = archive_read_support_filter_lzip(a);
+ if (r == ARCHIVE_WARN) {
+ skipping("lzip reading not fully supported on this platform");
+ } else {
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_memory(a, buff, used2));
+ for (i = 0; i < 100; i++) {
+ sprintf(path, "file%03d", i);
+ failure("Trying to read %s", path);
+ if (!assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_next_header(a, &ae)))
+ break;
+ assertEqualString(path, archive_entry_pathname(ae));
+ assertEqualInt((int)datasize, archive_entry_size(ae));
+ }
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ }
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+ /*
+ * Repeat again, with much lower compression.
+ */
+ assert((a = archive_write_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_bytes_per_block(a, 10));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_lzip(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_filter_option(a, NULL, "compression-level", "0"));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2));
+ for (i = 0; i < 100; i++) {
+ sprintf(path, "file%03d", i);
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_copy_pathname(ae, path);
+ archive_entry_set_size(ae, datasize);
+ archive_entry_set_filetype(ae, AE_IFREG);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ failure("Writing file %s", path);
+ assertEqualIntA(a, datasize,
+ (size_t)archive_write_data(a, data, datasize));
+ archive_entry_free(ae);
+ }
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* Level 0 really does result in larger data. */
+ failure("Compression-level=0 wrote %d bytes; default wrote %d bytes",
+ (int)used2, (int)used1);
+ assert(used2 > used1);
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ r = archive_read_support_filter_lzip(a);
+ if (r == ARCHIVE_WARN) {
+ skipping("lzip reading not fully supported on this platform");
+ } else {
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_memory(a, buff, used2));
+ for (i = 0; i < 100; i++) {
+ sprintf(path, "file%03d", i);
+ if (!assertEqualInt(ARCHIVE_OK,
+ archive_read_next_header(a, &ae)))
+ break;
+ assertEqualString(path, archive_entry_pathname(ae));
+ assertEqualInt((int)datasize, archive_entry_size(ae));
+ }
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ }
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+ /*
+ * Test various premature shutdown scenarios to make sure we
+ * don't crash or leak memory.
+ */
+ assert((a = archive_write_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_lzip(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ assert((a = archive_write_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_lzip(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ assert((a = archive_write_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_lzip(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ assert((a = archive_write_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_lzip(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2));
+ assertEqualInt(ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /*
+ * Clean up.
+ */
+ free(data);
+ free(buff);
+}
diff --git a/libarchive/test/test_write_compress_lzma.c b/libarchive/test/test_write_compress_lzma.c
index 30e1b7eae950..f3b9de369f2b 100644
--- a/libarchive/test/test_write_compress_lzma.c
+++ b/libarchive/test/test_write_compress_lzma.c
@@ -53,18 +53,19 @@ DEFINE_TEST(test_write_compress_lzma)
* Write a 100 files and read them all back.
*/
assert((a = archive_write_new()) != NULL);
- assertA(0 == archive_write_set_format_ustar(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
r = archive_write_set_compression_lzma(a);
if (r == ARCHIVE_FATAL) {
skipping("lzma writing not supported on this platform");
- assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
return;
}
assertEqualIntA(a, ARCHIVE_OK,
archive_write_set_bytes_per_block(a, 10));
assertEqualInt(ARCHIVE_COMPRESSION_LZMA, archive_compression(a));
assertEqualString("lzma", archive_compression_name(a));
- assertA(0 == archive_write_open_memory(a, buff, buffsize, &used1));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_open_memory(a, buff, buffsize, &used1));
assertEqualInt(ARCHIVE_COMPRESSION_LZMA, archive_compression(a));
assertEqualString("lzma", archive_compression_name(a));
assert((ae = archive_entry_new()) != NULL);
@@ -73,23 +74,23 @@ DEFINE_TEST(test_write_compress_lzma)
for (i = 0; i < 100; i++) {
sprintf(path, "file%03d", i);
archive_entry_copy_pathname(ae, path);
- assertA(0 == archive_write_header(a, ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
assertA(datasize
== (size_t)archive_write_data(a, data, datasize));
}
archive_entry_free(ae);
- archive_write_close(a);
- assert(0 == archive_write_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
assert((a = archive_read_new()) != NULL);
- assertA(0 == archive_read_support_format_all(a));
- r = archive_read_support_compression_lzma(a);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ r = archive_read_support_filter_lzma(a);
if (r == ARCHIVE_WARN) {
skipping("Can't verify lzma writing by reading back;"
" lzma reading not fully supported on this platform");
} else {
assertEqualIntA(a, ARCHIVE_OK,
- archive_read_support_compression_all(a));
+ archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_open_memory(a, buff, used1));
for (i = 0; i < 100; i++) {
@@ -102,48 +103,48 @@ DEFINE_TEST(test_write_compress_lzma)
}
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
}
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
/*
* Repeat the cycle again, this time setting some compression
* options.
*/
assert((a = archive_write_new()) != NULL);
- assertA(0 == archive_write_set_format_ustar(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_write_set_bytes_per_block(a, 10));
- assertA(0 == archive_write_set_compression_lzma(a));
- assertEqualIntA(a, ARCHIVE_WARN,
- archive_write_set_compressor_options(a, "nonexistent-option=0"));
- assertEqualIntA(a, ARCHIVE_WARN,
- archive_write_set_compressor_options(a, "compression-level=abc"));
- assertEqualIntA(a, ARCHIVE_WARN,
- archive_write_set_compressor_options(a, "compression-level=99"));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_lzma(a));
+ assertEqualIntA(a, ARCHIVE_FAILED,
+ archive_write_set_filter_option(a, NULL, "nonexistent-option", "0"));
+ assertEqualIntA(a, ARCHIVE_FAILED,
+ archive_write_set_filter_option(a, NULL, "compression-level", "abc"));
+ assertEqualIntA(a, ARCHIVE_FAILED,
+ archive_write_set_filter_option(a, NULL, "compression-level", "99"));
assertEqualIntA(a, ARCHIVE_OK,
- archive_write_set_compressor_options(a, "compression-level=9"));
- assertA(0 == archive_write_open_memory(a, buff, buffsize, &used2));
+ archive_write_set_filter_option(a, NULL, "compression-level", "9"));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2));
for (i = 0; i < 100; i++) {
sprintf(path, "file%03d", i);
assert((ae = archive_entry_new()) != NULL);
archive_entry_copy_pathname(ae, path);
archive_entry_set_size(ae, datasize);
archive_entry_set_filetype(ae, AE_IFREG);
- assertA(0 == archive_write_header(a, ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
assertA(datasize == (size_t)archive_write_data(a, data, datasize));
archive_entry_free(ae);
}
- archive_write_close(a);
- assert(0 == archive_write_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
- r = archive_read_support_compression_lzma(a);
+ r = archive_read_support_filter_lzma(a);
if (r == ARCHIVE_WARN) {
skipping("lzma reading not fully supported on this platform");
} else {
assertEqualIntA(a, ARCHIVE_OK,
- archive_read_support_compression_all(a));
+ archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_open_memory(a, buff, used2));
for (i = 0; i < 100; i++) {
@@ -157,33 +158,33 @@ DEFINE_TEST(test_write_compress_lzma)
}
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
}
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
/*
* Repeat again, with much lower compression.
*/
assert((a = archive_write_new()) != NULL);
- assertA(0 == archive_write_set_format_ustar(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_write_set_bytes_per_block(a, 10));
- assertA(0 == archive_write_set_compression_lzma(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_lzma(a));
assertEqualIntA(a, ARCHIVE_OK,
- archive_write_set_compressor_options(a, "compression-level=0"));
- assertA(0 == archive_write_open_memory(a, buff, buffsize, &used2));
+ archive_write_set_filter_option(a, NULL, "compression-level", "0"));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2));
for (i = 0; i < 100; i++) {
sprintf(path, "file%03d", i);
assert((ae = archive_entry_new()) != NULL);
archive_entry_copy_pathname(ae, path);
archive_entry_set_size(ae, datasize);
archive_entry_set_filetype(ae, AE_IFREG);
- assertA(0 == archive_write_header(a, ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
failure("Writing file %s", path);
assertEqualIntA(a, datasize,
(size_t)archive_write_data(a, data, datasize));
archive_entry_free(ae);
}
- archive_write_close(a);
- assert(0 == archive_write_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/* It would be nice to assert that compression-level=0 produced
* consistently larger/smaller results than the default compression,
@@ -196,9 +197,9 @@ DEFINE_TEST(test_write_compress_lzma)
*/
assert((a = archive_read_new()) != NULL);
- assertA(0 == archive_read_support_format_all(a));
- assertA(0 == archive_read_support_compression_all(a));
- r = archive_read_support_compression_lzma(a);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ r = archive_read_support_filter_lzma(a);
if (r == ARCHIVE_WARN) {
skipping("lzma reading not fully supported on this platform");
} else {
@@ -214,7 +215,7 @@ DEFINE_TEST(test_write_compress_lzma)
}
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
}
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
/*
* Test various premature shutdown scenarios to make sure we
@@ -222,25 +223,25 @@ DEFINE_TEST(test_write_compress_lzma)
*/
assert((a = archive_write_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_lzma(a));
- assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
assert((a = archive_write_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_lzma(a));
assertEqualInt(ARCHIVE_OK, archive_write_close(a));
- assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
assert((a = archive_write_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_lzma(a));
assertEqualInt(ARCHIVE_OK, archive_write_close(a));
- assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
assert((a = archive_write_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_lzma(a));
- assertA(0 == archive_write_open_memory(a, buff, buffsize, &used2));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2));
assertEqualInt(ARCHIVE_OK, archive_write_close(a));
- assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/*
* Clean up.
diff --git a/libarchive/test/test_write_compress_program.c b/libarchive/test/test_write_compress_program.c
index bae77e5341bb..ba005a68fe4f 100644
--- a/libarchive/test/test_write_compress_program.c
+++ b/libarchive/test/test_write_compress_program.c
@@ -30,9 +30,6 @@ char buff2[64];
DEFINE_TEST(test_write_compress_program)
{
-#if ARCHIVE_VERSION_NUMBER < 1009000
- skipping("archive_write_set_compress_program()");
-#else
struct archive_entry *ae;
struct archive *a;
size_t used;
@@ -52,7 +49,7 @@ DEFINE_TEST(test_write_compress_program)
if (r == ARCHIVE_FATAL) {
skipping("Write compression via external "
"program unsupported on this platform");
- archive_write_finish(a);
+ archive_write_free(a);
return;
}
assertA(0 == archive_write_set_bytes_per_block(a, blocksize));
@@ -75,29 +72,29 @@ DEFINE_TEST(test_write_compress_program)
assertA(8 == archive_write_data(a, "12345678", 9));
/* Close out the archive. */
- assertA(0 == archive_write_close(a));
- assertA(0 == archive_write_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/*
* Now, read the data back through the built-in gzip support.
*/
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
- assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a));
- r = archive_read_support_compression_gzip(a);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ r = archive_read_support_filter_gzip(a);
/* The compression_gzip() handler will fall back to gunzip
* automatically, but if we know gunzip isn't available, then
* skip the rest. */
if (r != ARCHIVE_OK && !canGunzip()) {
skipping("No libz and no gunzip program, "
"unable to verify gzip compression");
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
return;
}
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used));
if (!assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae))) {
- archive_read_finish(a);
+ archive_read_free(a);
return;
}
@@ -113,6 +110,5 @@ DEFINE_TEST(test_write_compress_program)
/* Verify the end of the archive. */
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
-#endif
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_write_compress_xz.c b/libarchive/test/test_write_compress_xz.c
index d5c4c951ba81..281dbcf55752 100644
--- a/libarchive/test/test_write_compress_xz.c
+++ b/libarchive/test/test_write_compress_xz.c
@@ -54,18 +54,18 @@ DEFINE_TEST(test_write_compress_xz)
* Write a 100 files and read them all back.
*/
assert((a = archive_write_new()) != NULL);
- assertA(0 == archive_write_set_format_ustar(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
r = archive_write_set_compression_xz(a);
if (r == ARCHIVE_FATAL) {
skipping("xz writing not supported on this platform");
- assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
return;
}
assertEqualIntA(a, ARCHIVE_OK,
archive_write_set_bytes_per_block(a, 10));
assertEqualInt(ARCHIVE_COMPRESSION_XZ, archive_compression(a));
assertEqualString("xz", archive_compression_name(a));
- assertA(0 == archive_write_open_memory(a, buff, buffsize, &used1));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used1));
assertEqualInt(ARCHIVE_COMPRESSION_XZ, archive_compression(a));
assertEqualString("xz", archive_compression_name(a));
assert((ae = archive_entry_new()) != NULL);
@@ -74,23 +74,23 @@ DEFINE_TEST(test_write_compress_xz)
for (i = 0; i < 100; i++) {
sprintf(path, "file%03d", i);
archive_entry_copy_pathname(ae, path);
- assertA(0 == archive_write_header(a, ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
assertA(datasize
== (size_t)archive_write_data(a, data, datasize));
}
archive_entry_free(ae);
- archive_write_close(a);
- assert(0 == archive_write_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
assert((a = archive_read_new()) != NULL);
- assertA(0 == archive_read_support_format_all(a));
- r = archive_read_support_compression_xz(a);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ r = archive_read_support_filter_xz(a);
if (r == ARCHIVE_WARN) {
skipping("Can't verify xz writing by reading back;"
" xz reading not fully supported on this platform");
} else {
assertEqualIntA(a, ARCHIVE_OK,
- archive_read_support_compression_all(a));
+ archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_open_memory(a, buff, used1));
for (i = 0; i < 100; i++) {
@@ -103,38 +103,38 @@ DEFINE_TEST(test_write_compress_xz)
}
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
}
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
/*
* Repeat the cycle again, this time setting some compression
* options.
*/
assert((a = archive_write_new()) != NULL);
- assertA(0 == archive_write_set_format_ustar(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_write_set_bytes_per_block(a, 10));
- assertA(0 == archive_write_set_compression_xz(a));
- assertEqualIntA(a, ARCHIVE_WARN,
- archive_write_set_compressor_options(a, "nonexistent-option=0"));
- assertEqualIntA(a, ARCHIVE_WARN,
- archive_write_set_compressor_options(a, "compression-level=abc"));
- assertEqualIntA(a, ARCHIVE_WARN,
- archive_write_set_compressor_options(a, "compression-level=99"));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_xz(a));
+ assertEqualIntA(a, ARCHIVE_FAILED,
+ archive_write_set_filter_option(a, NULL, "nonexistent-option", "0"));
+ assertEqualIntA(a, ARCHIVE_FAILED,
+ archive_write_set_filter_option(a, NULL, "compression-level", "abc"));
+ assertEqualIntA(a, ARCHIVE_FAILED,
+ archive_write_set_filter_option(a, NULL, "compression-level", "99"));
assertEqualIntA(a, ARCHIVE_OK,
- archive_write_set_compressor_options(a, "compression-level=9"));
- assertA(0 == archive_write_open_memory(a, buff, buffsize, &used2));
+ archive_write_set_filter_option(a, NULL, "compression-level", "9"));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2));
for (i = 0; i < 100; i++) {
sprintf(path, "file%03d", i);
assert((ae = archive_entry_new()) != NULL);
archive_entry_copy_pathname(ae, path);
archive_entry_set_size(ae, datasize);
archive_entry_set_filetype(ae, AE_IFREG);
- assertA(0 == archive_write_header(a, ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
assertA(datasize == (size_t)archive_write_data(a, data, datasize));
archive_entry_free(ae);
}
- archive_write_close(a);
- assert(0 == archive_write_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/* Curiously, this test fails; the test data above compresses
* better at default compression than at level 9. */
@@ -146,12 +146,12 @@ DEFINE_TEST(test_write_compress_xz)
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
- r = archive_read_support_compression_xz(a);
+ r = archive_read_support_filter_xz(a);
if (r == ARCHIVE_WARN) {
skipping("xz reading not fully supported on this platform");
} else {
assertEqualIntA(a, ARCHIVE_OK,
- archive_read_support_compression_all(a));
+ archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_open_memory(a, buff, used2));
for (i = 0; i < 100; i++) {
@@ -165,33 +165,33 @@ DEFINE_TEST(test_write_compress_xz)
}
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
}
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
/*
* Repeat again, with much lower compression.
*/
assert((a = archive_write_new()) != NULL);
- assertA(0 == archive_write_set_format_ustar(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_write_set_bytes_per_block(a, 10));
- assertA(0 == archive_write_set_compression_xz(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_xz(a));
assertEqualIntA(a, ARCHIVE_OK,
- archive_write_set_compressor_options(a, "compression-level=0"));
- assertA(0 == archive_write_open_memory(a, buff, buffsize, &used2));
+ archive_write_set_filter_option(a, NULL, "compression-level", "0"));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2));
for (i = 0; i < 100; i++) {
sprintf(path, "file%03d", i);
assert((ae = archive_entry_new()) != NULL);
archive_entry_copy_pathname(ae, path);
archive_entry_set_size(ae, datasize);
archive_entry_set_filetype(ae, AE_IFREG);
- assertA(0 == archive_write_header(a, ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
failure("Writing file %s", path);
assertEqualIntA(a, datasize,
(size_t)archive_write_data(a, data, datasize));
archive_entry_free(ae);
}
- archive_write_close(a);
- assert(0 == archive_write_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/* I would like to assert that compression-level=0 results in
* larger data than the default compression, but that's not true
@@ -203,9 +203,9 @@ DEFINE_TEST(test_write_compress_xz)
*/
assert((a = archive_read_new()) != NULL);
- assertA(0 == archive_read_support_format_all(a));
- assertA(0 == archive_read_support_compression_all(a));
- r = archive_read_support_compression_xz(a);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ r = archive_read_support_filter_xz(a);
if (r == ARCHIVE_WARN) {
skipping("xz reading not fully supported on this platform");
} else {
@@ -221,7 +221,7 @@ DEFINE_TEST(test_write_compress_xz)
}
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
}
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
/*
* Test various premature shutdown scenarios to make sure we
@@ -229,25 +229,25 @@ DEFINE_TEST(test_write_compress_xz)
*/
assert((a = archive_write_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_xz(a));
- assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
assert((a = archive_write_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_xz(a));
assertEqualInt(ARCHIVE_OK, archive_write_close(a));
- assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
assert((a = archive_write_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_xz(a));
assertEqualInt(ARCHIVE_OK, archive_write_close(a));
- assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
assert((a = archive_write_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_xz(a));
- assertA(0 == archive_write_open_memory(a, buff, buffsize, &used2));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2));
assertEqualInt(ARCHIVE_OK, archive_write_close(a));
- assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/*
* Clean up.
diff --git a/libarchive/test/test_write_disk.c b/libarchive/test/test_write_disk.c
index 169f4f239965..60bcdc24edf5 100644
--- a/libarchive/test/test_write_disk.c
+++ b/libarchive/test/test_write_disk.c
@@ -25,8 +25,6 @@
#include "test.h"
__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_disk.c 201247 2009-12-30 05:59:21Z kientzle $");
-#if ARCHIVE_VERSION_NUMBER >= 1009000
-
#define UMASK 022
/*
* When comparing mode values, ignore high-order bits
@@ -47,11 +45,8 @@ static void create(struct archive_entry *ae, const char *msg)
failure("%s", msg);
assertEqualIntA(ad, 0, archive_write_header(ad, ae));
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_write_finish(ad);
-#else
- assertEqualInt(0, archive_write_finish(ad));
-#endif
+ assertEqualInt(0, archive_write_free(ad));
+
/* Test the entries on disk. */
assert(0 == stat(archive_entry_pathname(ae), &st));
failure("%s", msg);
@@ -97,11 +92,8 @@ static void create_reg_file(struct archive_entry *ae, const char *msg)
assertEqualIntA(ad, 0, archive_write_header(ad, ae));
assertEqualInt(sizeof(data), archive_write_data(ad, data, sizeof(data)));
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_write_finish(ad);
-#else
- assertEqualInt(0, archive_write_finish(ad));
-#endif
+ assertEqualInt(0, archive_write_free(ad));
+
/* Test the entries on disk. */
assertIsReg(archive_entry_pathname(ae), archive_entry_mode(ae) & 0777);
assertFileSize(archive_entry_pathname(ae), sizeof(data));
@@ -136,7 +128,7 @@ static void create_reg_file2(struct archive_entry *ae, const char *msg)
archive_write_data_block(ad, data + i, 1000, i));
}
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
- assertEqualInt(0, archive_write_finish(ad));
+ assertEqualInt(0, archive_write_free(ad));
/* Test the entries on disk. */
assertIsReg(archive_entry_pathname(ae), archive_entry_mode(ae) & 0777);
@@ -159,11 +151,8 @@ static void create_reg_file3(struct archive_entry *ae, const char *msg)
assertEqualIntA(ad, 0, archive_write_header(ad, ae));
assertEqualInt(5, archive_write_data(ad, data, sizeof(data)));
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_write_finish(ad);
-#else
- assertEqualInt(0, archive_write_finish(ad));
-#endif
+ assertEqualInt(0, archive_write_free(ad));
+
/* Test the entry on disk. */
assert(0 == stat(archive_entry_pathname(ae), &st));
failure("st.st_mode=%o archive_entry_mode(ae)=%o",
@@ -188,11 +177,8 @@ static void create_reg_file4(struct archive_entry *ae, const char *msg)
assertEqualInt(ARCHIVE_OK,
archive_write_data_block(ad, data, sizeof(data), 0));
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_write_finish(ad);
-#else
- assertEqualInt(0, archive_write_finish(ad));
-#endif
+ assertEqualInt(0, archive_write_free(ad));
+
/* Test the entry on disk. */
assert(0 == stat(archive_entry_pathname(ae), &st));
failure("st.st_mode=%o archive_entry_mode(ae)=%o",
@@ -209,48 +195,54 @@ static void create_reg_file_win(struct archive_entry *ae, const char *msg)
{
static const char data[]="abcdefghijklmnopqrstuvwxyz";
struct archive *ad;
- struct stat st;
- char *p, *fname;
+ struct _stat st;
+ wchar_t *p, *fname;
size_t l;
/* Write the entry to disk. */
assert((ad = archive_write_disk_new()) != NULL);
- archive_write_disk_set_options(ad, ARCHIVE_EXTRACT_TIME);
+ archive_write_disk_set_options(ad, ARCHIVE_EXTRACT_TIME);
failure("%s", msg);
archive_entry_set_size(ae, sizeof(data));
archive_entry_set_mtime(ae, 123456789, 0);
assertEqualIntA(ad, 0, archive_write_header(ad, ae));
assertEqualInt(sizeof(data), archive_write_data(ad, data, sizeof(data)));
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_write_finish(ad);
-#else
- assertEqualInt(0, archive_write_finish(ad));
-#endif
+ assertEqualInt(0, archive_write_free(ad));
+
/* Test the entries on disk. */
- l = strlen(archive_entry_pathname(ae));
- fname = malloc(l + 1);
+ l = wcslen(archive_entry_pathname_w(ae));
+ fname = malloc((l + 1) * sizeof(wchar_t));
assert(NULL != fname);
- strcpy(fname, archive_entry_pathname(ae));
+ wcscpy(fname, archive_entry_pathname_w(ae));
+ p = fname;
+ /* Skip leading drive letter from archives created
+ * on Windows. */
+ if (((p[0] >= L'a' && p[0] <= L'z') ||
+ (p[0] >= L'A' && p[0] <= L'Z')) &&
+ p[1] == L':' && p[2] == L'\\') {
+ p += 3;
+ }
/* Replace unusable characters in Windows to '_' */
- for (p = fname; *p != '\0'; p++)
- if (*p == ':' || *p == '*' || *p == '?' ||
- *p == '"' || *p == '<' || *p == '>' || *p == '|')
+ for (; *p != L'\0'; p++)
+ if (*p == L':' || *p == L'*' || *p == L'?' ||
+ *p == L'"' || *p == L'<' || *p == L'>' || *p == L'|')
*p = '_';
- assert(0 == stat(fname, &st));
+ assert(0 == _wstat(fname, &st));
failure("st.st_mode=%o archive_entry_mode(ae)=%o",
st.st_mode, archive_entry_mode(ae));
assertEqualInt(st.st_size, sizeof(data));
+ free(fname);
}
#endif /* _WIN32 && !__CYGWIN__ */
-#endif
DEFINE_TEST(test_write_disk)
{
-#if ARCHIVE_VERSION_NUMBER < 1009000
- skipping("archive_write_disk interface");
-#else
struct archive_entry *ae;
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ wchar_t *fullpath;
+ DWORD l;
+#endif
/* Force the umask to something predictable. */
assertUmask(UMASK);
@@ -314,7 +306,7 @@ DEFINE_TEST(test_write_disk)
#if defined(_WIN32) && !defined(__CYGWIN__)
/* A file with unusable characters in its file name. */
assert((ae = archive_entry_new()) != NULL);
- archive_entry_copy_pathname(ae, "f:i*l?e\"f<i>l|e");
+ archive_entry_copy_pathname_w(ae, L"f:i*l?e\"f<i>l|e");
archive_entry_set_mode(ae, S_IFREG | 0755);
create_reg_file_win(ae, "Test creating a regular file"
" with unusable characters in its file name");
@@ -322,11 +314,36 @@ DEFINE_TEST(test_write_disk)
/* A file with unusable characters in its directory name. */
assert((ae = archive_entry_new()) != NULL);
- archive_entry_copy_pathname(ae, "d:i*r?e\"c<t>o|ry/file1");
+ archive_entry_copy_pathname_w(ae, L"d:i*r?e\"c<t>o|ry/file1");
+ archive_entry_set_mode(ae, S_IFREG | 0755);
+ create_reg_file_win(ae, "Test creating a regular file"
+ " with unusable characters in its file name");
+ archive_entry_free(ae);
+
+ /* A full-path file with unusable characters in its file name. */
+ assert((l = GetCurrentDirectoryW(0, NULL)) != 0);
+ assert((fullpath = malloc((l + 20) * sizeof(wchar_t))) != NULL);
+ assert((l = GetCurrentDirectoryW(l, fullpath)) != 0);
+ wcscat(fullpath, L"\\f:i*l?e\"f<i>l|e");
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_copy_pathname_w(ae, fullpath);
archive_entry_set_mode(ae, S_IFREG | 0755);
create_reg_file_win(ae, "Test creating a regular file"
" with unusable characters in its file name");
archive_entry_free(ae);
+ free(fullpath);
+
+ /* A full-path file with unusable characters in its directory name. */
+ assert((l = GetCurrentDirectoryW(0, NULL)) != 0);
+ assert((fullpath = malloc((l + 30) * sizeof(wchar_t))) != NULL);
+ assert((l = GetCurrentDirectoryW(l, fullpath)) != 0);
+ wcscat(fullpath, L"\\d:i*r?e\"c<t>o|ry/file1");
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_copy_pathname_w(ae, fullpath);
+ archive_entry_set_mode(ae, S_IFREG | 0755);
+ create_reg_file_win(ae, "Test creating a regular file"
+ " with unusable characters in its file name");
+ archive_entry_free(ae);
+ free(fullpath);
#endif /* _WIN32 && !__CYGWIN__ */
-#endif
}
diff --git a/libarchive/test/test_write_disk_failures.c b/libarchive/test/test_write_disk_failures.c
index 991fa3d4fe6e..c563ce1d3212 100644
--- a/libarchive/test/test_write_disk_failures.c
+++ b/libarchive/test/test_write_disk_failures.c
@@ -25,16 +25,9 @@
#include "test.h"
__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_disk_failures.c 201247 2009-12-30 05:59:21Z kientzle $");
-#if ARCHIVE_VERSION_NUMBER >= 1009000
-
-#define UMASK 022
-
-
-#endif
-
DEFINE_TEST(test_write_disk_failures)
{
-#if ARCHIVE_VERSION_NUMBER < 1009000 || (defined(_WIN32) && !defined(__CYGWIN__))
+#if defined(_WIN32) && !defined(__CYGWIN__)
skipping("archive_write_disk interface");
#else
struct archive_entry *ae;
@@ -42,7 +35,7 @@ DEFINE_TEST(test_write_disk_failures)
int fd;
/* Force the umask to something predictable. */
- assertUmask(UMASK);
+ assertUmask(022);
/* A directory that we can't write to. */
assertMakeDir("dir", 0555);
@@ -66,7 +59,7 @@ DEFINE_TEST(test_write_disk_failures)
archive_entry_set_mtime(ae, 123456789, 0);
assertEqualIntA(a, ARCHIVE_FAILED, archive_write_header(a, ae));
assertEqualIntA(a, 0, archive_write_finish_entry(a));
- assertEqualInt(0, archive_write_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
archive_entry_free(ae);
#endif
}
diff --git a/libarchive/test/test_write_disk_hardlink.c b/libarchive/test/test_write_disk_hardlink.c
index 934aa08d5782..f80821c7e367 100644
--- a/libarchive/test/test_write_disk_hardlink.c
+++ b/libarchive/test/test_write_disk_hardlink.c
@@ -37,8 +37,8 @@ __FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_disk_hardlink.c 201247 2
/*
* Exercise hardlink recreation.
*
- * File permissions are chosen so that the authoritive entry
- * has the correct permission and the non-authoritive versions
+ * File permissions are chosen so that the authoritative entry
+ * has the correct permission and the non-authoritative versions
* are just writeable files.
*/
DEFINE_TEST(test_write_disk_hardlink)
@@ -157,11 +157,7 @@ DEFINE_TEST(test_write_disk_hardlink)
archive_entry_set_mode(ae, S_IFREG | 0600);
archive_entry_set_size(ae, 0);
assertEqualIntA(ad, 0, archive_write_header(ad, ae));
-#if ARCHIVE_VERSION_NUMBER < 3000000
assertEqualInt(ARCHIVE_WARN, archive_write_data(ad, data, 1));
-#else
- assertEqualInt(-1, archive_write_data(ad, data, 1));
-#endif
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
archive_entry_free(ae);
@@ -178,14 +174,14 @@ DEFINE_TEST(test_write_disk_hardlink)
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
}
archive_entry_free(ae);
- assertEqualInt(0, archive_write_finish(ad));
+ assertEqualInt(0, archive_write_free(ad));
/* Test the entries on disk. */
/* Test #1 */
/* If the hardlink was successfully created and the archive
* doesn't carry data for it, we consider it to be
- * non-authoritive for meta data as well. This is consistent
+ * non-authoritative for meta data as well. This is consistent
* with GNU tar and BSD pax. */
assertIsReg("link1a", 0755 & ~UMASK);
assertFileSize("link1a", sizeof(data));
diff --git a/libarchive/test/test_write_disk_lookup.c b/libarchive/test/test_write_disk_lookup.c
new file mode 100644
index 000000000000..2a5ea4abb9cb
--- /dev/null
+++ b/libarchive/test/test_write_disk_lookup.c
@@ -0,0 +1,150 @@
+/*-
+ * Copyright (c) 2003-2010 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+static void
+group_cleanup(void *d)
+{
+ int *mp = d;
+ assertEqualInt(*mp, 0x13579);
+ *mp = 0x2468;
+}
+
+static int64_t
+group_lookup(void *d, const char *name, int64_t g)
+{
+ int *mp = d;
+ assertEqualInt(*mp, 0x13579);
+ if (strcmp(name, "FOOGROUP"))
+ return (1);
+ return (73);
+}
+
+static void
+user_cleanup(void *d)
+{
+ int *mp = d;
+ assertEqualInt(*mp, 0x1234);
+ *mp = 0x2345;
+}
+
+static int64_t
+user_lookup(void *d, const char *name, int64_t u)
+{
+ int *mp = d;
+ assertEqualInt(*mp, 0x1234);
+ if (strcmp("FOO", name) == 0)
+ return (2);
+ return (74);
+}
+
+DEFINE_TEST(test_write_disk_lookup)
+{
+ struct archive *a;
+ int gmagic = 0x13579, umagic = 0x1234;
+ int64_t id;
+
+ assert((a = archive_write_disk_new()) != NULL);
+
+ /* Default uname/gname lookups always return ID. */
+ assertEqualInt(0, archive_write_disk_gid(a, "", 0));
+ assertEqualInt(12, archive_write_disk_gid(a, "root", 12));
+ assertEqualInt(12, archive_write_disk_gid(a, "wheel", 12));
+ assertEqualInt(0, archive_write_disk_uid(a, "", 0));
+ assertEqualInt(18, archive_write_disk_uid(a, "root", 18));
+
+ /* Register some weird lookup functions. */
+ assertEqualInt(ARCHIVE_OK, archive_write_disk_set_group_lookup(a,
+ &gmagic, &group_lookup, &group_cleanup));
+ /* Verify that our new function got called. */
+ assertEqualInt(73, archive_write_disk_gid(a, "FOOGROUP", 8));
+ assertEqualInt(1, archive_write_disk_gid(a, "NOTFOOGROUP", 8));
+
+ /* De-register. */
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_disk_set_group_lookup(a, NULL, NULL, NULL));
+ /* Ensure our cleanup function got called. */
+ assertEqualInt(gmagic, 0x2468);
+
+ /* Same thing with uname lookup.... */
+ assertEqualInt(ARCHIVE_OK, archive_write_disk_set_user_lookup(a,
+ &umagic, &user_lookup, &user_cleanup));
+ assertEqualInt(2, archive_write_disk_uid(a, "FOO", 0));
+ assertEqualInt(74, archive_write_disk_uid(a, "NOTFOO", 1));
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_disk_set_user_lookup(a, NULL, NULL, NULL));
+ assertEqualInt(umagic, 0x2345);
+
+ /* Try the standard lookup functions. */
+ if (archive_write_disk_set_standard_lookup(a) != ARCHIVE_OK) {
+ skipping("standard uname/gname lookup");
+ } else {
+ /* Try a few common names for group #0. */
+ id = archive_write_disk_gid(a, "wheel", 8);
+ if (id != 0)
+ id = archive_write_disk_gid(a, "root", 8);
+ failure("Unable to verify lookup of group #0");
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ /* Not yet implemented on Windows. */
+ assertEqualInt(8, id);
+#else
+ assertEqualInt(0, id);
+#endif
+
+ /* Try a few common names for user #0. */
+ id = archive_write_disk_uid(a, "root", 8);
+ failure("Unable to verify lookup of user #0");
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ /* Not yet implemented on Windows. */
+ assertEqualInt(8, id);
+#else
+ assertEqualInt(0, id);
+#endif
+ }
+
+ /* Deregister again and verify the default lookups again. */
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_disk_set_group_lookup(a, NULL, NULL, NULL));
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_disk_set_user_lookup(a, NULL, NULL, NULL));
+ assertEqualInt(0, archive_write_disk_gid(a, "", 0));
+ assertEqualInt(0, archive_write_disk_uid(a, "", 0));
+
+ /* Re-register our custom handlers. */
+ gmagic = 0x13579;
+ umagic = 0x1234;
+ assertEqualInt(ARCHIVE_OK, archive_write_disk_set_group_lookup(a,
+ &gmagic, &group_lookup, &group_cleanup));
+ assertEqualInt(ARCHIVE_OK, archive_write_disk_set_user_lookup(a,
+ &umagic, &user_lookup, &user_cleanup));
+
+ /* Destroy the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+ /* Verify our cleanup functions got called. */
+ assertEqualInt(gmagic, 0x2468);
+ assertEqualInt(umagic, 0x2345);
+}
diff --git a/libarchive/test/test_write_disk_perms.c b/libarchive/test/test_write_disk_perms.c
index 207444833e7a..7861735bd573 100644
--- a/libarchive/test/test_write_disk_perms.c
+++ b/libarchive/test/test_write_disk_perms.c
@@ -25,7 +25,7 @@
#include "test.h"
__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_disk_perms.c 201247 2009-12-30 05:59:21Z kientzle $");
-#if ARCHIVE_VERSION_NUMBER >= 1009000 && (!defined(_WIN32) || defined(__CYGWIN__))
+#if !defined(_WIN32) || defined(__CYGWIN__)
#define UMASK 022
@@ -125,7 +125,7 @@ defaultgid(void)
DEFINE_TEST(test_write_disk_perms)
{
-#if ARCHIVE_VERSION_NUMBER < 1009000 || (defined(_WIN32) && !defined(__CYGWIN__))
+#if defined(_WIN32) && !defined(__CYGWIN__)
skipping("archive_write_disk interface");
#else
struct archive *a;
@@ -365,11 +365,7 @@ DEFINE_TEST(test_write_disk_perms)
assertEqualIntA(a,ARCHIVE_WARN,archive_write_finish_entry(a));
}
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_write_finish(a);
-#else
- assert(0 == archive_write_finish(a));
-#endif
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
archive_entry_free(ae);
/* Test the entries on disk. */
diff --git a/libarchive/test/test_write_disk_secure.c b/libarchive/test/test_write_disk_secure.c
index c14dadccfa6b..31c5bfd7c4b3 100644
--- a/libarchive/test/test_write_disk_secure.c
+++ b/libarchive/test/test_write_disk_secure.c
@@ -34,9 +34,9 @@ __FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_disk_secure.c 201247 200
DEFINE_TEST(test_write_disk_secure)
{
-#if ARCHIVE_VERSION_NUMBER < 1009000
- skipping("archive_write_disk interface");
-#elif !defined(_WIN32) || defined(__CYGWIN__)
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ skipping("archive_write_disk security checks not supported on Windows");
+#else
struct archive *a;
struct archive_entry *ae;
struct stat st;
@@ -178,7 +178,7 @@ DEFINE_TEST(test_write_disk_secure)
assert(S_ISDIR(st.st_mode));
archive_entry_free(ae);
- assert(0 == archive_write_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/* Test the entries on disk. */
assert(0 == lstat("dir", &st));
diff --git a/libarchive/test/test_write_disk_sparse.c b/libarchive/test/test_write_disk_sparse.c
index 638f0a4b26d3..d25b6c00637d 100644
--- a/libarchive/test/test_write_disk_sparse.c
+++ b/libarchive/test/test_write_disk_sparse.c
@@ -269,12 +269,12 @@ DEFINE_TEST(test_write_disk_sparse)
archive_write_disk_set_options(ad, 0);
verify_write_data(ad, 0);
verify_write_data_block(ad, 0);
- assertEqualInt(0, archive_write_finish(ad));
+ assertEqualInt(0, archive_write_free(ad));
assert((ad = archive_write_disk_new()) != NULL);
archive_write_disk_set_options(ad, ARCHIVE_EXTRACT_SPARSE);
verify_write_data(ad, 1);
verify_write_data_block(ad, 1);
- assertEqualInt(0, archive_write_finish(ad));
+ assertEqualInt(0, archive_write_free(ad));
}
diff --git a/libarchive/test/test_write_disk_symlink.c b/libarchive/test/test_write_disk_symlink.c
index 60d0bdcbb0e8..13089c78d894 100644
--- a/libarchive/test/test_write_disk_symlink.c
+++ b/libarchive/test/test_write_disk_symlink.c
@@ -99,7 +99,7 @@ DEFINE_TEST(test_write_disk_symlink)
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
archive_entry_free(ae);
- assertEqualInt(ARCHIVE_OK, archive_write_finish(ad));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(ad));
/* Test the entries on disk. */
diff --git a/libarchive/test/test_write_disk_times.c b/libarchive/test/test_write_disk_times.c
index 9ecbff69b568..568d04c0017d 100644
--- a/libarchive/test/test_write_disk_times.c
+++ b/libarchive/test/test_write_disk_times.c
@@ -163,5 +163,5 @@ DEFINE_TEST(test_write_disk_times)
skipping("Platform-specific time restore tests");
#endif
- archive_write_finish(a);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
}
diff --git a/libarchive/test/test_write_format_7zip.c b/libarchive/test/test_write_format_7zip.c
new file mode 100644
index 000000000000..b0f0a68fb630
--- /dev/null
+++ b/libarchive/test/test_write_format_7zip.c
@@ -0,0 +1,816 @@
+/*-
+ * Copyright (c) 2011-2012 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+static void
+test_basic(const char *compression_type)
+{
+ char filedata[64];
+ struct archive_entry *ae;
+ struct archive *a;
+ size_t used;
+ size_t buffsize = 1000;
+ char *buff;
+
+ buff = malloc(buffsize);
+
+ /* Create a new archive in memory. */
+ assert((a = archive_write_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_7zip(a));
+ if (compression_type != NULL &&
+ ARCHIVE_OK != archive_write_set_format_option(a, "7zip",
+ "compression", compression_type)) {
+ skipping("%s writing not fully supported on this platform",
+ compression_type);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+ free(buff);
+ return;
+ }
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_none(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_open_memory(a, buff, buffsize, &used));
+
+ /*
+ * Write an empty file to it.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_mtime(ae, 1, 10);
+ assertEqualInt(1, archive_entry_mtime(ae));
+ assertEqualInt(10, archive_entry_mtime_nsec(ae));
+ archive_entry_copy_pathname(ae, "empty");
+ assertEqualString("empty", archive_entry_pathname(ae));
+ archive_entry_set_mode(ae, AE_IFREG | 0755);
+ assertEqualInt((AE_IFREG | 0755), archive_entry_mode(ae));
+
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+
+ /*
+ * Write another empty file to it.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_mtime(ae, 1, 10);
+ assertEqualInt(1, archive_entry_mtime(ae));
+ assertEqualInt(10, archive_entry_mtime_nsec(ae));
+ archive_entry_copy_pathname(ae, "empty2");
+ assertEqualString("empty2", archive_entry_pathname(ae));
+ archive_entry_set_mode(ae, AE_IFREG | 0444);
+ assertEqualInt((AE_IFREG | 0444), archive_entry_mode(ae));
+
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+
+ /*
+ * Write a file to it.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_mtime(ae, 1, 100);
+ assertEqualInt(1, archive_entry_mtime(ae));
+ assertEqualInt(100, archive_entry_mtime_nsec(ae));
+ archive_entry_copy_pathname(ae, "file");
+ assertEqualString("file", archive_entry_pathname(ae));
+ archive_entry_set_mode(ae, AE_IFREG | 0755);
+ assertEqualInt((AE_IFREG | 0755), archive_entry_mode(ae));
+ archive_entry_set_size(ae, 8);
+
+ assertEqualInt(0, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ assertEqualInt(8, archive_write_data(a, "12345678", 9));
+ assertEqualInt(0, archive_write_data(a, "1", 1));
+
+ /*
+ * Write another file to it.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_mtime(ae, 1, 10);
+ assertEqualInt(1, archive_entry_mtime(ae));
+ assertEqualInt(10, archive_entry_mtime_nsec(ae));
+ archive_entry_copy_pathname(ae, "file2");
+ assertEqualString("file2", archive_entry_pathname(ae));
+ archive_entry_set_mode(ae, AE_IFREG | 0755);
+ assertEqualInt((AE_IFREG | 0755), archive_entry_mode(ae));
+ archive_entry_set_size(ae, 4);
+
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ assertEqualInt(4, archive_write_data(a, "1234", 5));
+
+ /*
+ * Write a symbolic file to it.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_mtime(ae, 1, 10);
+ assertEqualInt(1, archive_entry_mtime(ae));
+ assertEqualInt(10, archive_entry_mtime_nsec(ae));
+ archive_entry_copy_pathname(ae, "symbolic");
+ archive_entry_copy_symlink(ae, "file1");
+ assertEqualString("symbolic", archive_entry_pathname(ae));
+ archive_entry_set_mode(ae, AE_IFLNK | 0755);
+ assertEqualInt((AE_IFLNK | 0755), archive_entry_mode(ae));
+
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+
+ /*
+ * Write a directory to it.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_mtime(ae, 11, 100);
+ archive_entry_copy_pathname(ae, "dir");
+ archive_entry_set_mode(ae, AE_IFDIR | 0755);
+ archive_entry_set_size(ae, 512);
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ failure("size should be zero so that applications know not to write");
+ assertEqualInt(0, archive_entry_size(ae));
+ archive_entry_free(ae);
+ assertEqualIntA(a, 0, archive_write_data(a, "12345678", 9));
+
+ /*
+ * Write a sub directory to it.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_mtime(ae, 11, 200);
+ archive_entry_copy_pathname(ae, "dir/subdir");
+ archive_entry_set_mode(ae, AE_IFDIR | 0755);
+ archive_entry_set_size(ae, 512);
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ failure("size should be zero so that applications know not to write");
+ assertEqualInt(0, archive_entry_size(ae));
+ archive_entry_free(ae);
+ assertEqualIntA(a, 0, archive_write_data(a, "12345678", 9));
+
+ /*
+ * Write a sub sub-directory to it.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_mtime(ae, 11, 300);
+ archive_entry_copy_pathname(ae, "dir/subdir/subdir");
+ archive_entry_set_mode(ae, AE_IFDIR | 0755);
+ archive_entry_set_size(ae, 512);
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ failure("size should be zero so that applications know not to write");
+ assertEqualInt(0, archive_entry_size(ae));
+ archive_entry_free(ae);
+ assertEqualIntA(a, 0, archive_write_data(a, "12345678", 9));
+
+ /* Close out the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* Verify the initial header. */
+ assertEqualMem(buff, "\x37\x7a\xbc\xaf\x27\x1c\x00\x03", 8);
+
+ /*
+ * Now, read the data back.
+ */
+ /* With the test memory reader -- seeking mode. */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, used, 7));
+
+ /*
+ * Read and verify first file.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(1, archive_entry_mtime(ae));
+ assertEqualInt(100, archive_entry_mtime_nsec(ae));
+ assertEqualInt(0, archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_ctime(ae));
+ assertEqualString("file", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae));
+ assertEqualInt(8, archive_entry_size(ae));
+ assertEqualIntA(a, 8,
+ archive_read_data(a, filedata, sizeof(filedata)));
+ assertEqualMem(filedata, "12345678", 8);
+
+
+ /*
+ * Read the second file back.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(1, archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_mtime_nsec(ae));
+ assertEqualInt(0, archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_ctime(ae));
+ assertEqualString("file2", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae));
+ assertEqualInt(4, archive_entry_size(ae));
+ assertEqualIntA(a, 4,
+ archive_read_data(a, filedata, sizeof(filedata)));
+ assertEqualMem(filedata, "1234", 4);
+
+ /*
+ * Read and verify a symbolic file.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(1, archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_mtime_nsec(ae));
+ assertEqualInt(0, archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_ctime(ae));
+ assertEqualString("symbolic", archive_entry_pathname(ae));
+ assertEqualString("file1", archive_entry_symlink(ae));
+ assertEqualInt(AE_IFLNK | 0755, archive_entry_mode(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+
+ /*
+ * Read and verify an empty file.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(1, archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_mtime_nsec(ae));
+ assertEqualInt(0, archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_ctime(ae));
+ assertEqualString("empty", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+
+ /*
+ * Read and verify an empty file.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(1, archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_mtime_nsec(ae));
+ assertEqualInt(0, archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_ctime(ae));
+ assertEqualString("empty2", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG | 0444, archive_entry_mode(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+
+ /*
+ * Read the sub sub-dir entry back.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(11, archive_entry_mtime(ae));
+ assertEqualInt(300, archive_entry_mtime_nsec(ae));
+ assertEqualInt(0, archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_ctime(ae));
+ assertEqualString("dir/subdir/subdir/", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFDIR | 0755, archive_entry_mode(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualIntA(a, 0, archive_read_data(a, filedata, 10));
+
+ /*
+ * Read the sub dir entry back.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(11, archive_entry_mtime(ae));
+ assertEqualInt(200, archive_entry_mtime_nsec(ae));
+ assertEqualInt(0, archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_ctime(ae));
+ assertEqualString("dir/subdir/", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFDIR | 0755, archive_entry_mode(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualIntA(a, 0, archive_read_data(a, filedata, 10));
+
+ /*
+ * Read the dir entry back.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(11, archive_entry_mtime(ae));
+ assertEqualInt(100, archive_entry_mtime_nsec(ae));
+ assertEqualInt(0, archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_ctime(ae));
+ assertEqualString("dir/", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFDIR | 0755, archive_entry_mode(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualIntA(a, 0, archive_read_data(a, filedata, 10));
+
+ /* Verify the end of the archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a));
+
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+ free(buff);
+}
+
+static void
+test_basic2(const char *compression_type)
+{
+ char filedata[64];
+ struct archive_entry *ae;
+ struct archive *a;
+ size_t used;
+ size_t buffsize = 1000;
+ char *buff;
+
+ buff = malloc(buffsize);
+
+ /* Create a new archive in memory. */
+ assert((a = archive_write_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_7zip(a));
+ if (compression_type != NULL &&
+ ARCHIVE_OK != archive_write_set_format_option(a, "7zip",
+ "compression", compression_type)) {
+ skipping("%s writing not fully supported on this platform",
+ compression_type);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+ free(buff);
+ return;
+ }
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_none(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_open_memory(a, buff, buffsize, &used));
+
+ /*
+ * Write a file to it.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_mtime(ae, 1, 100);
+ assertEqualInt(1, archive_entry_mtime(ae));
+ assertEqualInt(100, archive_entry_mtime_nsec(ae));
+ archive_entry_copy_pathname(ae, "file");
+ assertEqualString("file", archive_entry_pathname(ae));
+ archive_entry_set_mode(ae, AE_IFREG | 0755);
+ assertEqualInt((AE_IFREG | 0755), archive_entry_mode(ae));
+ archive_entry_set_size(ae, 8);
+
+ assertEqualInt(0, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ assertEqualInt(8, archive_write_data(a, "12345678", 9));
+ assertEqualInt(0, archive_write_data(a, "1", 1));
+
+ /*
+ * Write another file to it.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_mtime(ae, 1, 10);
+ assertEqualInt(1, archive_entry_mtime(ae));
+ assertEqualInt(10, archive_entry_mtime_nsec(ae));
+ archive_entry_copy_pathname(ae, "file2");
+ assertEqualString("file2", archive_entry_pathname(ae));
+ archive_entry_set_mode(ae, AE_IFREG | 0755);
+ assertEqualInt((AE_IFREG | 0755), archive_entry_mode(ae));
+ archive_entry_set_size(ae, 4);
+
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ assertEqualInt(4, archive_write_data(a, "1234", 5));
+
+ /*
+ * Write a directory to it.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_mtime(ae, 11, 100);
+ archive_entry_copy_pathname(ae, "dir");
+ archive_entry_set_mode(ae, AE_IFDIR | 0755);
+ archive_entry_set_size(ae, 512);
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ failure("size should be zero so that applications know not to write");
+ assertEqualInt(0, archive_entry_size(ae));
+ archive_entry_free(ae);
+ assertEqualIntA(a, 0, archive_write_data(a, "12345678", 9));
+
+ /*
+ * Write a sub directory to it.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_mtime(ae, 11, 200);
+ archive_entry_copy_pathname(ae, "dir/subdir");
+ archive_entry_set_mode(ae, AE_IFDIR | 0755);
+ archive_entry_set_size(ae, 512);
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ failure("size should be zero so that applications know not to write");
+ assertEqualInt(0, archive_entry_size(ae));
+ archive_entry_free(ae);
+ assertEqualIntA(a, 0, archive_write_data(a, "12345678", 9));
+
+ /*
+ * Write a sub sub-directory to it.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_mtime(ae, 11, 300);
+ archive_entry_copy_pathname(ae, "dir/subdir/subdir");
+ archive_entry_set_mode(ae, AE_IFDIR | 0755);
+ archive_entry_set_size(ae, 512);
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ failure("size should be zero so that applications know not to write");
+ assertEqualInt(0, archive_entry_size(ae));
+ archive_entry_free(ae);
+ assertEqualIntA(a, 0, archive_write_data(a, "12345678", 9));
+
+ /* Close out the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* Verify the initial header. */
+ assertEqualMem(buff, "\x37\x7a\xbc\xaf\x27\x1c\x00\x03", 8);
+
+ /*
+ * Now, read the data back.
+ */
+ /* With the test memory reader -- seeking mode. */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, used, 7));
+
+ /*
+ * Read and verify first file.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(1, archive_entry_mtime(ae));
+ assertEqualInt(100, archive_entry_mtime_nsec(ae));
+ assertEqualInt(0, archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_ctime(ae));
+ assertEqualString("file", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae));
+ assertEqualInt(8, archive_entry_size(ae));
+ assertEqualIntA(a, 8,
+ archive_read_data(a, filedata, sizeof(filedata)));
+ assertEqualMem(filedata, "12345678", 8);
+
+
+ /*
+ * Read the second file back.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(1, archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_mtime_nsec(ae));
+ assertEqualInt(0, archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_ctime(ae));
+ assertEqualString("file2", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae));
+ assertEqualInt(4, archive_entry_size(ae));
+ assertEqualIntA(a, 4,
+ archive_read_data(a, filedata, sizeof(filedata)));
+ assertEqualMem(filedata, "1234", 4);
+
+ /*
+ * Read the sub sub-dir entry back.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(11, archive_entry_mtime(ae));
+ assertEqualInt(300, archive_entry_mtime_nsec(ae));
+ assertEqualInt(0, archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_ctime(ae));
+ assertEqualString("dir/subdir/subdir/", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFDIR | 0755, archive_entry_mode(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualIntA(a, 0, archive_read_data(a, filedata, 10));
+
+ /*
+ * Read the sub dir entry back.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(11, archive_entry_mtime(ae));
+ assertEqualInt(200, archive_entry_mtime_nsec(ae));
+ assertEqualInt(0, archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_ctime(ae));
+ assertEqualString("dir/subdir/", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFDIR | 0755, archive_entry_mode(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualIntA(a, 0, archive_read_data(a, filedata, 10));
+
+ /*
+ * Read the dir entry back.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(11, archive_entry_mtime(ae));
+ assertEqualInt(100, archive_entry_mtime_nsec(ae));
+ assertEqualInt(0, archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_ctime(ae));
+ assertEqualString("dir/", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFDIR | 0755, archive_entry_mode(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualIntA(a, 0, archive_read_data(a, filedata, 10));
+
+ /* Verify the end of the archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a));
+
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+ free(buff);
+}
+
+/*
+ * Test writing an empty archive.
+ */
+static void
+test_empty_archive(void)
+{
+ struct archive *a;
+ size_t buffsize = 1000;
+ char *buff;
+ size_t used;
+
+ buff = malloc(buffsize);
+
+ /* Create a new archive in memory. */
+ assert((a = archive_write_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_7zip(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_none(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_open_memory(a, buff, buffsize, &used));
+
+ /* Close out the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* Verify the archive file size. */
+ assertEqualInt(32, used);
+
+ /* Verify the initial header. */
+ assertEqualMem(buff,
+ "\x37\x7a\xbc\xaf\x27\x1c\x00\x03"
+ "\x8d\x9b\xd5\x0f\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00", 32);
+
+ free(buff);
+}
+
+/*
+ * Test writing an empty file.
+ */
+static void
+test_only_empty_file(void)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+ size_t buffsize = 1000;
+ char *buff;
+ size_t used;
+
+ buff = malloc(buffsize);
+
+ /* Create a new archive in memory. */
+ assert((a = archive_write_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_7zip(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_none(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_open_memory(a, buff, buffsize, &used));
+
+ /*
+ * Write an empty file to it.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_mtime(ae, 1, 10);
+ assertEqualInt(1, archive_entry_mtime(ae));
+ assertEqualInt(10, archive_entry_mtime_nsec(ae));
+ archive_entry_set_atime(ae, 2, 20);
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(20, archive_entry_atime_nsec(ae));
+ archive_entry_set_ctime(ae, 0, 100);
+ assertEqualInt(0, archive_entry_ctime(ae));
+ assertEqualInt(100, archive_entry_ctime_nsec(ae));
+ archive_entry_copy_pathname(ae, "empty");
+ assertEqualString("empty", archive_entry_pathname(ae));
+ archive_entry_set_mode(ae, AE_IFREG | 0755);
+ assertEqualInt((S_IFREG | 0755), archive_entry_mode(ae));
+
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+
+ /* Close out the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* Verify the archive file size. */
+ assertEqualInt(102, used);
+
+ /* Verify the initial header. */
+ assertEqualMem(buff,
+ "\x37\x7a\xbc\xaf\x27\x1c\x00\x03"
+ "\x00\x5b\x58\x25\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x46\x00\x00\x00"
+ "\x00\x00\x00\x00\x8f\xce\x1d\xf3", 32);
+
+ /*
+ * Now, read the data back.
+ */
+ /* With the test memory reader -- seeking mode. */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, used, 7));
+
+ /*
+ * Read and verify an empty file.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(1, archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_mtime_nsec(ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_atime_nsec(ae));
+ assertEqualInt(0, archive_entry_ctime(ae));
+ assertEqualInt(100, archive_entry_ctime_nsec(ae));
+ assertEqualString("empty", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+
+ /* Verify the end of the archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a));
+
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+ free(buff);
+}
+
+static void
+test_only_empty_files(void)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+ size_t buffsize = 1000;
+ char *buff;
+ size_t used;
+
+ buff = malloc(buffsize);
+
+ /* Create a new archive in memory. */
+ assert((a = archive_write_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_7zip(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_none(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_open_memory(a, buff, buffsize, &used));
+
+ /*
+ * Write an empty file to it.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_mtime(ae, 1, 10);
+ assertEqualInt(1, archive_entry_mtime(ae));
+ assertEqualInt(10, archive_entry_mtime_nsec(ae));
+ archive_entry_set_atime(ae, 2, 20);
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(20, archive_entry_atime_nsec(ae));
+ archive_entry_copy_pathname(ae, "empty");
+ assertEqualString("empty", archive_entry_pathname(ae));
+ archive_entry_set_mode(ae, AE_IFREG | 0755);
+ assertEqualInt((AE_IFREG | 0755), archive_entry_mode(ae));
+
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+
+ /*
+ * Write second empty file to it.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_mtime(ae, 2, 10);
+ assertEqualInt(2, archive_entry_mtime(ae));
+ assertEqualInt(10, archive_entry_mtime_nsec(ae));
+ archive_entry_set_ctime(ae, 2, 10);
+ assertEqualInt(2, archive_entry_ctime(ae));
+ assertEqualInt(10, archive_entry_ctime_nsec(ae));
+ archive_entry_copy_pathname(ae, "empty2");
+ assertEqualString("empty2", archive_entry_pathname(ae));
+ archive_entry_set_mode(ae, AE_IFREG | 0644);
+ assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
+
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+
+ /*
+ * Write third empty file to it.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_mtime(ae, 3, 10);
+ assertEqualInt(3, archive_entry_mtime(ae));
+ assertEqualInt(10, archive_entry_mtime_nsec(ae));
+ archive_entry_copy_pathname(ae, "empty3");
+ assertEqualString("empty3", archive_entry_pathname(ae));
+ archive_entry_set_mode(ae, AE_IFREG | 0644);
+ assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
+
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+
+ /* Close out the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* Verify the initial header. */
+ assertEqualMem(buff, "\x37\x7a\xbc\xaf\x27\x1c\x00\x03", 8);
+
+ /*
+ * Now, read the data back.
+ */
+ /* With the test memory reader -- seeking mode. */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, used, 7));
+
+ /*
+ * Read and verify an empty file.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(1, archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_mtime_nsec(ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_atime_nsec(ae));
+ assertEqualInt(0, archive_entry_ctime(ae));
+ assertEqualString("empty", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+
+ /*
+ * Read and verify second empty file.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(2, archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_mtime_nsec(ae));
+ assertEqualInt(0, archive_entry_atime(ae));
+ assertEqualInt(2, archive_entry_ctime(ae));
+ assertEqualInt(0, archive_entry_ctime_nsec(ae));
+ assertEqualString("empty2", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG | 0644, archive_entry_mode(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+
+ /*
+ * Read and verify third empty file.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(3, archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_mtime_nsec(ae));
+ assertEqualInt(0, archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_ctime(ae));
+ assertEqualString("empty3", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG | 0644, archive_entry_mode(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+
+ /* Verify the end of the archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+ assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a));
+
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+ free(buff);
+}
+
+DEFINE_TEST(test_write_format_7zip)
+{
+ /* Test that making a 7-Zip archive file by default compression
+ * in whatever compressions are supported on the running platform. */
+ test_basic(NULL);
+ /* Test that making a 7-Zip archive file without compression. */
+ test_basic("copy");
+ /* Test that making a 7-Zip archive file with deflate compression. */
+ test_basic("deflate");
+ /* Test that making a 7-Zip archive file with bzip2 compression. */
+ test_basic("bzip2");
+ /* Test that making a 7-Zip archive file with lzma1 compression. */
+ test_basic("lzma1");
+ /* Test that making a 7-Zip archive file with lzma2 compression. */
+ test_basic("lzma2");
+ /* Test that making a 7-Zip archive file with PPMd compression. */
+ test_basic("ppmd");
+ /* Test that making a 7-Zip archive file without empty files. */
+ test_basic2(NULL);
+ /* Test that making an empty 7-Zip archive file. */
+ test_empty_archive();
+ /* Test that write an empty file. */
+ test_only_empty_file();
+ test_only_empty_files();
+}
diff --git a/libarchive/test/test_write_format_ar.c b/libarchive/test/test_write_format_ar.c
index 5822b3f3817c..1c1b2a718b07 100644
--- a/libarchive/test/test_write_format_ar.c
+++ b/libarchive/test/test_write_format_ar.c
@@ -34,9 +34,6 @@ static char strtab[] = "abcdefghijklmn.o/\nggghhhjjjrrrttt.o/\niiijjjdddsssppp.o
DEFINE_TEST(test_write_format_ar)
{
-#if ARCHIVE_VERSION_NUMBER < 1009000
- skipping("ar write support");
-#else
struct archive_entry *ae;
struct archive* a;
size_t used;
@@ -45,14 +42,14 @@ DEFINE_TEST(test_write_format_ar)
* First we try to create a SVR4/GNU format archive.
*/
assert((a = archive_write_new()) != NULL);
- assertA(0 == archive_write_set_format_ar_svr4(a));
- assertA(0 == archive_write_open_memory(a, buff, sizeof(buff), &used));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ar_svr4(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff), &used));
/* write the filename table */
assert((ae = archive_entry_new()) != NULL);
archive_entry_copy_pathname(ae, "//");
archive_entry_set_size(ae, strlen(strtab));
- assertA(0 == archive_write_header(a, ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
assertA(strlen(strtab) == (size_t)archive_write_data(a, strtab, strlen(strtab)));
archive_entry_free(ae);
@@ -64,7 +61,7 @@ DEFINE_TEST(test_write_format_ar)
assert((S_IFREG | 0755) == archive_entry_mode(ae));
archive_entry_copy_pathname(ae, "abcdefghijklmn.o");
archive_entry_set_size(ae, 8);
- assertA(0 == archive_write_header(a, ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
assertA(8 == archive_write_data(a, "87654321", 15));
archive_entry_free(ae);
@@ -100,19 +97,18 @@ DEFINE_TEST(test_write_format_ar)
assertA(0 != archive_write_header(a, ae));
archive_entry_free(ae);
- archive_write_close(a);
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_write_finish(a);
-#else
- assertEqualInt(0, archive_write_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(archive_position_compressed(a),
+ archive_position_uncompressed(a));
+ assertEqualInt(used, archive_position_uncompressed(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/*
* Now, read the data back.
*/
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
- assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used));
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
@@ -139,12 +135,8 @@ DEFINE_TEST(test_write_format_ar)
assertEqualIntA(a, 8, archive_read_data(a, buff2, 17));
assertEqualMem(buff2, "88877766", 8);
- assertEqualIntA(a, 0, archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assertEqualInt(0, archive_read_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
/*
* Then, we try to create a BSD format archive.
@@ -172,17 +164,13 @@ DEFINE_TEST(test_write_format_ar)
assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
assertEqualIntA(a, 6, archive_write_data(a, "555555", 7));
archive_entry_free(ae);
- archive_write_close(a);
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_write_finish(a);
-#else
- assertEqualInt(0, archive_write_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/* Now, Read the data back */
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
- assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used));
assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
@@ -199,11 +187,6 @@ DEFINE_TEST(test_write_format_ar)
/* Test EOF */
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
- assertEqualIntA(a, 0, archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assertEqualInt(0, archive_read_finish(a));
-#endif
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
diff --git a/libarchive/test/test_write_format_cpio.c b/libarchive/test/test_write_format_cpio.c
index 7bf2a41a528a..2984a6a37c9a 100644
--- a/libarchive/test/test_write_format_cpio.c
+++ b/libarchive/test/test_write_format_cpio.c
@@ -25,8 +25,6 @@
#include "test.h"
__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_format_cpio.c 185672 2008-12-06 06:02:26Z kientzle $");
-/* The version stamp macro was introduced after cpio write support. */
-#if ARCHIVE_VERSION_NUMBER >= 1009000
static void
test_format(int (*set_format)(struct archive *))
{
@@ -88,6 +86,48 @@ test_format(int (*set_format)(struct archive *))
assertA(4 == archive_write_data(a, "1234", 5));
/*
+ * Write a file with a name, filetype, and size.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_copy_pathname(ae, "name");
+ archive_entry_set_size(ae, 0);
+ archive_entry_set_filetype(ae, AE_IFREG);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae));
+ assert(archive_error_string(a) == NULL);
+ archive_entry_free(ae);
+
+ /*
+ * Write a file with a name and filetype but no size.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_copy_pathname(ae, "name");
+ archive_entry_unset_size(ae);
+ archive_entry_set_filetype(ae, AE_IFREG);
+ assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, ae));
+ assert(archive_error_string(a) != NULL);
+ archive_entry_free(ae);
+
+ /*
+ * Write a file with a name and size but no filetype.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_copy_pathname(ae, "name");
+ archive_entry_set_size(ae, 0);
+ assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, ae));
+ assert(archive_error_string(a) != NULL);
+ archive_entry_free(ae);
+
+ /*
+ * Write a file with a size and filetype but no name.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_size(ae, 0);
+ archive_entry_set_filetype(ae, AE_IFREG);
+ assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, ae));
+ assert(archive_error_string(a) != NULL);
+ archive_entry_free(ae);
+
+ /*
* Write a directory to it.
*/
assert((ae = archive_entry_new()) != NULL);
@@ -103,12 +143,8 @@ test_format(int (*set_format)(struct archive *))
/* Close out the archive. */
- assertA(0 == archive_write_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_write_finish(a);
-#else
- assertA(0 == archive_write_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/*
* Damage the second entry to test the search-ahead recovery.
@@ -133,11 +169,11 @@ test_format(int (*set_format)(struct archive *))
*/
assert((a = archive_read_new()) != NULL);
assertA(0 == archive_read_support_format_all(a));
- assertA(0 == archive_read_support_compression_all(a));
+ assertA(0 == archive_read_support_filter_all(a));
assertA(0 == archive_read_open_memory(a, buff, used));
if (!assertEqualIntA(a, 0, archive_read_next_header(a, &ae))) {
- archive_read_finish(a);
+ archive_read_free(a);
return;
}
@@ -150,17 +186,23 @@ test_format(int (*set_format)(struct archive *))
assertEqualInt((S_IFREG | 0755), archive_entry_mode(ae));
assertEqualInt(8, archive_entry_size(ae));
assertA(8 == archive_read_data(a, filedata, 10));
- assert(0 == memcmp(filedata, "12345678", 8));
+ assertEqualMem(filedata, "12345678", 8);
/*
* The second file can't be read because we damaged its header.
*/
/*
- * Read the dir entry back.
+ * Read the third file back.
* ARCHIVE_WARN here because the damaged entry was skipped.
*/
assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae));
+ assertEqualString("name", archive_entry_pathname(ae));
+
+ /*
+ * Read the dir entry back.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualInt(11, archive_entry_mtime(ae));
assert(0 == archive_entry_mtime_nsec(ae));
assert(0 == archive_entry_atime(ae));
@@ -172,23 +214,57 @@ test_format(int (*set_format)(struct archive *))
/* Verify the end of the archive. */
assertEqualIntA(a, 1, archive_read_next_header(a, &ae));
- assert(0 == archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assert(0 == archive_read_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
free(buff);
}
-#endif
+
+static void
+test_big_entries(int (*set_format)(struct archive *), int64_t size, int expected)
+{
+ struct archive_entry *ae;
+ struct archive *a;
+ size_t buffsize = 1000000;
+ size_t used;
+ char *buff;
+
+ buff = malloc(buffsize);
+
+ /* Create a new archive in memory. */
+ assert((a = archive_write_new()) != NULL);
+ assertA(0 == (*set_format)(a));
+ assertA(0 == archive_write_set_compression_none(a));
+ assertA(0 == archive_write_open_memory(a, buff, buffsize, &used));
+
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_copy_pathname(ae, "file");
+ archive_entry_set_size(ae, size);
+ archive_entry_set_filetype(ae, AE_IFREG);
+ assertEqualInt(expected, archive_write_header(a, ae));
+ if (expected != ARCHIVE_OK)
+ assert(archive_error_string(a) != NULL);
+
+ archive_entry_free(ae);
+ archive_write_free(a);
+ free(buff);
+}
+
DEFINE_TEST(test_write_format_cpio)
{
-#if ARCHIVE_VERSION_NUMBER >= 1009000
+ int64_t size_4g = ((int64_t)1) << 32;
+ int64_t size_8g = ((int64_t)1) << 33;
+
test_format(archive_write_set_format_cpio);
test_format(archive_write_set_format_cpio_newc);
-#else
- skipping("cpio write support");
-#endif
+
+ test_big_entries(archive_write_set_format_cpio,
+ size_8g - 1, ARCHIVE_OK);
+ test_big_entries(archive_write_set_format_cpio,
+ size_8g, ARCHIVE_FAILED);
+ test_big_entries(archive_write_set_format_cpio_newc,
+ size_4g - 1, ARCHIVE_OK);
+ test_big_entries(archive_write_set_format_cpio_newc,
+ size_4g, ARCHIVE_FAILED);
}
diff --git a/libarchive/test/test_write_format_cpio_empty.c b/libarchive/test/test_write_format_cpio_empty.c
index 131ac24617d2..53aaec822712 100644
--- a/libarchive/test/test_write_format_cpio_empty.c
+++ b/libarchive/test/test_write_format_cpio_empty.c
@@ -61,12 +61,8 @@ DEFINE_TEST(test_write_format_cpio_empty)
assertA(0 == archive_write_open_memory(a, buff, sizeof(buff), &used));
/* Close out the archive. */
- assertA(0 == archive_write_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_write_finish(a);
-#else
- assertA(0 == archive_write_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
failure("Empty cpio archive should be exactly 87 bytes, was %d.", used);
assert(used == 87);
diff --git a/libarchive/test/test_write_format_cpio_newc.c b/libarchive/test/test_write_format_cpio_newc.c
index 1c3c330b0e9c..81c3d22d90e1 100644
--- a/libarchive/test/test_write_format_cpio_newc.c
+++ b/libarchive/test/test_write_format_cpio_newc.c
@@ -111,12 +111,7 @@ DEFINE_TEST(test_write_format_cpio_newc)
assertEqualIntA(a, 0, archive_write_header(a, entry));
archive_entry_free(entry);
-
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_write_finish(a);
-#else
- assert(0 == archive_write_finish(a));
-#endif
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/*
* Verify the archive format.
diff --git a/libarchive/test/test_write_format_cpio_odc.c b/libarchive/test/test_write_format_cpio_odc.c
index e2136f87cfb0..48af04ecf355 100644
--- a/libarchive/test/test_write_format_cpio_odc.c
+++ b/libarchive/test/test_write_format_cpio_odc.c
@@ -123,11 +123,7 @@ DEFINE_TEST(test_write_format_cpio_odc)
/* Write of data to symlink should fail == zero bytes get written. */
assertEqualIntA(a, 0, archive_write_data(a, "1234567890", 10));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_write_finish(a);
-#else
- assert(0 == archive_write_finish(a));
-#endif
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/*
* Verify the archive format.
diff --git a/libarchive/test/test_write_format_gnutar.c b/libarchive/test/test_write_format_gnutar.c
new file mode 100644
index 000000000000..42063e9cfa36
--- /dev/null
+++ b/libarchive/test/test_write_format_gnutar.c
@@ -0,0 +1,236 @@
+/*-
+ * Copyright (c) 2010 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+char buff2[64];
+
+/* Some names 1026 characters long */
+static const char *longfilename = "abcdefghijklmnopqrstuvwxyz"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890";
+
+static const char *longlinkname = "Xabcdefghijklmnopqrstuvwxyz"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890";
+
+static const char *longhardlinkname = "Yabcdefghijklmnopqrstuvwxyz"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890";
+
+
+DEFINE_TEST(test_write_format_gnutar)
+{
+ size_t buffsize = 1000000;
+ char *buff;
+ struct archive_entry *ae;
+ struct archive *a;
+ size_t used;
+
+ buff = malloc(buffsize); /* million bytes of work area */
+ assert(buff != NULL);
+
+ /* Create a new archive in memory. */
+ assert((a = archive_write_new()) != NULL);
+ assertA(0 == archive_write_set_format_gnutar(a));
+ assertA(0 == archive_write_set_compression_none(a));
+ assertA(0 == archive_write_open_memory(a, buff, buffsize, &used));
+
+ /*
+ * "file" has a bunch of attributes and 8 bytes of data.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 20);
+ archive_entry_set_birthtime(ae, 3, 30);
+ archive_entry_set_ctime(ae, 4, 40);
+ archive_entry_set_mtime(ae, 5, 50);
+ archive_entry_copy_pathname(ae, "file");
+ archive_entry_set_mode(ae, S_IFREG | 0755);
+ archive_entry_set_size(ae, 8);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9));
+
+ /*
+ * A file with a very long name
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_copy_pathname(ae, longfilename);
+ archive_entry_set_mode(ae, S_IFREG | 0755);
+ archive_entry_set_size(ae, 8);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ assertEqualIntA(a, 8, archive_write_data(a, "abcdefgh", 9));
+
+ /*
+ * A hardlink to the above file.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_copy_pathname(ae, longhardlinkname);
+ archive_entry_copy_hardlink(ae, longfilename);
+ archive_entry_set_mode(ae, S_IFREG | 0755);
+ archive_entry_set_size(ae, 8);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+
+ /*
+ * A symlink to the above file.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_copy_pathname(ae, longlinkname);
+ archive_entry_copy_symlink(ae, longfilename);
+ archive_entry_set_mode(ae, AE_IFLNK | 0755);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+
+ /* TODO: support GNU tar sparse format and test it here. */
+ /* See test_write_format_pax for an example of testing sparse files. */
+
+ /* Close out the archive. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a));
+
+ /*
+ * Some basic verification of the low-level format.
+ */
+
+ /* Verify GNU tar magic/version fields */
+ assertEqualMem(buff + 257, "ustar \0", 8);
+
+ assertEqualInt(14336, used);
+
+ /*
+ *
+ * Now, read the data back.
+ *
+ */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, 0, archive_read_support_format_all(a));
+ assertEqualIntA(a, 0, archive_read_support_filter_all(a));
+ assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used));
+
+ /*
+ * Read "file"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assert(!archive_entry_atime_is_set(ae));
+ assert(!archive_entry_birthtime_is_set(ae));
+ assert(!archive_entry_ctime_is_set(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_mtime_nsec(ae));
+ assertEqualString("file", archive_entry_pathname(ae));
+ assertEqualInt(S_IFREG | 0755, archive_entry_mode(ae));
+ assertEqualInt(8, archive_entry_size(ae));
+ assertEqualIntA(a, 8, archive_read_data(a, buff2, 10));
+ assertEqualMem(buff2, "12345678", 8);
+
+ /*
+ * Read file with very long name.
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualString(longfilename, archive_entry_pathname(ae));
+ assertEqualInt(S_IFREG | 0755, archive_entry_mode(ae));
+ assertEqualInt(8, archive_entry_size(ae));
+ assertEqualIntA(a, 8, archive_read_data(a, buff2, 10));
+ assertEqualMem(buff2, "abcdefgh", 8);
+
+ /*
+ * Read hardlink.
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualString(longhardlinkname, archive_entry_pathname(ae));
+ assertEqualString(longfilename, archive_entry_hardlink(ae));
+
+ /*
+ * Read symlink.
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualString(longlinkname, archive_entry_pathname(ae));
+ assertEqualString(longfilename, archive_entry_symlink(ae));
+ assertEqualInt(AE_IFLNK | 0755, archive_entry_mode(ae));
+
+ /*
+ * Verify the end of the archive.
+ */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
+
+ free(buff);
+}
diff --git a/libarchive/test/test_write_format_iso9660.c b/libarchive/test/test_write_format_iso9660.c
new file mode 100644
index 000000000000..dd027afa32d5
--- /dev/null
+++ b/libarchive/test/test_write_format_iso9660.c
@@ -0,0 +1,937 @@
+/*-
+ * Copyright (c) 2003-2008 Tim Kientzle
+ * Copyright (c) 2009,2010 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+char buff2[64];
+DEFINE_TEST(test_write_format_iso9660)
+{
+ size_t buffsize = 1000000;
+ char *buff;
+ struct archive_entry *ae;
+ struct archive *a;
+ char dirname[1024];
+ char dir[6];
+ char longname[] =
+ "longname00aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
+ "cccccccccccccccccccccccccccccccccccccccccccccccccc"
+ "dddddddddddddddddddddddddddddddddddddddddddddddddd";
+
+ size_t used;
+ int i;
+
+ buff = malloc(buffsize); /* million bytes of work area */
+ assert(buff != NULL);
+
+ /* Create a new archive in memory. */
+ assert((a = archive_write_new()) != NULL);
+ assertA(0 == archive_write_set_format_iso9660(a));
+ assertA(0 == archive_write_set_compression_none(a));
+ assertA(0 == archive_write_open_memory(a, buff, buffsize, &used));
+
+ /*
+ * "file" has a bunch of attributes and 8 bytes of data.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 20);
+ archive_entry_set_birthtime(ae, 3, 30);
+ archive_entry_set_ctime(ae, 4, 40);
+ archive_entry_set_mtime(ae, 5, 50);
+ archive_entry_copy_pathname(ae, "file");
+ archive_entry_set_mode(ae, AE_IFREG | 0755);
+ archive_entry_set_size(ae, 8);
+ archive_entry_set_nlink(ae, 2);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9));
+
+ /*
+ * "hardlnk" has linked to "file".
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 20);
+ archive_entry_set_birthtime(ae, 3, 30);
+ archive_entry_set_ctime(ae, 4, 40);
+ archive_entry_set_mtime(ae, 5, 50);
+ archive_entry_copy_pathname(ae, "hardlnk");
+ archive_entry_set_mode(ae, AE_IFREG | 0755);
+ archive_entry_set_hardlink(ae, "file");
+ archive_entry_set_nlink(ae, 2);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+
+ /*
+ * longname is similar but has birthtime later than mtime.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 20);
+ archive_entry_set_birthtime(ae, 8, 80);
+ archive_entry_set_ctime(ae, 4, 40);
+ archive_entry_set_mtime(ae, 5, 50);
+ archive_entry_copy_pathname(ae, longname);
+ archive_entry_set_mode(ae, AE_IFREG | 0666);
+ archive_entry_set_size(ae, 8);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9));
+
+ /*
+ * "symlnk has symbolic linked to longname.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 20);
+ archive_entry_set_ctime(ae, 4, 40);
+ archive_entry_set_mtime(ae, 5, 50);
+ archive_entry_copy_pathname(ae, "symlnk");
+ archive_entry_set_mode(ae, AE_IFLNK | 0555);
+ archive_entry_set_symlink(ae, longname);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+
+ /*
+ * "dir*" has a bunch of attributes.
+ */
+ dirname[0] = '\0';
+ strcpy(dir, "/dir0");
+ for (i = 0; i < 10; i++) {
+ dir[4] = '0' + i;
+ if (i == 0)
+ strcat(dirname, dir+1);
+ else
+ strcat(dirname, dir);
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 20);
+ archive_entry_set_birthtime(ae, 3, 30);
+ archive_entry_set_ctime(ae, 4, 40);
+ archive_entry_set_mtime(ae, 5, 50);
+ archive_entry_copy_pathname(ae, dirname);
+ archive_entry_set_mode(ae, S_IFDIR | 0755);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ }
+
+ /*
+ * "dir0/dir1/file1" has 8 bytes of data.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 20);
+ archive_entry_set_birthtime(ae, 3, 30);
+ archive_entry_set_ctime(ae, 4, 40);
+ archive_entry_set_mtime(ae, 5, 50);
+ archive_entry_copy_pathname(ae, "dir0/dir1/file1");
+ archive_entry_set_mode(ae, AE_IFREG | 0755);
+ archive_entry_set_size(ae, 8);
+ archive_entry_set_nlink(ae, 1);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9));
+
+ /*
+ * "dir0/dir1/file2" has 8 bytes of data.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 20);
+ archive_entry_set_birthtime(ae, 3, 30);
+ archive_entry_set_ctime(ae, 4, 40);
+ archive_entry_set_mtime(ae, 5, 50);
+ archive_entry_copy_pathname(ae, "dir0/dir1/file2");
+ archive_entry_set_mode(ae, AE_IFREG | 0755);
+ archive_entry_set_size(ae, 8);
+ archive_entry_set_nlink(ae, 1);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9));
+
+ /*
+ * Add a wrong path "dir0/dir1/file2/wrong"
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 20);
+ archive_entry_set_birthtime(ae, 3, 30);
+ archive_entry_set_ctime(ae, 4, 40);
+ archive_entry_set_mtime(ae, 5, 50);
+ archive_entry_copy_pathname(ae, "dir0/dir1/file2/wrong");
+ archive_entry_set_mode(ae, AE_IFREG | 0755);
+ archive_entry_set_size(ae, 8);
+ archive_entry_set_nlink(ae, 1);
+ assertEqualIntA(a, ARCHIVE_FAILED, archive_write_header(a, ae));
+ archive_entry_free(ae);
+
+ /* Close out the archive. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a));
+
+ /*
+ * -----------------------------------------------------------
+ * Now, read the data back(read Rockridge extensions).
+ * -----------------------------------------------------------
+ */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, 0, archive_read_support_format_all(a));
+ assertEqualIntA(a, 0, archive_read_support_filter_all(a));
+ assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used));
+
+ /*
+ * Read Root Directory
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(archive_entry_atime(ae), archive_entry_ctime(ae));
+ assertEqualInt(archive_entry_atime(ae), archive_entry_mtime(ae));
+ assertEqualString(".", archive_entry_pathname(ae));
+ assert((S_IFDIR | 0555) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "dir0"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(3, archive_entry_birthtime(ae));
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("dir0", archive_entry_pathname(ae));
+ assert((S_IFDIR | 0555) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "dir0/dir1"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(3, archive_entry_birthtime(ae));
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("dir0/dir1", archive_entry_pathname(ae));
+ assert((S_IFDIR | 0555) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "dir0/dir1/dir2"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(3, archive_entry_birthtime(ae));
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("dir0/dir1/dir2", archive_entry_pathname(ae));
+ assert((S_IFDIR | 0555) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "dir0/dir1/dir2/dir3"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(3, archive_entry_birthtime(ae));
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("dir0/dir1/dir2/dir3",
+ archive_entry_pathname(ae));
+ assert((S_IFDIR | 0555) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "dir0/dir1/dir2/dir3/dir4"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(3, archive_entry_birthtime(ae));
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("dir0/dir1/dir2/dir3/dir4",
+ archive_entry_pathname(ae));
+ assert((S_IFDIR | 0555) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "dir0/dir1/dir2/dir3/dir4/dir5"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(3, archive_entry_birthtime(ae));
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5",
+ archive_entry_pathname(ae));
+ assert((S_IFDIR | 0555) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(3, archive_entry_birthtime(ae));
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6",
+ archive_entry_pathname(ae));
+ assert((S_IFDIR | 0555) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(3, archive_entry_birthtime(ae));
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7",
+ archive_entry_pathname(ae));
+ assert((S_IFDIR | 0555) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(3, archive_entry_birthtime(ae));
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8",
+ archive_entry_pathname(ae));
+ assert((S_IFDIR | 0555) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(3, archive_entry_birthtime(ae));
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9",
+ archive_entry_pathname(ae));
+ assert((S_IFDIR | 0555) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "hardlnk"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(3, archive_entry_birthtime(ae));
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("hardlnk", archive_entry_pathname(ae));
+ assert((AE_IFREG | 0555) == archive_entry_mode(ae));
+ assertEqualInt(2, archive_entry_nlink(ae));
+ assertEqualInt(8, archive_entry_size(ae));
+ assertEqualIntA(a, 8, archive_read_data(a, buff2, 10));
+ assertEqualMem(buff2, "12345678", 8);
+
+ /*
+ * Read "file"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(3, archive_entry_birthtime(ae));
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("file", archive_entry_pathname(ae));
+ assertEqualString("hardlnk", archive_entry_hardlink(ae));
+ assert((AE_IFREG | 0555) == archive_entry_mode(ae));
+ assertEqualInt(2, archive_entry_nlink(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+
+ /*
+ * Read longname
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assert(archive_entry_atime_is_set(ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ /* Birthtime > mtime above, so it doesn't get stored at all. */
+ assert(!archive_entry_birthtime_is_set(ae));
+ assertEqualInt(0, archive_entry_birthtime(ae));
+ assert(archive_entry_ctime_is_set(ae));
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assert(archive_entry_mtime_is_set(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString(longname, archive_entry_pathname(ae));
+#if !defined(_WIN32) && !defined(__CYGWIN__)
+ assert((AE_IFREG | 0444) == archive_entry_mode(ae));
+#else
+ /* On Windows and CYGWIN, always set all exec bit ON by default. */
+ assert((AE_IFREG | 0555) == archive_entry_mode(ae));
+#endif
+ assertEqualInt(8, archive_entry_size(ae));
+ assertEqualIntA(a, 8, archive_read_data(a, buff2, 10));
+ assertEqualMem(buff2, "12345678", 8);
+
+ /*
+ * Read "dir0/dir1/file1"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(3, archive_entry_birthtime(ae));
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("dir0/dir1/file1", archive_entry_pathname(ae));
+ assert((AE_IFREG | 0555) == archive_entry_mode(ae));
+ assertEqualInt(1, archive_entry_nlink(ae));
+ assertEqualInt(8, archive_entry_size(ae));
+ assertEqualIntA(a, 8, archive_read_data(a, buff2, 10));
+ assertEqualMem(buff2, "12345678", 8);
+
+ /*
+ * Read "dir0/dir1/file2"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(3, archive_entry_birthtime(ae));
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("dir0/dir1/file2", archive_entry_pathname(ae));
+ assert((AE_IFREG | 0555) == archive_entry_mode(ae));
+ assertEqualInt(1, archive_entry_nlink(ae));
+ assertEqualInt(8, archive_entry_size(ae));
+ assertEqualIntA(a, 8, archive_read_data(a, buff2, 10));
+ assertEqualMem(buff2, "12345678", 8);
+
+ /*
+ * Read "symlnk"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assert(archive_entry_atime_is_set(ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ assert(!archive_entry_birthtime_is_set(ae));
+ assertEqualInt(0, archive_entry_birthtime(ae));
+ assert(archive_entry_ctime_is_set(ae));
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assert(archive_entry_mtime_is_set(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("symlnk", archive_entry_pathname(ae));
+ assert((AE_IFLNK | 0555) == archive_entry_mode(ae));
+ assertEqualString(longname, archive_entry_symlink(ae));
+
+ /*
+ * Verify the end of the archive.
+ */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
+
+ /*
+ * -----------------------------------------------------------
+ * Now, read the data back without Rockridge option
+ * (read Joliet extensions).
+ * -----------------------------------------------------------
+ */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, 0, archive_read_support_format_all(a));
+ assertEqualIntA(a, 0, archive_read_support_filter_all(a));
+ /* Disable Rockridge extensions support. */
+ assertEqualInt(ARCHIVE_OK,
+ archive_read_set_option(a, NULL, "rockridge", NULL));
+ assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used));
+
+ /*
+ * Read Root Directory
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(archive_entry_atime(ae), archive_entry_ctime(ae));
+ assertEqualInt(archive_entry_atime(ae), archive_entry_mtime(ae));
+ assertEqualString(".", archive_entry_pathname(ae));
+ assert((S_IFDIR | 0700) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "dir0"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("dir0", archive_entry_pathname(ae));
+ assert((S_IFDIR | 0700) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "dir0/dir1"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("dir0/dir1", archive_entry_pathname(ae));
+ assert((S_IFDIR | 0700) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "dir0/dir1/dir2"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("dir0/dir1/dir2", archive_entry_pathname(ae));
+ assert((S_IFDIR | 0700) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "dir0/dir1/dir2/dir3"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("dir0/dir1/dir2/dir3",
+ archive_entry_pathname(ae));
+ assert((S_IFDIR | 0700) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "dir0/dir1/dir2/dir3/dir4"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("dir0/dir1/dir2/dir3/dir4",
+ archive_entry_pathname(ae));
+ assert((S_IFDIR | 0700) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "dir0/dir1/dir2/dir3/dir4/dir5"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5",
+ archive_entry_pathname(ae));
+ assert((S_IFDIR | 0700) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6",
+ archive_entry_pathname(ae));
+ assert((S_IFDIR | 0700) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7",
+ archive_entry_pathname(ae));
+ assert((S_IFDIR | 0700) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8",
+ archive_entry_pathname(ae));
+ assert((S_IFDIR | 0700) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9",
+ archive_entry_pathname(ae));
+ assert((S_IFDIR | 0700) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "hardlnk"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("hardlnk", archive_entry_pathname(ae));
+ assert((AE_IFREG | 0400) == archive_entry_mode(ae));
+ assertEqualInt(2, archive_entry_nlink(ae));
+ assertEqualInt(8, archive_entry_size(ae));
+ assertEqualIntA(a, 8, archive_read_data(a, buff2, 10));
+ assertEqualMem(buff2, "12345678", 8);
+
+ /*
+ * Read "file"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("file", archive_entry_pathname(ae));
+ assertEqualString("hardlnk", archive_entry_hardlink(ae));
+ assert((AE_IFREG | 0400) == archive_entry_mode(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualIntA(a, 0, archive_read_data(a, buff2, 10));
+
+ /*
+ * Read longname
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assert(archive_entry_atime_is_set(ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assert(archive_entry_ctime_is_set(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assert(archive_entry_mtime_is_set(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ /* Trim lngname to 64 characters. */
+ longname[64] = '\0';
+ assertEqualString(longname, archive_entry_pathname(ae));
+ assert((AE_IFREG | 0400) == archive_entry_mode(ae));
+ assertEqualInt(8, archive_entry_size(ae));
+ assertEqualIntA(a, 8, archive_read_data(a, buff2, 10));
+ assertEqualMem(buff2, "12345678", 8);
+
+ /*
+ * Read "dir0/dir1/file1"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("dir0/dir1/file1", archive_entry_pathname(ae));
+ assert((AE_IFREG | 0400) == archive_entry_mode(ae));
+ assertEqualInt(1, archive_entry_nlink(ae));
+ assertEqualInt(8, archive_entry_size(ae));
+ assertEqualIntA(a, 8, archive_read_data(a, buff2, 10));
+ assertEqualMem(buff2, "12345678", 8);
+
+ /*
+ * Read "dir0/dir1/file2"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("dir0/dir1/file2", archive_entry_pathname(ae));
+ assert((AE_IFREG | 0400) == archive_entry_mode(ae));
+ assertEqualInt(1, archive_entry_nlink(ae));
+ assertEqualInt(8, archive_entry_size(ae));
+ assertEqualIntA(a, 8, archive_read_data(a, buff2, 10));
+ assertEqualMem(buff2, "12345678", 8);
+
+ /*
+ * Read "symlnk"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assert(archive_entry_atime_is_set(ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assert(!archive_entry_birthtime_is_set(ae));
+ assertEqualInt(0, archive_entry_birthtime(ae));
+ assert(archive_entry_ctime_is_set(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assert(archive_entry_mtime_is_set(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assert((AE_IFREG | 0400) == archive_entry_mode(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+
+ /*
+ * Verify the end of the archive.
+ */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
+
+ /*
+ * -----------------------------------------------------------
+ * Now, read the data back without Rockridge and Joliet option
+ * (read ISO9660).
+ * This mode appears rr_moved directory.
+ * -----------------------------------------------------------
+ */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, 0, archive_read_support_format_all(a));
+ assertEqualIntA(a, 0, archive_read_support_filter_all(a));
+ /* Disable Rockridge and Joliet extensions support. */
+ assertEqualInt(ARCHIVE_OK,
+ archive_read_set_option(a, NULL, "rockridge", NULL));
+ assertEqualInt(ARCHIVE_OK,
+ archive_read_set_option(a, NULL, "joliet", NULL));
+ assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used));
+
+ /*
+ * Read Root Directory
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(archive_entry_atime(ae), archive_entry_ctime(ae));
+ assertEqualInt(archive_entry_atime(ae), archive_entry_mtime(ae));
+ assertEqualString(".", archive_entry_pathname(ae));
+ assert((S_IFDIR | 0700) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "rr_moved"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(archive_entry_atime(ae), archive_entry_ctime(ae));
+ assertEqualInt(archive_entry_atime(ae), archive_entry_mtime(ae));
+ assertEqualString("RR_MOVED", archive_entry_pathname(ae));
+ assert((S_IFDIR | 0700) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "rr_moved/dir7"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("RR_MOVED/DIR7", archive_entry_pathname(ae));
+ assert((S_IFDIR | 0700) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "rr_moved/dir7/dir8"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("RR_MOVED/DIR7/DIR8", archive_entry_pathname(ae));
+ assert((S_IFDIR | 0700) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "rr_moved/dir7/dir8/dir9"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("RR_MOVED/DIR7/DIR8/DIR9",
+ archive_entry_pathname(ae));
+ assert((S_IFDIR | 0700) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "dir0"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("DIR0", archive_entry_pathname(ae));
+ assert((S_IFDIR | 0700) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "dir0/dir1"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("DIR0/DIR1", archive_entry_pathname(ae));
+ assert((S_IFDIR | 0700) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "dir0/dir1/dir2"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("DIR0/DIR1/DIR2", archive_entry_pathname(ae));
+ assert((S_IFDIR | 0700) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "dir0/dir1/dir2/dir3"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("DIR0/DIR1/DIR2/DIR3",
+ archive_entry_pathname(ae));
+ assert((S_IFDIR | 0700) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "dir0/dir1/dir2/dir3/dir4"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("DIR0/DIR1/DIR2/DIR3/DIR4",
+ archive_entry_pathname(ae));
+ assert((S_IFDIR | 0700) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "dir0/dir1/dir2/dir3/dir4/dir5"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("DIR0/DIR1/DIR2/DIR3/DIR4/DIR5",
+ archive_entry_pathname(ae));
+ assert((S_IFDIR | 0700) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("DIR0/DIR1/DIR2/DIR3/DIR4/DIR5/DIR6",
+ archive_entry_pathname(ae));
+ assert((S_IFDIR | 0700) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "file"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_birthtime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("FILE", archive_entry_pathname(ae));
+ assert((AE_IFREG | 0400) == archive_entry_mode(ae));
+ assertEqualInt(2, archive_entry_nlink(ae));
+ assertEqualInt(8, archive_entry_size(ae));
+ assertEqualIntA(a, 8, archive_read_data(a, buff2, 10));
+ assertEqualMem(buff2, "12345678", 8);
+
+ /*
+ * Read "hardlink"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("HARDLNK", archive_entry_pathname(ae));
+ assertEqualString("FILE", archive_entry_hardlink(ae));
+ assert((AE_IFREG | 0400) == archive_entry_mode(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualIntA(a, 0, archive_read_data(a, buff2, 10));
+
+ /*
+ * Read longname
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assert(archive_entry_atime_is_set(ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assert(archive_entry_ctime_is_set(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assert(archive_entry_mtime_is_set(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("LONGNAME", archive_entry_pathname(ae));
+ assert((AE_IFREG | 0400) == archive_entry_mode(ae));
+ assertEqualInt(8, archive_entry_size(ae));
+ assertEqualIntA(a, 8, archive_read_data(a, buff2, 10));
+ assertEqualMem(buff2, "12345678", 8);
+
+ /*
+ * Read "dir0/dir1/file1"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("DIR0/DIR1/FILE1", archive_entry_pathname(ae));
+ assert((AE_IFREG | 0400) == archive_entry_mode(ae));
+ assertEqualInt(1, archive_entry_nlink(ae));
+ assertEqualInt(8, archive_entry_size(ae));
+ assertEqualIntA(a, 8, archive_read_data(a, buff2, 10));
+ assertEqualMem(buff2, "12345678", 8);
+
+ /*
+ * Read "dir0/dir1/file2"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("DIR0/DIR1/FILE2", archive_entry_pathname(ae));
+ assert((AE_IFREG | 0400) == archive_entry_mode(ae));
+ assertEqualInt(1, archive_entry_nlink(ae));
+ assertEqualInt(8, archive_entry_size(ae));
+ assertEqualIntA(a, 8, archive_read_data(a, buff2, 10));
+ assertEqualMem(buff2, "12345678", 8);
+
+ /*
+ * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7" as file
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("DIR0/DIR1/DIR2/DIR3/DIR4/DIR5/DIR6/DIR7",
+ archive_entry_pathname(ae));
+ assert((AE_IFREG | 0400) == archive_entry_mode(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+
+ /*
+ * Read "symlnk"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assert(archive_entry_atime_is_set(ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assert(!archive_entry_birthtime_is_set(ae));
+ assertEqualInt(0, archive_entry_birthtime(ae));
+ assert(archive_entry_ctime_is_set(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assert(archive_entry_mtime_is_set(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("SYMLNK", archive_entry_pathname(ae));
+ assert((AE_IFREG | 0400) == archive_entry_mode(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+
+ /*
+ * Verify the end of the archive.
+ */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
+
+ free(buff);
+}
diff --git a/libarchive/test/test_write_format_iso9660_boot.c b/libarchive/test/test_write_format_iso9660_boot.c
new file mode 100644
index 000000000000..d3f8ab0e9349
--- /dev/null
+++ b/libarchive/test/test_write_format_iso9660_boot.c
@@ -0,0 +1,276 @@
+/*-
+ * Copyright (c) 2009 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+
+/*
+ * Check that a "bootable CD" ISO 9660 image is correctly created.
+ */
+
+static const unsigned char primary_id[] = {
+ 0x01, 0x43, 0x44, 0x30, 0x30, 0x31, 0x01, 0x00
+};
+static const unsigned char volumesize[] = {
+ 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26
+};
+static const unsigned char volumeidu16[] = {
+ 0x00, 0x43, 0x00, 0x44, 0x00, 0x52, 0x00, 0x4f,
+ 0x00, 0x4d, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20,
+ 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20,
+ 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20
+};
+static const unsigned char boot_id[] = {
+ 0x00, 0x43, 0x44, 0x30, 0x30, 0x31, 0x01, 0x45,
+ 0x4c, 0x20, 0x54, 0x4f, 0x52, 0x49, 0x54, 0x4f,
+ 0x20, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49,
+ 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+static const unsigned char supplementary_id[] = {
+ 0x02, 0x43, 0x44, 0x30, 0x30, 0x31, 0x01, 0x00
+};
+static const unsigned char terminator_id[] = {
+ 0xff, 0x43, 0x44, 0x30, 0x30, 0x31, 0x01, 0x00
+};
+
+static const unsigned char boot_catalog[] = {
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xaa, 0x55, 0x55, 0xaa,
+ 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
+ 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char info_table[] = {
+ 0x10, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
+ 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char el_torito_signature[] = {
+ "ER\355\001\012T\207\001RRIP_1991ATHE ROCK RIDGE "
+ "INTERCHANGE PROTOCOL PROVIDES SUPPORT FOR POSIX "
+ "FILE SYSTEM SEMANTICSPLEASE CONTACT DISC PUBLISHER "
+ "FOR SPECIFICATION SOURCE. SEE PUBLISHER IDENTIFIER "
+ "IN PRIMARY VOLUME DESCRIPTOR FOR CONTACT INFORMATION."
+};
+
+char buff2[1024];
+
+static void
+_test_write_format_iso9660_boot(int write_info_tbl)
+{
+ unsigned char nullb[2048];
+ struct archive *a;
+ struct archive_entry *ae;
+ unsigned char *buff;
+ size_t buffsize = 39 * 2048;
+ size_t used;
+ unsigned int i;
+
+ memset(nullb, 0, sizeof(nullb));
+ buff = malloc(buffsize);
+ assert(buff != NULL);
+
+ /* ISO9660 format: Create a new archive in memory. */
+ assert((a = archive_write_new()) != NULL);
+ assertA(0 == archive_write_set_format_iso9660(a));
+ assertA(0 == archive_write_set_compression_none(a));
+ assertA(0 == archive_write_set_option(a, NULL, "boot", "boot.img"));
+ if (write_info_tbl)
+ assertA(0 == archive_write_set_option(a, NULL, "boot-info-table", "1"));
+ assertA(0 == archive_write_set_option(a, NULL, "pad", NULL));
+ assertA(0 == archive_write_open_memory(a, buff, buffsize, &used));
+
+ /*
+ * "boot.img" has a bunch of attributes and 10K bytes of null data.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 20);
+ archive_entry_set_birthtime(ae, 3, 30);
+ archive_entry_set_ctime(ae, 4, 40);
+ archive_entry_set_mtime(ae, 5, 50);
+ archive_entry_copy_pathname(ae, "boot.img");
+ archive_entry_set_mode(ae, S_IFREG | 0755);
+ archive_entry_set_nlink(ae, 1);
+ archive_entry_set_size(ae, 10*1024);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ for (i = 0; i < 10; i++)
+ assertEqualIntA(a, 1024, archive_write_data(a, nullb, 1024));
+
+ /* Close out the archive. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a));
+
+ assert(used == 2048 * 38);
+ /* Check System Area. */
+ for (i = 0; i < 2048 * 16; i += 2048) {
+ assertEqualMem(buff+i, nullb, 2048);
+ }
+
+ /* Primary Volume. */
+ failure("Primary Volume Descriptor should be in 16 Logical Sector.");
+ assertEqualMem(buff+2048*16, primary_id, 8);
+ assertEqualMem(buff+2048*16+0x28,
+ "CDROM ", 32);
+ assertEqualMem(buff+2048*16+0x50, volumesize, 8);
+
+ /* Boot Volume. */
+ failure("Boot Volume Descriptor should be in 17 Logical Sector.");
+ assertEqualMem(buff+2048*17, boot_id, sizeof(boot_id));
+ for (i = 0x27; i <= 0x46; i++) {
+ failure("Unused area must be all nulls.");
+ assert(buff[2048*17+i] == 0);
+ }
+ /* First sector of Boot Catalog. */
+ assert(buff[2048*17+0x47] == 0x20);
+ assert(buff[2048*17+0x48] == 0x00);
+ assert(buff[2048*17+0x49] == 0x00);
+ assert(buff[2048*17+0x4a] == 0x00);
+ for (i = 0x4a; i <= 0x7ff; i++) {
+ failure("Unused area must be all nulls.");
+ assert(buff[2048*17+i] == 0);
+ }
+
+ /* Supplementary Volume. */
+ failure("Supplementary Volume(Joliet) Descriptor "
+ "should be in 18 Logical Sector.");
+ assertEqualMem(buff+2048*18, supplementary_id, 8);
+ assertEqualMem(buff+2048*18+0x28, volumeidu16, 32);
+ assertEqualMem(buff+2048*18+0x50, volumesize, 8);
+ failure("Date and Time of Primary Volume and "
+ "Date and Time of Supplementary Volume "
+ "must be the same.");
+ assertEqualMem(buff+2048*16+0x32d, buff+2048*18+0x32d, 0x44);
+
+ /* Terminator. */
+ failure("Volume Descriptor Set Terminator "
+ "should be in 19 Logical Sector.");
+ assertEqualMem(buff+2048*19, terminator_id, 8);
+ for (i = 8; i < 2048; i++) {
+ failure("Body of Volume Descriptor Set Terminator "
+ "should be all nulls.");
+ assert(buff[2048*19+i] == 0);
+ }
+
+ /* Check signature of El-Torito. */
+ assertEqualMem(buff+2048*31, el_torito_signature, 237);
+ assertEqualMem(buff+2048*31+237, nullb, 2048-237);
+
+ /* Check contents of "boot.catalog". */
+ assertEqualMem(buff+2048*32, boot_catalog, 64);
+ assertEqualMem(buff+2048*32+64, nullb, 2048-64);
+
+ /* Check contents of "boot.img". */
+ if (write_info_tbl) {
+ assertEqualMem(buff+2048*33, nullb, 8);
+ assertEqualMem(buff+2048*33+8, info_table, 56);
+ assertEqualMem(buff+2048*33+64, nullb, 2048-64);
+ } else {
+ assertEqualMem(buff+2048*33, nullb, 2048);
+ }
+ for (i = 2048*34; i < 2048*38; i += 2048) {
+ assertEqualMem(buff+i, nullb, 2048);
+ }
+
+ /*
+ * Read ISO image.
+ */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, 0, archive_read_support_format_all(a));
+ assertEqualIntA(a, 0, archive_read_support_filter_all(a));
+ assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used));
+
+ /*
+ * Read Root Directory
+ * Root Directory entry must be in ISO image.
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(archive_entry_atime(ae), archive_entry_ctime(ae));
+ assertEqualInt(archive_entry_atime(ae), archive_entry_mtime(ae));
+ assertEqualString(".", archive_entry_pathname(ae));
+ assert((S_IFDIR | 0555) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "boot.catalog".
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualString("boot.catalog", archive_entry_pathname(ae));
+#if !defined(_WIN32) && !defined(__CYGWIN__)
+ assert((S_IFREG | 0444) == archive_entry_mode(ae));
+#else
+ /* On Windows and CYGWIN, always set all exec bit ON by default. */
+ assert((S_IFREG | 0555) == archive_entry_mode(ae));
+#endif
+ assertEqualInt(1, archive_entry_nlink(ae));
+ assertEqualInt(2*1024, archive_entry_size(ae));
+ assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
+ assertEqualMem(buff2, boot_catalog, 64);
+
+ /*
+ * Read "boot.img".
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(3, archive_entry_birthtime(ae));
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("boot.img", archive_entry_pathname(ae));
+ assert((S_IFREG | 0555) == archive_entry_mode(ae));
+ assertEqualInt(1, archive_entry_nlink(ae));
+ assertEqualInt(10*1024, archive_entry_size(ae));
+ assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
+ if (write_info_tbl) {
+ assertEqualMem(buff2, nullb, 8);
+ assertEqualMem(buff2+8, info_table, 56);
+ assertEqualMem(buff2+64, nullb, 1024-64);
+ } else
+ assertEqualMem(buff2, nullb, 1024);
+
+ /*
+ * Verify the end of the archive.
+ */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
+
+ free(buff);
+}
+
+DEFINE_TEST(test_write_format_iso9660_boot)
+{
+ _test_write_format_iso9660_boot(0);
+ /* Use 'boot-info-table' option. */
+ _test_write_format_iso9660_boot(1);
+}
diff --git a/libarchive/test/test_write_format_iso9660_empty.c b/libarchive/test/test_write_format_iso9660_empty.c
new file mode 100644
index 000000000000..1c5acdbfc58b
--- /dev/null
+++ b/libarchive/test/test_write_format_iso9660_empty.c
@@ -0,0 +1,202 @@
+/*-
+ * Copyright (c) 2009-2011 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+
+/*
+ * Check that an "empty" ISO 9660 image is correctly created.
+ */
+
+static const unsigned char primary_id[] = {
+ 0x01, 0x43, 0x44, 0x30, 0x30, 0x31, 0x01, 0x00
+};
+static const unsigned char volumesize[] = {
+ 0xb5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb5
+};
+static const unsigned char volumeidu16[] = {
+ 0x00, 0x43, 0x00, 0x44, 0x00, 0x52, 0x00, 0x4f,
+ 0x00, 0x4d, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20,
+ 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20,
+ 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20
+};
+static const unsigned char supplementary_id[] = {
+ 0x02, 0x43, 0x44, 0x30, 0x30, 0x31, 0x01, 0x00
+};
+static const unsigned char terminator_id[] = {
+ 0xff, 0x43, 0x44, 0x30, 0x30, 0x31, 0x01, 0x00
+};
+
+DEFINE_TEST(test_write_format_iso9660_empty)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+ unsigned char *buff;
+ size_t buffsize = 190 * 2048;
+ size_t used;
+ unsigned int i;
+
+ buff = malloc(buffsize);
+ assert(buff != NULL);
+
+ /* ISO9660 format: Create a new archive in memory. */
+ assert((a = archive_write_new()) != NULL);
+ assertA(0 == archive_write_set_format_iso9660(a));
+ assertA(0 == archive_write_set_compression_none(a));
+ assertA(0 == archive_write_set_bytes_per_block(a, 1));
+ assertA(0 == archive_write_set_bytes_in_last_block(a, 1));
+ assertA(0 == archive_write_open_memory(a, buff, buffsize, &used));
+
+ /* Add "." entry which must be ignored. */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 0);
+ archive_entry_set_ctime(ae, 4, 0);
+ archive_entry_set_mtime(ae, 5, 0);
+ archive_entry_copy_pathname(ae, ".");
+ archive_entry_set_mode(ae, S_IFDIR | 0755);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+
+ /* Add ".." entry which must be ignored. */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 0);
+ archive_entry_set_ctime(ae, 4, 0);
+ archive_entry_set_mtime(ae, 5, 0);
+ archive_entry_copy_pathname(ae, "..");
+ archive_entry_set_mode(ae, S_IFDIR | 0755);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+
+ /* Add "/" entry which must be ignored. */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 0);
+ archive_entry_set_ctime(ae, 4, 0);
+ archive_entry_set_mtime(ae, 5, 0);
+ archive_entry_copy_pathname(ae, "/");
+ archive_entry_set_mode(ae, S_IFDIR | 0755);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+
+ /* Add "../" entry which must be ignored. */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 0);
+ archive_entry_set_ctime(ae, 4, 0);
+ archive_entry_set_mtime(ae, 5, 0);
+ archive_entry_copy_pathname(ae, "../");
+ archive_entry_set_mode(ae, S_IFDIR | 0755);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+
+ /* Add "../../." entry which must be ignored. */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 0);
+ archive_entry_set_ctime(ae, 4, 0);
+ archive_entry_set_mtime(ae, 5, 0);
+ archive_entry_copy_pathname(ae, "../../.");
+ archive_entry_set_mode(ae, S_IFDIR | 0755);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+
+ /* Add "..//.././" entry which must be ignored. */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 0);
+ archive_entry_set_ctime(ae, 4, 0);
+ archive_entry_set_mtime(ae, 5, 0);
+ archive_entry_copy_pathname(ae, "..//.././");
+ archive_entry_set_mode(ae, S_IFDIR | 0755);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+
+ /* Close out the archive. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a));
+
+ assert(used == 2048 * 181);
+ /* Check System Area. */
+ for (i = 0; i < 2048 * 16; i++) {
+ failure("System Area should be all nulls.");
+ assert(buff[i] == 0);
+ }
+
+ /* Primary Volume. */
+ failure("Primary Volume Descriptor should be in 16 Logical Sector.");
+ assertEqualMem(buff+2048*16, primary_id, 8);
+ assertEqualMem(buff+2048*16+0x28,
+ "CDROM ", 32);
+ assertEqualMem(buff+2048*16+0x50, volumesize, 8);
+
+ /* Supplementary Volume. */
+ failure("Supplementary Volume(Joliet) Descriptor "
+ "should be in 17 Logical Sector.");
+ assertEqualMem(buff+2048*17, supplementary_id, 8);
+ assertEqualMem(buff+2048*17+0x28, volumeidu16, 32);
+ assertEqualMem(buff+2048*17+0x50, volumesize, 8);
+ failure("Date and Time of Primary Volume and "
+ "Date and Time of Supplementary Volume "
+ "must be the same.");
+ assertEqualMem(buff+2048*16+0x32d, buff+2048*17+0x32d, 0x44);
+
+ /* Terminator. */
+ failure("Volume Descriptor Set Terminator "
+ "should be in 18 Logical Sector.");
+ assertEqualMem(buff+2048*18, terminator_id, 8);
+ for (i = 8; i < 2048; i++) {
+ failure("Body of Volume Descriptor Set Terminator "
+ "should be all nulls.");
+ assert(buff[2048*18+i] == 0);
+ }
+
+ /* Padding data. */
+ for (i = 0; i < 2048*150; i++) {
+ failure("Padding data should be all nulls.");
+ assert(buff[2048*31+i] == 0);
+ }
+
+ /*
+ * Read ISO image.
+ */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, 0, archive_read_support_format_all(a));
+ assertEqualIntA(a, 0, archive_read_support_filter_all(a));
+ assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used));
+
+ /*
+ * Read Root Directory
+ * Root Directory entry must be in ISO image.
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(archive_entry_atime(ae), archive_entry_ctime(ae));
+ assertEqualInt(archive_entry_atime(ae), archive_entry_mtime(ae));
+ assertEqualString(".", archive_entry_pathname(ae));
+ assert((S_IFDIR | 0555) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Verify the end of the archive.
+ */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
+
+ free(buff);
+}
diff --git a/libarchive/test/test_write_format_iso9660_filename.c b/libarchive/test/test_write_format_iso9660_filename.c
new file mode 100644
index 000000000000..337233e56179
--- /dev/null
+++ b/libarchive/test/test_write_format_iso9660_filename.c
@@ -0,0 +1,468 @@
+/*-
+ * Copyright (c) 2009,2010 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+
+/*
+ * Check that an ISO 9660 image is correctly created.
+ */
+static void
+add_entry(struct archive *a, const char *fname, const char *sym)
+{
+ struct archive_entry *ae;
+
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_birthtime(ae, 2, 20);
+ archive_entry_set_atime(ae, 3, 30);
+ archive_entry_set_ctime(ae, 4, 40);
+ archive_entry_set_mtime(ae, 5, 50);
+ archive_entry_copy_pathname(ae, fname);
+ if (sym != NULL)
+ archive_entry_set_symlink(ae, sym);
+ archive_entry_set_mode(ae, S_IFREG | 0555);
+ archive_entry_set_size(ae, 0);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+}
+
+struct fns {
+ size_t maxlen;
+ size_t longest_len;
+ size_t maxflen;
+ size_t maxelen;
+ size_t alloc;
+ int cnt;
+ char **names;
+ int opt;
+#define UPPER_CASE_ONLY 0x00001
+#define ONE_DOT 0x00002
+#define ALLOW_LDOT 0x00004
+};
+
+enum vtype {
+ ROCKRIDGE,
+ JOLIET,
+ ISO9660
+};
+
+/*
+ * Verify file
+ */
+static void
+verify_file(struct archive *a, enum vtype type, struct fns *fns)
+{
+ struct archive_entry *ae;
+ int i;
+
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ if (type == ROCKRIDGE) {
+ assertEqualInt(2, archive_entry_birthtime(ae));
+ assertEqualInt(3, archive_entry_atime(ae));
+ assertEqualInt(4, archive_entry_ctime(ae));
+ } else {
+ assertEqualInt(0, archive_entry_birthtime_is_set(ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ }
+ assertEqualInt(5, archive_entry_mtime(ae));
+ if (type == ROCKRIDGE)
+ assert((S_IFREG | 0555) == archive_entry_mode(ae));
+ else
+ assert((S_IFREG | 0400) == archive_entry_mode(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+
+ /*
+ * Check if the same filename does not appear.
+ */
+ for (i = 0; i < fns->cnt; i++) {
+ const char *p;
+ const char *pathname = archive_entry_pathname(ae);
+ const char *symlink = archive_entry_symlink(ae);
+ size_t length;
+
+ if (symlink != NULL) {
+ length = strlen(symlink);
+ assert(length == 1 || length == 128 || length == 255);
+ assertEqualInt(symlink[length-1], 'x');
+ }
+ failure("Found duplicate for %s", pathname);
+ assert(strcmp(fns->names[i], pathname) != 0);
+ assert((length = strlen(pathname)) <= fns->maxlen);
+ if (length > fns->longest_len)
+ fns->longest_len = length;
+ p = strrchr(pathname, '.');
+ if (p != NULL) {
+ /* Check a length of file name. */
+ assert((size_t)(p - pathname) <= fns->maxflen);
+ /* Check a length of file extension. */
+ assert(strlen(p+1) <= fns->maxelen);
+ if (fns->opt & ONE_DOT) {
+ /* Do not have multi dot. */
+ assert(strchr(pathname, '.') == p);
+ }
+ }
+ for (p = pathname; *p; p++) {
+ if (fns->opt & UPPER_CASE_ONLY) {
+ /* Do not have any lower-case character. */
+ assert(*p < 'a' || *p > 'z');
+ } else
+ break;
+ }
+ if ((fns->opt & ALLOW_LDOT) == 0)
+ /* Do not have a dot at the first position. */
+ assert(*pathname != '.');
+ }
+ /* Save the filename which is appeared to use above next time. */
+ fns->names[fns->cnt++] = strdup(archive_entry_pathname(ae));
+}
+
+static void
+verify(unsigned char *buff, size_t used, enum vtype type, struct fns *fns)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+ size_t i;
+
+ /*
+ * Read ISO image.
+ */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, 0, archive_read_support_format_all(a));
+ assertEqualIntA(a, 0, archive_read_support_filter_all(a));
+ if (type >= 1)
+ assertA(0 == archive_read_set_option(a, NULL, "rockridge",
+ NULL));
+ if (type >= 2)
+ assertA(0 == archive_read_set_option(a, NULL, "joliet",
+ NULL));
+ assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used));
+
+ /*
+ * Read Root Directory
+ * Root Directory entry must be in ISO image.
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(archive_entry_atime(ae), archive_entry_ctime(ae));
+ assertEqualInt(archive_entry_atime(ae), archive_entry_mtime(ae));
+ assertEqualString(".", archive_entry_pathname(ae));
+ switch (type) {
+ case ROCKRIDGE:
+ assert((S_IFDIR | 0555) == archive_entry_mode(ae));
+ break;
+ case JOLIET:
+ assert((S_IFDIR | 0700) == archive_entry_mode(ae));
+ break;
+ case ISO9660:
+ assert((S_IFDIR | 0700) == archive_entry_mode(ae));
+ break;
+ }
+
+ /*
+ * Verify file status.
+ */
+ memset(fns->names, 0, sizeof(char *) * fns->alloc);
+ fns->cnt = 0;
+ for (i = 0; i < fns->alloc; i++)
+ verify_file(a, type, fns);
+ for (i = 0; i < fns->alloc; i++)
+ free(fns->names[i]);
+ assertEqualInt((int)fns->longest_len, (int)fns->maxlen);
+
+ /*
+ * Verify the end of the archive.
+ */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
+}
+
+static int
+create_iso_image(unsigned char *buff, size_t buffsize, size_t *used,
+ const char *opt)
+{
+ struct archive *a;
+ int i, l, fcnt;
+ const int lens[] = {
+ 0, 1, 3, 5, 7, 8, 9, 29, 30, 31, 32,
+ 62, 63, 64, 65, 101, 102, 103, 104,
+ 191, 192, 193, 194, 204, 205, 206, 207, 208,
+ 252, 253, 254, 255,
+ -1 };
+ char fname1[256];
+ char fname2[256];
+ char sym1[2];
+ char sym128[129];
+ char sym255[256];
+
+ /* ISO9660 format: Create a new archive in memory. */
+ assert((a = archive_write_new()) != NULL);
+ assertA(0 == archive_write_set_format_iso9660(a));
+ assertA(0 == archive_write_set_compression_none(a));
+ assertA(0 == archive_write_set_option(a, NULL, "pad", NULL));
+ if (opt)
+ assertA(0 == archive_write_set_options(a, opt));
+ assertA(0 == archive_write_set_bytes_per_block(a, 1));
+ assertA(0 == archive_write_set_bytes_in_last_block(a, 1));
+ assertA(0 == archive_write_open_memory(a, buff, buffsize, used));
+
+ sym1[0] = 'x';
+ sym1[1] = '\0';
+ for (i = 0; i < sizeof(sym128)-2; i++)
+ sym128[i] = 'a';
+ sym128[sizeof(sym128)-2] = 'x';
+ sym128[sizeof(sym128)-1] = '\0';
+ for (i = 0; i < sizeof(sym255)-2; i++)
+ sym255[i] = 'a';
+ sym255[sizeof(sym255)-2] = 'x';
+ sym255[sizeof(sym255)-1] = '\0';
+
+ fcnt = 0;
+ for (i = 0; lens[i] >= 0; i++) {
+ for (l = 0; l < lens[i]; l++) {
+ fname1[l] = 'a';
+ fname2[l] = 'A';
+ }
+ if (l > 0) {
+ fname1[l] = '\0';
+ fname2[l] = '\0';
+ add_entry(a, fname1, NULL);
+ add_entry(a, fname2, sym1);
+ fcnt += 2;
+ }
+ if (l < 254) {
+ fname1[l] = '.';
+ fname1[l+1] = 'c';
+ fname1[l+2] = '\0';
+ fname2[l] = '.';
+ fname2[l+1] = 'C';
+ fname2[l+2] = '\0';
+ add_entry(a, fname1, sym128);
+ add_entry(a, fname2, sym255);
+ fcnt += 2;
+ }
+ if (l < 252) {
+ fname1[l] = '.';
+ fname1[l+1] = 'p';
+ fname1[l+2] = 'n';
+ fname1[l+3] = 'g';
+ fname1[l+4] = '\0';
+ fname2[l] = '.';
+ fname2[l+1] = 'P';
+ fname2[l+2] = 'N';
+ fname2[l+3] = 'G';
+ fname2[l+4] = '\0';
+ add_entry(a, fname1, NULL);
+ add_entry(a, fname2, sym1);
+ fcnt += 2;
+ }
+ if (l < 251) {
+ fname1[l] = '.';
+ fname1[l+1] = 'j';
+ fname1[l+2] = 'p';
+ fname1[l+3] = 'e';
+ fname1[l+4] = 'g';
+ fname1[l+5] = '\0';
+ fname2[l] = '.';
+ fname2[l+1] = 'J';
+ fname2[l+2] = 'P';
+ fname2[l+3] = 'E';
+ fname2[l+4] = 'G';
+ fname2[l+5] = '\0';
+ add_entry(a, fname1, sym128);
+ add_entry(a, fname2, sym255);
+ fcnt += 2;
+ }
+ }
+
+ /* Close out the archive. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a));
+
+ return (fcnt);
+}
+
+DEFINE_TEST(test_write_format_iso9660_filename)
+{
+ unsigned char *buff;
+ size_t buffsize = 120 * 2048;
+ size_t used;
+ int fcnt;
+ struct fns fns;
+
+ buff = malloc(buffsize);
+ assert(buff != NULL);
+ memset(&fns, 0, sizeof(fns));
+
+ /*
+ * Create ISO image with no option.
+ */
+ fcnt = create_iso_image(buff, buffsize, &used, NULL);
+
+ fns.names = (char **)malloc(sizeof(char *) * fcnt);
+ assert(fns.names != NULL);
+ fns.alloc = fcnt;
+
+ /* Verify rockridge filenames. */
+ fns.longest_len = 0;
+ fns.maxlen = fns.maxflen = fns.maxelen = 255;
+ fns.opt = ALLOW_LDOT;
+ verify(buff, used, ROCKRIDGE, &fns);
+
+ /* Verify joliet filenames. */
+ fns.longest_len = 0;
+ fns.maxlen = fns.maxflen = fns.maxelen = 64;
+ fns.opt = ALLOW_LDOT;
+ verify(buff, used, JOLIET, &fns);
+
+ /* Verify ISO9660 filenames. */
+ fns.longest_len = 0;
+ fns.maxlen = 8+3+1;
+ fns.maxflen = 8;
+ fns.maxelen = 3;
+ fns.opt = UPPER_CASE_ONLY | ONE_DOT;
+ verify(buff, used, ISO9660, &fns);
+
+ /*
+ * Create ISO image with iso-level=2.
+ */
+ assertEqualInt(fcnt, create_iso_image(buff, buffsize, &used,
+ "iso-level=2"));
+
+ /* Verify rockridge filenames. */
+ fns.longest_len = 0;
+ fns.maxlen = fns.maxflen = fns.maxelen = 255;
+ fns.opt = ALLOW_LDOT;
+ verify(buff, used, ROCKRIDGE, &fns);
+
+ /* Verify joliet filenames. */
+ fns.longest_len = 0;
+ fns.maxlen = fns.maxflen = fns.maxelen = 64;
+ fns.opt = ALLOW_LDOT;
+ verify(buff, used, JOLIET, &fns);
+
+ /* Verify ISO9660 filenames. */
+ fns.longest_len = 0;
+ fns.maxlen = 31;
+ fns.maxflen = 30;
+ fns.maxelen = 30;
+ fns.opt = UPPER_CASE_ONLY | ONE_DOT;
+ verify(buff, used, ISO9660, &fns);
+
+ /*
+ * Create ISO image with iso-level=3.
+ */
+ assertEqualInt(fcnt, create_iso_image(buff, buffsize, &used,
+ "iso-level=3"));
+
+ /* Verify rockridge filenames. */
+ fns.longest_len = 0;
+ fns.maxlen = fns.maxflen = fns.maxelen = 255;
+ fns.opt = ALLOW_LDOT;
+ verify(buff, used, ROCKRIDGE, &fns);
+
+ /* Verify joliet filenames. */
+ fns.longest_len = 0;
+ fns.maxlen = fns.maxflen = fns.maxelen = 64;
+ fns.opt = ALLOW_LDOT;
+ verify(buff, used, JOLIET, &fns);
+
+ /* Verify ISO9660 filenames. */
+ fns.longest_len = 0;
+ fns.maxlen = 31;
+ fns.maxflen = 30;
+ fns.maxelen = 30;
+ fns.opt = UPPER_CASE_ONLY | ONE_DOT;
+ verify(buff, used, ISO9660, &fns);
+
+ /*
+ * Create ISO image with iso-level=4.
+ */
+ assertEqualInt(fcnt, create_iso_image(buff, buffsize, &used,
+ "iso-level=4"));
+
+ /* Verify rockridge filenames. */
+ fns.longest_len = 0;
+ fns.maxlen = fns.maxflen = fns.maxelen = 255;
+ fns.opt = ALLOW_LDOT;
+ verify(buff, used, ROCKRIDGE, &fns);
+
+ /* Verify joliet filenames. */
+ fns.longest_len = 0;
+ fns.maxlen = fns.maxflen = fns.maxelen = 64;
+ fns.opt = ALLOW_LDOT;
+ verify(buff, used, JOLIET, &fns);
+
+ /* Verify ISO9660 filenames. */
+ fns.longest_len = 0;
+ fns.maxlen = fns.maxflen = fns.maxelen = 193;
+ fns.opt = ALLOW_LDOT;
+ verify(buff, used, ISO9660, &fns);
+
+ /*
+ * Create ISO image with iso-level=4 and !rockridge.
+ */
+ assertEqualInt(fcnt, create_iso_image(buff, buffsize, &used,
+ "iso-level=4,!rockridge"));
+
+ /* Verify joliet filenames. */
+ fns.longest_len = 0;
+ fns.maxlen = fns.maxflen = fns.maxelen = 64;
+ fns.opt = ALLOW_LDOT;
+ verify(buff, used, JOLIET, &fns);
+
+ /* Verify ISO9660 filenames. */
+ fns.longest_len = 0;
+ fns.maxlen = fns.maxflen = fns.maxelen = 207;
+ fns.opt = ALLOW_LDOT;
+ verify(buff, used, ISO9660, &fns);
+
+ /*
+ * Create ISO image with joliet=long.
+ */
+ assertEqualInt(fcnt, create_iso_image(buff, buffsize, &used,
+ "joliet=long"));
+
+ /* Verify rockridge filenames. */
+ fns.longest_len = 0;
+ fns.maxlen = fns.maxflen = fns.maxelen = 255;
+ fns.opt = ALLOW_LDOT;
+ verify(buff, used, ROCKRIDGE, &fns);
+
+ /* Verify joliet filenames. */
+ fns.longest_len = 0;
+ fns.maxlen = fns.maxflen = fns.maxelen = 103;
+ fns.opt = ALLOW_LDOT;
+ verify(buff, used, JOLIET, &fns);
+
+ /* Verify ISO9660 filenames. */
+ fns.longest_len = 0;
+ fns.maxlen = 8+3+1;
+ fns.maxflen = 8;
+ fns.maxelen = 3;
+ fns.opt = UPPER_CASE_ONLY | ONE_DOT;
+ verify(buff, used, ISO9660, &fns);
+
+ free(fns.names);
+ free(buff);
+}
diff --git a/libarchive/test/test_write_format_iso9660_zisofs.c b/libarchive/test/test_write_format_iso9660_zisofs.c
new file mode 100644
index 000000000000..7db9b50131d1
--- /dev/null
+++ b/libarchive/test/test_write_format_iso9660_zisofs.c
@@ -0,0 +1,819 @@
+/*-
+ * Copyright (c) 2009-2011 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+
+/*
+ * Check that a "zisofs" ISO 9660 imaeg is correctly created.
+ */
+
+static const unsigned char primary_id[] = {
+ 0x01, 0x43, 0x44, 0x30, 0x30, 0x31, 0x01, 0x00
+};
+static const unsigned char volumesize[] = {
+ 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23
+};
+static const unsigned char volumesize2[] = {
+ 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36
+};
+static const unsigned char volumesize3[] = {
+ 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28
+};
+static const unsigned char volumeidu16[] = {
+ 0x00, 0x43, 0x00, 0x44, 0x00, 0x52, 0x00, 0x4f,
+ 0x00, 0x4d, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20,
+ 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20,
+ 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20
+};
+static const unsigned char supplementary_id[] = {
+ 0x02, 0x43, 0x44, 0x30, 0x30, 0x31, 0x01, 0x00
+};
+static const unsigned char terminator_id[] = {
+ 0xff, 0x43, 0x44, 0x30, 0x30, 0x31, 0x01, 0x00
+};
+
+static const unsigned char zisofs_magic[8] = {
+ 0x37, 0xE4, 0x53, 0x96, 0xC9, 0xDB, 0xD6, 0x07
+};
+
+static const unsigned char zisofs_data[24] = {
+ 0x37, 0xe4, 0x53, 0x96, 0xc9, 0xdb, 0xd6, 0x07,
+ 0x00, 0x80, 0x00, 0x00, 0x04, 0x0f, 0x00, 0x00,
+ 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00
+};
+
+static const unsigned char boot_id[] = {
+ 0x00, 0x43, 0x44, 0x30, 0x30, 0x31, 0x01, 0x45,
+ 0x4c, 0x20, 0x54, 0x4f, 0x52, 0x49, 0x54, 0x4f,
+ 0x20, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49,
+ 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+static const unsigned char boot_catalog[] = {
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xaa, 0x55, 0x55, 0xaa,
+ 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
+ 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char el_torito_signature[] = {
+ "ER\355\001\012T\207\001RRIP_1991ATHE ROCK RIDGE "
+ "INTERCHANGE PROTOCOL PROVIDES SUPPORT FOR POSIX "
+ "FILE SYSTEM SEMANTICSPLEASE CONTACT DISC PUBLISHER "
+ "FOR SPECIFICATION SOURCE. SEE PUBLISHER IDENTIFIER "
+ "IN PRIMARY VOLUME DESCRIPTOR FOR CONTACT INFORMATION."
+};
+
+static void
+test_write_format_iso9660_zisofs_1(void)
+{
+ unsigned char buff2[1024];
+ unsigned char nullb[1024];
+ struct archive *a;
+ struct archive_entry *ae;
+ unsigned char *buff;
+ size_t buffsize = 36 * 2048;
+ size_t used;
+ unsigned int i;
+ int r;
+
+ memset(nullb, 0, sizeof(nullb));
+ buff = malloc(buffsize);
+ assert(buff != NULL);
+
+ /* ISO9660 format: Create a new archive in memory. */
+ assert((a = archive_write_new()) != NULL);
+ assertEqualIntA(a, 0, archive_write_set_format_iso9660(a));
+ assertEqualIntA(a, 0, archive_write_set_compression_none(a));
+ r = archive_write_set_option(a, NULL, "zisofs", "1");
+ if (r == ARCHIVE_FATAL) {
+ skipping("zisofs option not supported on this platform");
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+ return;
+ }
+ assertEqualIntA(a, 0, archive_write_set_option(a, NULL, "pad", NULL));
+ assertEqualIntA(a, 0, archive_write_open_memory(a, buff, buffsize, &used));
+
+ /*
+ * "file1" has a bunch of attributes and 256K bytes of null data.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 20);
+ archive_entry_set_birthtime(ae, 3, 30);
+ archive_entry_set_ctime(ae, 4, 40);
+ archive_entry_set_mtime(ae, 5, 50);
+ archive_entry_copy_pathname(ae, "file1");
+ archive_entry_set_mode(ae, S_IFREG | 0755);
+ archive_entry_set_size(ae, 256*1024);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ assertEqualIntA(a, 1024, archive_write_data(a, nullb, 1024));
+
+ /*
+ * "file2" has a bunch of attributes and 2048 bytes of null data.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 20);
+ archive_entry_set_birthtime(ae, 3, 30);
+ archive_entry_set_ctime(ae, 4, 40);
+ archive_entry_set_mtime(ae, 5, 50);
+ archive_entry_copy_pathname(ae, "file2");
+ archive_entry_set_mode(ae, S_IFREG | 0755);
+ archive_entry_set_size(ae, 2048);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ assertEqualIntA(a, 1024, archive_write_data(a, nullb, 1024));
+
+ /*
+ * "file3" has a bunch of attributes and 2049 bytes of null data.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 20);
+ archive_entry_set_birthtime(ae, 3, 30);
+ archive_entry_set_ctime(ae, 4, 40);
+ archive_entry_set_mtime(ae, 5, 50);
+ archive_entry_copy_pathname(ae, "file3");
+ archive_entry_set_mode(ae, S_IFREG | 0755);
+ archive_entry_set_size(ae, 2049);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ assertEqualIntA(a, 1024, archive_write_data(a, nullb, 1024));
+
+ /*
+ * "file4" has a bunch of attributes and 24 bytes of zisofs data
+ * which is compressed from 32K bytes null data.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 20);
+ archive_entry_set_birthtime(ae, 3, 30);
+ archive_entry_set_ctime(ae, 4, 40);
+ archive_entry_set_mtime(ae, 5, 50);
+ archive_entry_copy_pathname(ae, "file4");
+ archive_entry_set_mode(ae, S_IFREG | 0755);
+ archive_entry_set_size(ae, 24);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ assertEqualIntA(a, 24, archive_write_data(a, zisofs_data, 24));
+
+ /* Close out the archive. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a));
+
+ failure("The ISO image size should be 71680 bytes.");
+ assertEqualInt(used, 2048 * 35);
+
+ /* Check System Area. */
+ for (i = 0; i < 2048 * 16; i++) {
+ failure("System Area should be all nulls.");
+ assertEqualInt(buff[i], 0);
+ }
+
+ /* Primary Volume. */
+ failure("Primary Volume Descriptor should be in 16 Logical Sector.");
+ assertEqualMem(buff+2048*16, primary_id, 8);
+ assertEqualMem(buff+2048*16+0x28,
+ "CDROM ", 32);
+ assertEqualMem(buff+2048*16+0x50, volumesize, 8);
+
+ /* Supplementary Volume. */
+ failure("Supplementary Volume(Joliet) Descriptor "
+ "should be in 17 Logical Sector.");
+ assertEqualMem(buff+2048*17, supplementary_id, 8);
+ assertEqualMem(buff+2048*17+0x28, volumeidu16, 32);
+ assertEqualMem(buff+2048*17+0x50, volumesize, 8);
+ failure("Date and Time of Primary Volume and "
+ "Date and Time of Supplementary Volume "
+ "must be the same.");
+ assertEqualMem(buff+2048*16+0x32d, buff+2048*17+0x32d, 0x44);
+
+ /* Terminator. */
+ failure("Volume Descriptor Set Terminator "
+ "should be in 18 Logical Sector.");
+ assertEqualMem(buff+2048*18, terminator_id, 8);
+ for (i = 8; i < 2048; i++) {
+ failure("Body of Volume Descriptor Set Terminator "
+ "should be all nulls.");
+ assertEqualInt(buff[2048*18+i], 0);
+ }
+
+ /* "file1" Contents is zisofs data. */
+ failure("file1 image should be zisofs'ed.");
+ assertEqualMem(buff+2048*31, zisofs_magic, 8);
+ /* "file2" Contents is not zisofs data. */
+ failure("file2 image should not be zisofs'ed.");
+ assertEqualMem(buff+2048*32, nullb, 8);
+ /* "file3" Contents is zisofs data. */
+ failure("file3 image should be zisofs'ed.");
+ assertEqualMem(buff+2048*33, zisofs_magic, 8);
+ /* "file4" Contents is zisofs data. */
+ failure("file4 image should be zisofs'ed.");
+ assertEqualMem(buff+2048*34, zisofs_magic, 8);
+
+ /*
+ * Read ISO image.
+ */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, 0, archive_read_support_format_all(a));
+ assertEqualIntA(a, 0, archive_read_support_filter_all(a));
+ assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used));
+
+ /*
+ * Read Root Directory
+ * Root Directory entry must be in ISO image.
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(archive_entry_atime(ae), archive_entry_ctime(ae));
+ assertEqualInt(archive_entry_atime(ae), archive_entry_mtime(ae));
+ assertEqualString(".", archive_entry_pathname(ae));
+ assert((S_IFDIR | 0555) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "file1" which has 256K bytes null data.
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ /* assertEqualInt(3, archive_entry_birthtime(ae)); */
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("file1", archive_entry_pathname(ae));
+ assert((S_IFREG | 0555) == archive_entry_mode(ae));
+ assertEqualInt(256*1024, archive_entry_size(ae));
+ assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
+ assertEqualMem(buff2, nullb, 1024);
+
+ /*
+ * Read "file2" which has 2048 bytes null data.
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ /* assertEqualInt(3, archive_entry_birthtime(ae)); */
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("file2", archive_entry_pathname(ae));
+ assert((S_IFREG | 0555) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+ assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
+ assertEqualMem(buff2, nullb, 1024);
+
+ /*
+ * Read "file3" which has 2049 bytes null data.
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ /* assertEqualInt(3, archive_entry_birthtime(ae)); */
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("file3", archive_entry_pathname(ae));
+ assert((S_IFREG | 0555) == archive_entry_mode(ae));
+ assertEqualInt(2049, archive_entry_size(ae));
+ assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
+ assertEqualMem(buff2, nullb, 1024);
+
+ /*
+ * Read "file4" which has 32K bytes null data.
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ /* assertEqualInt(3, archive_entry_birthtime(ae)); */
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("file4", archive_entry_pathname(ae));
+ assert((S_IFREG | 0555) == archive_entry_mode(ae));
+ assertEqualInt(32768, archive_entry_size(ae));
+ assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
+ assertEqualMem(buff2, nullb, 1024);
+
+ /*
+ * Verify the end of the archive.
+ */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
+
+ free(buff);
+}
+
+static void
+test_write_format_iso9660_zisofs_2(void)
+{
+ unsigned char buff2[1024];
+ unsigned char data[1024];
+ struct archive *a;
+ struct archive_entry *ae;
+ unsigned char *buff;
+ size_t buffsize = 60 * 2048;
+ size_t used;
+ unsigned int i;
+ int r;
+
+ buff = malloc(buffsize);
+ assert(buff != NULL);
+
+ /* ISO9660 format: Create a new archive in memory. */
+ assert((a = archive_write_new()) != NULL);
+ assertEqualIntA(a, 0, archive_write_set_format_iso9660(a));
+ assertEqualIntA(a, 0, archive_write_set_compression_none(a));
+ r = archive_write_set_option(a, NULL, "zisofs", "1");
+ if (r == ARCHIVE_FATAL) {
+ skipping("zisofs option not supported on this platform");
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+ return;
+ }
+ assertEqualIntA(a, 0, archive_write_set_option(a, NULL, "pad", NULL));
+ assertEqualIntA(a, 0, archive_write_open_memory(a, buff, buffsize, &used));
+
+ /*
+ * "file1" has a bunch of attributes and 256K bytes of random data.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 20);
+ archive_entry_set_birthtime(ae, 3, 30);
+ archive_entry_set_ctime(ae, 4, 40);
+ archive_entry_set_mtime(ae, 5, 50);
+ archive_entry_copy_pathname(ae, "file1");
+ archive_entry_set_mode(ae, S_IFREG | 0755);
+ archive_entry_set_size(ae, 256*1024);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ for (i = 0; i < 256; i++) {
+ int j;
+ if (i == 0) {
+ for (j = 0; j < sizeof(data); j++)
+ data[j] = (i^j) & 0xff;
+ } else {
+ for (j = 0; j < sizeof(data); j++)
+ data[j] ^= i+j;
+ }
+ assertEqualIntA(a, 1024, archive_write_data(a, data, 1024));
+ }
+
+ /*
+ * "file2" has a bunch of attributes and 2048 bytes data.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 20);
+ archive_entry_set_birthtime(ae, 3, 30);
+ archive_entry_set_ctime(ae, 4, 40);
+ archive_entry_set_mtime(ae, 5, 50);
+ archive_entry_copy_pathname(ae, "file2");
+ archive_entry_set_mode(ae, S_IFREG | 0755);
+ archive_entry_set_size(ae, 2048);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ memset(data, 'a', sizeof(data));
+ assertEqualIntA(a, 1024, archive_write_data(a, data, 1024));
+ memset(data, 'b', sizeof(data));
+ assertEqualIntA(a, 1024, archive_write_data(a, data, 1024));
+
+ /*
+ * "file3" has a bunch of attributes and 1024 bytes of 'Z'
+ * + 1025 bytes of null data.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 20);
+ archive_entry_set_birthtime(ae, 3, 30);
+ archive_entry_set_ctime(ae, 4, 40);
+ archive_entry_set_mtime(ae, 5, 50);
+ archive_entry_copy_pathname(ae, "file3");
+ archive_entry_set_mode(ae, S_IFREG | 0755);
+ archive_entry_set_size(ae, 2049);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ memset(data, 'Z', sizeof(data));
+ assertEqualIntA(a, 1024, archive_write_data(a, data, 1024));
+
+ /*
+ * "file4" has a bunch of attributes and 24 bytes of zisofs data
+ * which is compressed from 32K bytes null data.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 20);
+ archive_entry_set_birthtime(ae, 3, 30);
+ archive_entry_set_ctime(ae, 4, 40);
+ archive_entry_set_mtime(ae, 5, 50);
+ archive_entry_copy_pathname(ae, "file4");
+ archive_entry_set_mode(ae, S_IFREG | 0755);
+ archive_entry_set_size(ae, 24);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ assertEqualIntA(a, 24, archive_write_data(a, zisofs_data, 24));
+
+ /* Close out the archive. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a));
+
+ failure("The ISO image size should be 110592 bytes.");
+ assertEqualInt(used, 2048 * 54);
+
+ /* Check System Area. */
+ for (i = 0; i < 2048 * 16; i++) {
+ failure("System Area should be all nulls.");
+ assertEqualInt(buff[i], 0);
+ }
+
+ /* Primary Volume. */
+ failure("Primary Volume Descriptor should be in 16 Logical Sector.");
+ assertEqualMem(buff+2048*16, primary_id, 8);
+ assertEqualMem(buff+2048*16+0x28,
+ "CDROM ", 32);
+ assertEqualMem(buff+2048*16+0x50, volumesize2, 8);
+
+ /* Supplementary Volume. */
+ failure("Supplementary Volume(Joliet) Descriptor "
+ "should be in 17 Logical Sector.");
+ assertEqualMem(buff+2048*17, supplementary_id, 8);
+ assertEqualMem(buff+2048*17+0x28, volumeidu16, 32);
+ assertEqualMem(buff+2048*17+0x50, volumesize2, 8);
+ failure("Date and Time of Primary Volume and "
+ "Date and Time of Supplementary Volume "
+ "must be the same.");
+ assertEqualMem(buff+2048*16+0x32d, buff+2048*17+0x32d, 0x44);
+
+ /* Terminator. */
+ failure("Volume Descriptor Set Terminator "
+ "should be in 18 Logical Sector.");
+ assertEqualMem(buff+2048*18, terminator_id, 8);
+ for (i = 8; i < 2048; i++) {
+ failure("Body of Volume Descriptor Set Terminator "
+ "should be all nulls.");
+ assertEqualInt(buff[2048*18+i], 0);
+ }
+
+ /* "file1" Contents is zisofs data. */
+ failure("file1 image should be zisofs'ed.");
+ assertEqualMem(buff+2048*31, zisofs_magic, 8);
+ /* "file2" Contents is not zisofs data. */
+ memset(data, 'a', sizeof(data));
+ failure("file2 image should not be zisofs'ed.");
+ assertEqualMem(buff+2048*51, data, 1024);
+ memset(data, 'b', sizeof(data));
+ failure("file2 image should not be zisofs'ed.");
+ assertEqualMem(buff+2048*51+1024, data, 1024);
+ /* "file3" Contents is zisofs data. */
+ failure("file3 image should be zisofs'ed.");
+ assertEqualMem(buff+2048*52, zisofs_magic, 8);
+ /* "file4" Contents is zisofs data. */
+ failure("file4 image should be zisofs'ed.");
+ assertEqualMem(buff+2048*53, zisofs_magic, 8);
+
+ /*
+ * Read ISO image.
+ */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, 0, archive_read_support_format_all(a));
+ assertEqualIntA(a, 0, archive_read_support_filter_all(a));
+ assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used));
+
+ /*
+ * Read Root Directory
+ * Root Directory entry must be in ISO image.
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(archive_entry_atime(ae), archive_entry_ctime(ae));
+ assertEqualInt(archive_entry_atime(ae), archive_entry_mtime(ae));
+ assertEqualString(".", archive_entry_pathname(ae));
+ assert((S_IFDIR | 0555) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "file1" which has 256K bytes random data.
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("file1", archive_entry_pathname(ae));
+ assert((S_IFREG | 0555) == archive_entry_mode(ae));
+ assertEqualInt(256*1024, archive_entry_size(ae));
+ assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
+
+ /*
+ * Read "file2" which has 2048 bytes data.
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("file2", archive_entry_pathname(ae));
+ assert((S_IFREG | 0555) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+ assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
+ memset(data, 'a', sizeof(data));
+ assertEqualMem(buff2, data, 1024);
+
+ /*
+ * Read "file3" which has 2049 bytes data.
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("file3", archive_entry_pathname(ae));
+ assert((S_IFREG | 0555) == archive_entry_mode(ae));
+ assertEqualInt(2049, archive_entry_size(ae));
+ assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
+ memset(data, 'Z', sizeof(data));
+ assertEqualMem(buff2, data, 1024);
+
+ /*
+ * Read "file4" which has 32K bytes null data.
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("file4", archive_entry_pathname(ae));
+ assert((S_IFREG | 0555) == archive_entry_mode(ae));
+ assertEqualInt(32768, archive_entry_size(ae));
+ assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
+ memset(data, 0, sizeof(data));
+ assertEqualMem(buff2, data, 1024);
+
+ /*
+ * Verify the end of the archive.
+ */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
+
+ free(buff);
+}
+
+/*
+ * Make a bootable ISO image with "zisofs" option.
+ */
+static void
+test_write_format_iso9660_zisofs_3(void)
+{
+ unsigned char buff2[1024];
+ unsigned char nullb[2048];
+ struct archive *a;
+ struct archive_entry *ae;
+ unsigned char *buff;
+ size_t buffsize = 50 * 2048;
+ size_t used;
+ unsigned int i;
+ int r;
+
+ memset(nullb, 0, sizeof(nullb));
+ buff = malloc(buffsize);
+ assert(buff != NULL);
+
+ /* ISO9660 format: Create a new archive in memory. */
+ assert((a = archive_write_new()) != NULL);
+ assertEqualIntA(a, 0, archive_write_set_format_iso9660(a));
+ assertEqualIntA(a, 0, archive_write_set_compression_none(a));
+ r = archive_write_set_option(a, NULL, "zisofs", "1");
+ if (r == ARCHIVE_FATAL) {
+ skipping("zisofs option not supported on this platform");
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+ return;
+ }
+ assertEqualIntA(a, 0, archive_write_set_option(a, NULL, "boot", "boot.img"));
+ assertEqualIntA(a, 0, archive_write_set_option(a, NULL, "pad", NULL));
+ assertEqualIntA(a, 0, archive_write_open_memory(a, buff, buffsize, &used));
+
+ /*
+ * "file1" has a bunch of attributes and 256K bytes of null data.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 20);
+ archive_entry_set_birthtime(ae, 3, 30);
+ archive_entry_set_ctime(ae, 4, 40);
+ archive_entry_set_mtime(ae, 5, 50);
+ archive_entry_copy_pathname(ae, "boot.img");
+ archive_entry_set_mode(ae, S_IFREG | 0755);
+ archive_entry_set_size(ae, 10*1024);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ assertEqualIntA(a, 1024, archive_write_data(a, nullb, 1024));
+
+ /*
+ * "file2" has a bunch of attributes and 2048 bytes of null data.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 20);
+ archive_entry_set_birthtime(ae, 3, 30);
+ archive_entry_set_ctime(ae, 4, 40);
+ archive_entry_set_mtime(ae, 5, 50);
+ archive_entry_copy_pathname(ae, "file2");
+ archive_entry_set_mode(ae, S_IFREG | 0755);
+ archive_entry_set_size(ae, 2048);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ assertEqualIntA(a, 1024, archive_write_data(a, nullb, 1024));
+
+ /*
+ * "file3" has a bunch of attributes and 2049 bytes of null data.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 20);
+ archive_entry_set_birthtime(ae, 3, 30);
+ archive_entry_set_ctime(ae, 4, 40);
+ archive_entry_set_mtime(ae, 5, 50);
+ archive_entry_copy_pathname(ae, "file3");
+ archive_entry_set_mode(ae, S_IFREG | 0755);
+ archive_entry_set_size(ae, 2049);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ assertEqualIntA(a, 1024, archive_write_data(a, nullb, 1024));
+
+ /* Close out the archive. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a));
+
+ failure("The ISO image size should be 81920 bytes.");
+ assertEqualInt(used, 2048 * 40);
+
+ /* Check System Area. */
+ for (i = 0; i < 2048 * 16; i++) {
+ failure("System Area should be all nulls.");
+ assertEqualInt(buff[i], 0);
+ }
+
+ /* Primary Volume. */
+ failure("Primary Volume Descriptor should be in 16 Logical Sector.");
+ assertEqualMem(buff+2048*16, primary_id, 8);
+ assertEqualMem(buff+2048*16+0x28,
+ "CDROM ", 32);
+ assertEqualMem(buff+2048*16+0x50, volumesize3, 8);
+
+ /* Boot Volume. */
+ failure("Boot Volume Descriptor should be in 17 Logical Sector.");
+ assertEqualMem(buff+2048*17, boot_id, sizeof(boot_id));
+ for (i = 0x27; i <= 0x46; i++) {
+ failure("Unused area must be all nulls.");
+ assert(buff[2048*17+i] == 0);
+ }
+ /* First sector of Boot Catalog. */
+ assert(buff[2048*17+0x47] == 0x20);
+ assert(buff[2048*17+0x48] == 0x00);
+ assert(buff[2048*17+0x49] == 0x00);
+ assert(buff[2048*17+0x4a] == 0x00);
+ for (i = 0x4a; i <= 0x7ff; i++) {
+ failure("Unused area must be all nulls.");
+ assert(buff[2048*17+i] == 0);
+ }
+
+ /* Supplementary Volume. */
+ failure("Supplementary Volume(Joliet) Descriptor "
+ "should be in 18 Logical Sector.");
+ assertEqualMem(buff+2048*18, supplementary_id, 8);
+ assertEqualMem(buff+2048*18+0x28, volumeidu16, 32);
+ assertEqualMem(buff+2048*18+0x50, volumesize3, 8);
+ failure("Date and Time of Primary Volume and "
+ "Date and Time of Supplementary Volume "
+ "must be the same.");
+ assertEqualMem(buff+2048*16+0x32d, buff+2048*18+0x32d, 0x44);
+
+ /* Terminator. */
+ failure("Volume Descriptor Set Terminator "
+ "should be in 19 Logical Sector.");
+ assertEqualMem(buff+2048*19, terminator_id, 8);
+ for (i = 8; i < 2048; i++) {
+ failure("Body of Volume Descriptor Set Terminator "
+ "should be all nulls.");
+ assertEqualInt(buff[2048*19+i], 0);
+ }
+
+ /* Check signature of El-Torito. */
+ assertEqualMem(buff+2048*31, el_torito_signature, 237);
+ assertEqualMem(buff+2048*31+237, nullb, 2048-237);
+
+ /* Check contents of "boot.catalog". */
+ assertEqualMem(buff+2048*32, boot_catalog, 64);
+ assertEqualMem(buff+2048*32+64, nullb, 2048-64);
+
+ /* Check contents of "boot.img". */
+ failure("boot.img image should not be zisofs'ed.");
+ assertEqualMem(buff+2048*33, nullb, 2048);
+ for (i = 2048*34; i < 2048*38; i += 2048) {
+ assertEqualMem(buff+i, nullb, 2048);
+ }
+
+ /* "file2" Contents is not zisofs data. */
+ failure("file2 image should not be zisofs'ed.");
+ assertEqualMem(buff+2048*38, nullb, 8);
+ /* "file3" Contents is zisofs data. */
+ failure("file3 image should be zisofs'ed.");
+ assertEqualMem(buff+2048*39, zisofs_magic, 8);
+
+ /*
+ * Read ISO image.
+ */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, 0, archive_read_support_format_all(a));
+ assertEqualIntA(a, 0, archive_read_support_filter_all(a));
+ assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used));
+
+ /*
+ * Read Root Directory
+ * Root Directory entry must be in ISO image.
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(archive_entry_atime(ae), archive_entry_ctime(ae));
+ assertEqualInt(archive_entry_atime(ae), archive_entry_mtime(ae));
+ assertEqualString(".", archive_entry_pathname(ae));
+ assert((S_IFDIR | 0555) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "boot.catalog".
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualString("boot.catalog", archive_entry_pathname(ae));
+#if !defined(_WIN32) && !defined(__CYGWIN__)
+ assert((S_IFREG | 0444) == archive_entry_mode(ae));
+#else
+ /* On Windows and CYGWIN, always set all exec bit ON by default. */
+ assert((S_IFREG | 0555) == archive_entry_mode(ae));
+#endif
+ assertEqualInt(1, archive_entry_nlink(ae));
+ assertEqualInt(2*1024, archive_entry_size(ae));
+ assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
+ assertEqualMem(buff2, boot_catalog, 64);
+
+ /*
+ * Read "boot.img".
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(3, archive_entry_birthtime(ae));
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("boot.img", archive_entry_pathname(ae));
+ assert((S_IFREG | 0555) == archive_entry_mode(ae));
+ assertEqualInt(1, archive_entry_nlink(ae));
+ assertEqualInt(10*1024, archive_entry_size(ae));
+ assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
+ assertEqualMem(buff2, nullb, 1024);
+
+ /*
+ * Read "file2" which has 2048 bytes null data.
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("file2", archive_entry_pathname(ae));
+ assert((S_IFREG | 0555) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+ assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
+ assertEqualMem(buff2, nullb, 1024);
+
+ /*
+ * Read "file3" which has 2049 bytes null data.
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("file3", archive_entry_pathname(ae));
+ assert((S_IFREG | 0555) == archive_entry_mode(ae));
+ assertEqualInt(2049, archive_entry_size(ae));
+ assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
+ assertEqualMem(buff2, nullb, 1024);
+
+ /*
+ * Verify the end of the archive.
+ */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
+
+ free(buff);
+}
+
+DEFINE_TEST(test_write_format_iso9660_zisofs)
+{
+ test_write_format_iso9660_zisofs_1();
+ test_write_format_iso9660_zisofs_2();
+ test_write_format_iso9660_zisofs_3();
+}
diff --git a/libarchive/test/test_write_format_mtree.c b/libarchive/test/test_write_format_mtree.c
index e0b78f557165..ee436d08d5bf 100644
--- a/libarchive/test/test_write_format_mtree.c
+++ b/libarchive/test/test_write_format_mtree.c
@@ -59,12 +59,12 @@ test_write_format_mtree_sub(int use_set, int dironly)
/* Create a mtree format archive. */
assert((a = archive_write_new()) != NULL);
- assertA(0 == archive_write_set_format_mtree(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_mtree(a));
if (use_set)
- assertA(0 == archive_write_set_options(a, "use-set"));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_option(a, NULL, "use-set", "1"));
if (dironly)
- assertA(0 == archive_write_set_options(a, "dironly"));
- assertA(0 == archive_write_open_memory(a, buff, sizeof(buff)-1, &used));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_option(a, NULL, "dironly", "1"));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff)-1, &used));
/* Write entries */
for (i = 0; entries[i].path != NULL; i++) {
@@ -80,17 +80,15 @@ test_write_format_mtree_sub(int use_set, int dironly)
archive_entry_copy_pathname(ae, entries[i].path);
if ((entries[i].mode & AE_IFMT) != S_IFDIR)
archive_entry_set_size(ae, 8);
- assertA(0 == archive_write_header(a, ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
if ((entries[i].mode & AE_IFMT) != S_IFDIR)
- assertA(8 == archive_write_data(a, "Hello012", 15));
+ assertEqualIntA(a, 8,
+ archive_write_data(a, "Hello012", 15));
archive_entry_free(ae);
}
- archive_write_close(a);
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_write_finish(a);
-#else
- assertEqualInt(0, archive_write_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
if (use_set) {
const char *p;
@@ -118,7 +116,7 @@ test_write_format_mtree_sub(int use_set, int dironly)
*/
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
- assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used));
/* Read entries */
@@ -134,12 +132,8 @@ test_write_format_mtree_sub(int use_set, int dironly)
if ((entries[i].mode & AE_IFMT) != S_IFDIR)
assertEqualInt(8, archive_entry_size(ae));
}
- assertEqualIntA(a, 0, archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assertEqualInt(0, archive_read_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
DEFINE_TEST(test_write_format_mtree)
diff --git a/libarchive/test/test_write_format_mtree_fflags.c b/libarchive/test/test_write_format_mtree_fflags.c
new file mode 100644
index 000000000000..18689fe855de
--- /dev/null
+++ b/libarchive/test/test_write_format_mtree_fflags.c
@@ -0,0 +1,134 @@
+/*-
+ * Copyright (c) 2011 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "test.h"
+__FBSDID("$FreeBSD$");
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+/*
+ * Test UFS file flags with/without use-set option.
+ */
+#if defined(UF_IMMUTABLE) && defined(UF_NODUMP)
+
+static char buff[4096];
+static struct {
+ const char *path;
+ unsigned long fflags;
+} entries[] = {
+ { "./f1", UF_IMMUTABLE | UF_NODUMP },
+ { "./f2", 0 },
+ { "./f3", UF_NODUMP },
+ { NULL, 0 }
+};
+
+static void
+test_write_format_mtree_sub(int use_set)
+{
+ struct archive_entry *ae;
+ struct archive* a;
+ size_t used;
+ int i;
+
+ /* Create a mtree format archive. */
+ assert((a = archive_write_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_mtree(a));
+ if (use_set)
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_options(a, "use-set,!all,flags,type"));
+ else
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_options(a, "!all,flags,type"));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff)-1, &used));
+
+ /* Write entries */
+ for (i = 0; entries[i].path != NULL; i++) {
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_fflags(ae, entries[i].fflags, 0);
+ archive_entry_copy_pathname(ae, entries[i].path);
+ archive_entry_set_size(ae, 0);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ }
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ if (use_set) {
+ const char *p;
+
+ buff[used] = '\0';
+ assert(NULL != (p = strstr(buff, "\n/set ")));
+ if (p != NULL) {
+ char *r;
+ const char *o;
+ p++;
+ r = strchr(p, '\n');
+ if (r != NULL)
+ *r = '\0';
+ o = "/set type=file flags=uchg,nodump";
+ assertEqualString(o, p);
+ if (r != NULL)
+ *r = '\n';
+ }
+ }
+
+ /*
+ * Read the data and check it.
+ */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used));
+
+ /* Read entries */
+ for (i = 0; entries[i].path != NULL; i++) {
+ unsigned long fset, fclr;
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ archive_entry_fflags(ae, &fset, &fclr);
+ assertEqualInt((int)entries[i].fflags, (int)fset);
+ assertEqualInt(0, (int)fclr);
+ assertEqualString(entries[i].path, archive_entry_pathname(ae));
+ }
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+#endif
+
+DEFINE_TEST(test_write_format_mtree_fflags)
+{
+#if defined(UF_IMMUTABLE) && defined(UF_NODUMP)
+ /* Default setting */
+ test_write_format_mtree_sub(0);
+ /* Use /set keyword */
+ test_write_format_mtree_sub(1);
+#else
+ skipping("This platform does not support UFS file flags");
+#endif
+}
diff --git a/libarchive/test/test_write_format_pax.c b/libarchive/test/test_write_format_pax.c
index 06cfca6fe992..21517188e1da 100644
--- a/libarchive/test/test_write_format_pax.c
+++ b/libarchive/test/test_write_format_pax.c
@@ -34,6 +34,9 @@ DEFINE_TEST(test_write_format_pax)
struct archive_entry *ae;
struct archive *a;
size_t used;
+ int i;
+ char nulls[1024];
+ int64_t offset, length;
buff = malloc(buffsize); /* million bytes of work area */
assert(buff != NULL);
@@ -75,6 +78,27 @@ DEFINE_TEST(test_write_format_pax)
assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9));
/*
+ * "file3" is sparse file and has hole size of which is
+ * 1024000 bytes, and has 8 bytes data after the hole.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 20);
+ archive_entry_set_birthtime(ae, 3, 30);
+ archive_entry_set_ctime(ae, 4, 40);
+ archive_entry_set_mtime(ae, 5, 50);
+ archive_entry_copy_pathname(ae, "file3");
+ archive_entry_set_mode(ae, S_IFREG | 0755);
+ archive_entry_set_size(ae, 1024008);
+ archive_entry_sparse_add_entry(ae, 1024000, 8);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ memset(nulls, 0, sizeof(nulls));
+ for (i = 0; i < 1024000; i += 1024)
+ /* write hole data, which won't be stored into an archive file. */
+ assertEqualIntA(a, 1024, archive_write_data(a, nulls, 1024));
+ assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9));
+
+ /*
* XXX TODO XXX Archive directory, other file types.
* Archive extended attributes, ACLs, other metadata.
* Verify they get read back correctly.
@@ -82,7 +106,7 @@ DEFINE_TEST(test_write_format_pax)
/* Close out the archive. */
assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
- assertEqualIntA(a, ARCHIVE_OK, archive_write_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a));
/*
*
@@ -91,7 +115,7 @@ DEFINE_TEST(test_write_format_pax)
*/
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, 0, archive_read_support_format_all(a));
- assertEqualIntA(a, 0, archive_read_support_compression_all(a));
+ assertEqualIntA(a, 0, archive_read_support_filter_all(a));
assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used));
/*
@@ -136,11 +160,40 @@ DEFINE_TEST(test_write_format_pax)
assertEqualMem(buff2, "12345678", 8);
/*
+ * Read "file3"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(20, archive_entry_atime_nsec(ae));
+ assertEqualInt(3, archive_entry_birthtime(ae));
+ assertEqualInt(30, archive_entry_birthtime_nsec(ae));
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(40, archive_entry_ctime_nsec(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualInt(50, archive_entry_mtime_nsec(ae));
+ assertEqualString("file3", archive_entry_pathname(ae));
+ assert((S_IFREG | 0755) == archive_entry_mode(ae));
+ assertEqualInt(1024008, archive_entry_size(ae));
+ assertEqualInt(1, archive_entry_sparse_reset(ae));
+ assertEqualInt(ARCHIVE_OK,
+ archive_entry_sparse_next(ae, &offset, &length));
+ assertEqualInt(1024000, offset);
+ assertEqualInt(8, length);
+ for (i = 0; i < 1024000; i += 1024) {
+ int j;
+ assertEqualIntA(a, 1024, archive_read_data(a, nulls, 1024));
+ for (j = 0; j < 1024; j++)
+ assertEqualInt(0, nulls[j]);
+ }
+ assertEqualIntA(a, 8, archive_read_data(a, buff2, 10));
+ assertEqualMem(buff2, "12345678", 8);
+
+ /*
* Verify the end of the archive.
*/
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
- assertEqualIntA(a, ARCHIVE_OK, archive_read_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
free(buff);
}
diff --git a/libarchive/test/test_write_format_shar_empty.c b/libarchive/test/test_write_format_shar_empty.c
index 14ee3889a366..09cfcd6b7598 100644
--- a/libarchive/test/test_write_format_shar_empty.c
+++ b/libarchive/test/test_write_format_shar_empty.c
@@ -46,12 +46,8 @@ DEFINE_TEST(test_write_format_shar_empty)
assertA(0 == archive_write_open_memory(a, buff, sizeof(buff), &used));
/* Close out the archive. */
- assertA(0 == archive_write_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_write_finish(a);
-#else
- assertA(0 == archive_write_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
failure("Empty shar archive should be exactly 0 bytes, was %d.", used);
assert(used == 0);
diff --git a/libarchive/test/test_write_format_tar.c b/libarchive/test/test_write_format_tar.c
index 372fef1f0232..81aeab64b334 100644
--- a/libarchive/test/test_write_format_tar.c
+++ b/libarchive/test/test_write_format_tar.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2003-2010 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -40,75 +40,80 @@ DEFINE_TEST(test_write_format_tar)
for (blocksize = 1; blocksize < 100000; blocksize += blocksize + 3) {
/* Create a new archive in memory. */
assert((a = archive_write_new()) != NULL);
- assertA(0 == archive_write_set_format_ustar(a));
- assertA(0 == archive_write_set_compression_none(a));
- assertA(0 == archive_write_set_bytes_per_block(a, (int)blocksize));
- assertA(0 == archive_write_set_bytes_in_last_block(a, (int)blocksize));
- assertA(blocksize == (size_t)archive_write_get_bytes_in_last_block(a));
- assertA(0 == archive_write_open_memory(a, buff, sizeof(buff), &used));
- assertA(blocksize == (size_t)archive_write_get_bytes_in_last_block(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_format_ustar(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_compression_none(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_bytes_per_block(a, (int)blocksize));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_bytes_in_last_block(a, (int)blocksize));
+ assertEqualInt(blocksize,
+ archive_write_get_bytes_in_last_block(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+ assertEqualInt(blocksize,
+ archive_write_get_bytes_in_last_block(a));
/*
* Write a file to it.
*/
assert((ae = archive_entry_new()) != NULL);
archive_entry_set_mtime(ae, 1, 10);
- assert(1 == archive_entry_mtime(ae));
-#if !defined(__INTERIX)
- assert(10 == archive_entry_mtime_nsec(ae));
-#endif
+ assertEqualInt(1, archive_entry_mtime(ae));
+ assertEqualInt(10, archive_entry_mtime_nsec(ae));
p = strdup("file");
archive_entry_copy_pathname(ae, p);
strcpy(p, "XXXX");
free(p);
assertEqualString("file", archive_entry_pathname(ae));
archive_entry_set_mode(ae, S_IFREG | 0755);
- assert((S_IFREG | 0755) == archive_entry_mode(ae));
+ assertEqualInt(S_IFREG | 0755, archive_entry_mode(ae));
archive_entry_set_size(ae, 8);
- assertA(0 == archive_write_header(a, ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
archive_entry_free(ae);
- assertA(8 == archive_write_data(a, "12345678", 9));
+ assertEqualInt(8, archive_write_data(a, "12345678", 9));
/* Close out the archive. */
- assertA(0 == archive_write_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_write_finish(a);
-#else
- assertA(0 == archive_write_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
/* This calculation gives "the smallest multiple of
* the block size that is at least 2048 bytes". */
- assert(((2048 - 1)/blocksize+1)*blocksize == used);
+ failure("blocksize=%d", blocksize);
+ assertEqualInt(((2048 - 1)/blocksize+1)*blocksize, used);
/*
* Now, read the data back.
*/
assert((a = archive_read_new()) != NULL);
- assertA(0 == archive_read_support_format_all(a));
- assertA(0 == archive_read_support_compression_all(a));
- assertA(0 == archive_read_open_memory(a, buff, used));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_memory(a, buff, used));
- assertA(0 == archive_read_next_header(a, &ae));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_next_header(a, &ae));
- assert(1 == archive_entry_mtime(ae));
+ assertEqualInt(1, archive_entry_mtime(ae));
/* Not the same as above: ustar doesn't store hi-res times. */
- assert(0 == archive_entry_mtime_nsec(ae));
- assert(0 == archive_entry_atime(ae));
- assert(0 == archive_entry_ctime(ae));
+ assertEqualInt(0, archive_entry_mtime_nsec(ae));
+ assertEqualInt(0, archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_ctime(ae));
assertEqualString("file", archive_entry_pathname(ae));
- assert((S_IFREG | 0755) == archive_entry_mode(ae));
- assert(8 == archive_entry_size(ae));
- assertA(8 == archive_read_data(a, buff2, 10));
- assert(0 == memcmp(buff2, "12345678", 8));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae));
+ assertEqualInt(8, archive_entry_size(ae));
+ assertEqualInt(8, archive_read_data(a, buff2, 10));
+ assertEqualMem(buff2, "12345678", 8);
/* Verify the end of the archive. */
- assert(1 == archive_read_next_header(a, &ae));
- assert(0 == archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
- assert(0 == archive_read_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_EOF,
+ archive_read_next_header(a, &ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
}
diff --git a/libarchive/test/test_write_format_tar_empty.c b/libarchive/test/test_write_format_tar_empty.c
index 6b40f0767f3e..f9e972b4064b 100644
--- a/libarchive/test/test_write_format_tar_empty.c
+++ b/libarchive/test/test_write_format_tar_empty.c
@@ -45,19 +45,10 @@ DEFINE_TEST(test_write_format_tar_empty)
assertA(0 == archive_write_open_memory(a, buff, sizeof(buff), &used));
/* Close out the archive. */
- assertA(0 == archive_write_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_write_finish(a);
-#else
- assertA(0 == archive_write_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
-#if ARCHIVE_VERSION_NUMBER < 1009000
- /* Earlier versions wrote 0-length files for empty tar archives. */
- skipping("empty tar archive size");
-#else
assert(used == 1024);
-#endif
for (i = 0; i < used; i++) {
failure("Empty tar archive should be all nulls.");
assert(buff[i] == 0);
@@ -72,19 +63,10 @@ DEFINE_TEST(test_write_format_tar_empty)
assertA(0 == archive_write_open_memory(a, buff, sizeof(buff), &used));
/* Close out the archive. */
- assertA(0 == archive_write_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_write_finish(a);
-#else
- assertA(0 == archive_write_finish(a));
-#endif
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
-#if ARCHIVE_VERSION_NUMBER < 1009000
- /* Earlier versions wrote 0-length files for empty tar archives. */
- skipping("empty tar archive size");
-#else
assertEqualInt((int)used, 1024);
-#endif
for (i = 0; i < used; i++) {
failure("Empty tar archive should be all nulls.");
assert(buff[i] == 0);
diff --git a/libarchive/test/test_write_format_tar_sparse.c b/libarchive/test/test_write_format_tar_sparse.c
new file mode 100644
index 000000000000..00478160df9a
--- /dev/null
+++ b/libarchive/test/test_write_format_tar_sparse.c
@@ -0,0 +1,305 @@
+/*-
+ * Copyright (c) 2003-2010 Tim Kientzle
+ * Copyright (c) 2012 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+char buff[1000000];
+
+static void
+test_1(void)
+{
+ struct archive_entry *ae;
+ struct archive *a;
+ size_t used;
+ size_t blocksize;
+ int64_t offset, length;
+ char *buff2;
+ size_t buff2_size = 0x13000;
+ char buff3[1024];
+ long i;
+
+ assert((buff2 = malloc(buff2_size)) != NULL);
+ /* Repeat the following for a variety of odd blocksizes. */
+ for (blocksize = 1; blocksize < 100000; blocksize += blocksize + 3) {
+ /* Create a new archive in memory. */
+ assert((a = archive_write_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_format_pax(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_compression_none(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_bytes_per_block(a, (int)blocksize));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_bytes_in_last_block(a, (int)blocksize));
+ assertEqualInt(blocksize,
+ archive_write_get_bytes_in_last_block(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+ assertEqualInt(blocksize,
+ archive_write_get_bytes_in_last_block(a));
+
+ /*
+ * Write a file to it.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_mtime(ae, 1, 10);
+ assertEqualInt(1, archive_entry_mtime(ae));
+ assertEqualInt(10, archive_entry_mtime_nsec(ae));
+ archive_entry_copy_pathname(ae, "file");
+ assertEqualString("file", archive_entry_pathname(ae));
+ archive_entry_set_mode(ae, S_IFREG | 0755);
+ assertEqualInt(S_IFREG | 0755, archive_entry_mode(ae));
+ archive_entry_set_size(ae, 0x81000);
+ archive_entry_sparse_add_entry(ae, 0x10000, 0x1000);
+ archive_entry_sparse_add_entry(ae, 0x80000, 0x1000);
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ memset(buff2, 'a', buff2_size);
+ for (i = 0; i < 0x81000;) {
+ size_t ws = buff2_size;
+ if (i + ws > 0x81000)
+ ws = 0x81000 - i;
+ assertEqualInt(ws,
+ archive_write_data(a, buff2, ws));
+ i += ws;
+ }
+
+ /* Close out the archive. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* This calculation gives "the smallest multiple of
+ * the block size that is at least 11264 bytes". */
+ failure("blocksize=%d", blocksize);
+ assertEqualInt(((11264 - 1)/blocksize+1)*blocksize, used);
+
+ /*
+ * Now, read the data back.
+ */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_memory(a, buff, used));
+
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_next_header(a, &ae));
+
+ assertEqualInt(1, archive_entry_mtime(ae));
+ assertEqualInt(10, archive_entry_mtime_nsec(ae));
+ assertEqualInt(0, archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_ctime(ae));
+ assertEqualString("file", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae));
+ assertEqualInt(0x81000, archive_entry_size(ae));
+ /* Verify sparse information. */
+ assertEqualInt(2, archive_entry_sparse_reset(ae));
+ assertEqualInt(0,
+ archive_entry_sparse_next(ae, &offset, &length));
+ assertEqualInt(0x10000, offset);
+ assertEqualInt(0x1000, length);
+ assertEqualInt(0,
+ archive_entry_sparse_next(ae, &offset, &length));
+ assertEqualInt(0x80000, offset);
+ assertEqualInt(0x1000, length);
+ /* Verify file contents. */
+ memset(buff3, 0, sizeof(buff3));
+ for (i = 0; i < 0x10000; i += 1024) {
+ assertEqualInt(1024, archive_read_data(a, buff2, 1024));
+ failure("Read data(0x%lx - 0x%lx) should be all zero",
+ i, i + 1024);
+ assertEqualMem(buff2, buff3, 1024);
+ }
+ memset(buff3, 'a', sizeof(buff3));
+ for (i = 0x10000; i < 0x11000; i += 1024) {
+ assertEqualInt(1024, archive_read_data(a, buff2, 1024));
+ failure("Read data(0x%lx - 0x%lx) should be all 'a'",
+ i, i + 1024);
+ assertEqualMem(buff2, buff3, 1024);
+ }
+ memset(buff3, 0, sizeof(buff3));
+ for (i = 0x11000; i < 0x80000; i += 1024) {
+ assertEqualInt(1024, archive_read_data(a, buff2, 1024));
+ failure("Read data(0x%lx - 0x%lx) should be all zero",
+ i, i + 1024);
+ assertEqualMem(buff2, buff3, 1024);
+ }
+ memset(buff3, 'a', sizeof(buff3));
+ for (i = 0x80000; i < 0x81000; i += 1024) {
+ assertEqualInt(1024, archive_read_data(a, buff2, 1024));
+ failure("Read data(0x%lx - 0x%lx) should be all 'a'",
+ i, i + 1024);
+ assertEqualMem(buff2, buff3, 1024);
+ }
+
+ /* Verify the end of the archive. */
+ assertEqualIntA(a, ARCHIVE_EOF,
+ archive_read_next_header(a, &ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+ }
+ free(buff2);
+}
+
+/*
+ * Test for the case the full bytes of sparse file data is not written.
+ */
+static void
+test_2(void)
+{
+ struct archive_entry *ae;
+ struct archive *a;
+ size_t used;
+ size_t blocksize = 20 * 512;
+ int64_t offset, length;
+ char *buff2;
+ size_t buff2_size = 0x11000;
+ char buff3[1024];
+ long i;
+
+ assert((buff2 = malloc(buff2_size)) != NULL);
+ /* Create a new archive in memory. */
+ assert((a = archive_write_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_format_pax(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_compression_none(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_bytes_per_block(a, (int)blocksize));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_bytes_in_last_block(a, (int)blocksize));
+ assertEqualInt(blocksize,
+ archive_write_get_bytes_in_last_block(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+ assertEqualInt(blocksize,
+ archive_write_get_bytes_in_last_block(a));
+
+ /*
+ * Write a file to it.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_mtime(ae, 1, 10);
+ assertEqualInt(1, archive_entry_mtime(ae));
+ assertEqualInt(10, archive_entry_mtime_nsec(ae));
+ archive_entry_copy_pathname(ae, "file");
+ assertEqualString("file", archive_entry_pathname(ae));
+ archive_entry_set_mode(ae, S_IFREG | 0755);
+ assertEqualInt(S_IFREG | 0755, archive_entry_mode(ae));
+ archive_entry_set_size(ae, 0x81000);
+ archive_entry_sparse_add_entry(ae, 0x10000, 0x1000);
+ archive_entry_sparse_add_entry(ae, 0x80000, 0x1000);
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ memset(buff2, 'a', buff2_size);
+ /* Write bytes less than it should be. */
+ assertEqualInt(buff2_size, archive_write_data(a, buff2, buff2_size));
+
+ /* Close out the archive. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* This calculation gives "the smallest multiple of
+ * the block size that is at least 11264 bytes". */
+ failure("blocksize=%d", blocksize);
+ assertEqualInt(((11264 - 1)/blocksize+1)*blocksize, used);
+
+ /*
+ * Now, read the data back.
+ */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+
+ assertEqualInt(1, archive_entry_mtime(ae));
+ assertEqualInt(10, archive_entry_mtime_nsec(ae));
+ assertEqualInt(0, archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_ctime(ae));
+ assertEqualString("file", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae));
+ assertEqualInt(0x81000, archive_entry_size(ae));
+ /* Verify sparse information. */
+ assertEqualInt(2, archive_entry_sparse_reset(ae));
+ assertEqualInt(0, archive_entry_sparse_next(ae, &offset, &length));
+ assertEqualInt(0x10000, offset);
+ assertEqualInt(0x1000, length);
+ assertEqualInt(0, archive_entry_sparse_next(ae, &offset, &length));
+ assertEqualInt(0x80000, offset);
+ assertEqualInt(0x1000, length);
+ /* Verify file contents. */
+ memset(buff3, 0, sizeof(buff3));
+ for (i = 0; i < 0x10000; i += 1024) {
+ assertEqualInt(1024, archive_read_data(a, buff2, 1024));
+ failure("Read data(0x%lx - 0x%lx) should be all zero",
+ i, i + 1024);
+ assertEqualMem(buff2, buff3, 1024);
+ }
+ memset(buff3, 'a', sizeof(buff3));
+ for (i = 0x10000; i < 0x11000; i += 1024) {
+ assertEqualInt(1024, archive_read_data(a, buff2, 1024));
+ failure("Read data(0x%lx - 0x%lx) should be all 'a'",
+ i, i + 1024);
+ assertEqualMem(buff2, buff3, 1024);
+ }
+ memset(buff3, 0, sizeof(buff3));
+ for (i = 0x11000; i < 0x80000; i += 1024) {
+ assertEqualInt(1024, archive_read_data(a, buff2, 1024));
+ failure("Read data(0x%lx - 0x%lx) should be all zero",
+ i, i + 1024);
+ assertEqualMem(buff2, buff3, 1024);
+ }
+ memset(buff3, 0, sizeof(buff3));
+ for (i = 0x80000; i < 0x81000; i += 1024) {
+ assertEqualInt(1024, archive_read_data(a, buff2, 1024));
+ failure("Read data(0x%lx - 0x%lx) should be all 'a'",
+ i, i + 1024);
+ assertEqualMem(buff2, buff3, 1024);
+ }
+
+ /* Verify the end of the archive. */
+ assertEqualIntA(a, ARCHIVE_EOF,
+ archive_read_next_header(a, &ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+ free(buff2);
+}
+
+DEFINE_TEST(test_write_format_tar_sparse)
+{
+ /* Test1: archiving sparse files. */
+ test_1();
+ /* Test2: incompletely archiving sparse files. */
+ test_2();
+}
diff --git a/libarchive/test/test_write_format_tar_ustar.c b/libarchive/test/test_write_format_tar_ustar.c
index 29968dfb3313..52b50f45197d 100644
--- a/libarchive/test/test_write_format_tar_ustar.c
+++ b/libarchive/test/test_write_format_tar_ustar.c
@@ -76,9 +76,12 @@ DEFINE_TEST(test_write_format_tar_ustar)
/* Create a new archive in memory. */
assert((a = archive_write_new()) != NULL);
- assertEqualIntA(a, 0, archive_write_set_format_ustar(a));
- assertEqualIntA(a, 0, archive_write_set_compression_none(a));
- assertEqualIntA(a, 0, archive_write_open_memory(a, buff, buffsize, &used));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_format_ustar(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_compression_none(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_open_memory(a, buff, buffsize, &used));
/*
* Add various files to it.
@@ -96,7 +99,8 @@ DEFINE_TEST(test_write_format_tar_ustar)
archive_entry_set_dev(entry, 12);
archive_entry_set_ino(entry, 89);
archive_entry_set_nlink(entry, 2);
- assertEqualIntA(a, 0, archive_write_header(a, entry));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_header(a, entry));
archive_entry_free(entry);
assertEqualIntA(a, 10, archive_write_data(a, "1234567890", 10));
@@ -112,7 +116,8 @@ DEFINE_TEST(test_write_format_tar_ustar)
archive_entry_set_dev(entry, 12);
archive_entry_set_ino(entry, 89);
archive_entry_set_nlink(entry, 2);
- assertEqualIntA(a, 0, archive_write_header(a, entry));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_header(a, entry));
archive_entry_free(entry);
/* Write of data to dir should fail == zero bytes get written. */
assertEqualIntA(a, 0, archive_write_data(a, "1234567890", 10));
@@ -124,7 +129,8 @@ DEFINE_TEST(test_write_format_tar_ustar)
archive_entry_set_mode(entry, S_IFDIR | 0775);
archive_entry_set_size(entry, 10);
archive_entry_set_nlink(entry, 2);
- assertEqualIntA(a, 0, archive_write_header(a, entry));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_header(a, entry));
archive_entry_free(entry);
/* Write of data to dir should fail == zero bytes get written. */
assertEqualIntA(a, 0, archive_write_data(a, "1234567890", 10));
@@ -142,7 +148,8 @@ DEFINE_TEST(test_write_format_tar_ustar)
archive_entry_set_dev(entry, 12);
archive_entry_set_ino(entry, 90);
archive_entry_set_nlink(entry, 1);
- assertEqualIntA(a, 0, archive_write_header(a, entry));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_header(a, entry));
archive_entry_free(entry);
/* Write of data to symlink should fail == zero bytes get written. */
assertEqualIntA(a, 0, archive_write_data(a, "1234567890", 10));
@@ -158,7 +165,8 @@ DEFINE_TEST(test_write_format_tar_ustar)
archive_entry_set_dev(entry, 102);
archive_entry_set_ino(entry, 7);
archive_entry_set_nlink(entry, 1);
- assertEqualIntA(a, 0, archive_write_header(a, entry));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_header(a, entry));
archive_entry_free(entry);
/* file with 100-char filename. */
@@ -172,7 +180,8 @@ DEFINE_TEST(test_write_format_tar_ustar)
archive_entry_set_dev(entry, 102);
archive_entry_set_ino(entry, 7);
archive_entry_set_nlink(entry, 1);
- assertEqualIntA(a, 0, archive_write_header(a, entry));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_header(a, entry));
archive_entry_free(entry);
/* file with 256-char filename. */
@@ -186,14 +195,12 @@ DEFINE_TEST(test_write_format_tar_ustar)
archive_entry_set_dev(entry, 102);
archive_entry_set_ino(entry, 7);
archive_entry_set_nlink(entry, 1);
- assertEqualIntA(a, 0, archive_write_header(a, entry));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_header(a, entry));
archive_entry_free(entry);
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_write_finish(a);
-#else
- assert(0 == archive_write_finish(a));
-#endif
+ /* Close out the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/*
* Verify the archive format.
diff --git a/libarchive/test/test_write_format_xar.c b/libarchive/test/test_write_format_xar.c
new file mode 100644
index 000000000000..449e49da1a9b
--- /dev/null
+++ b/libarchive/test/test_write_format_xar.c
@@ -0,0 +1,312 @@
+/*-
+ * Copyright (c) 2003-2008 Tim Kientzle
+ * Copyright (c) 2010 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+static void
+test_xar(const char *option)
+{
+ char buff2[64];
+ size_t buffsize = 1500;
+ char *buff;
+ struct archive_entry *ae;
+ struct archive *a;
+ size_t used;
+ const char *name;
+ const void *value;
+ size_t size;
+
+ /* Create a new archive in memory. */
+ assert((a = archive_write_new()) != NULL);
+ if (archive_write_set_format_xar(a) != ARCHIVE_OK) {
+ skipping("xar is not supported on this platform");
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a));
+ return;
+ }
+ assertA(0 == archive_write_set_compression_none(a));
+ if (option != NULL &&
+ archive_write_set_options(a, option) != ARCHIVE_OK) {
+ skipping("option `%s` is not supported on this platform", option);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a));
+ return;
+ }
+
+ buff = malloc(buffsize);
+ assert(buff != NULL);
+
+ assertA(0 == archive_write_open_memory(a, buff, buffsize, &used));
+
+ /*
+ * "file" has a bunch of attributes and 8 bytes of data and
+ * 7 bytes of xattr data and 3 bytes of xattr.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 20);
+ archive_entry_set_ctime(ae, 4, 40);
+ archive_entry_set_mtime(ae, 5, 50);
+ archive_entry_copy_pathname(ae, "file");
+ archive_entry_set_mode(ae, AE_IFREG | 0755);
+ archive_entry_set_nlink(ae, 2);
+ archive_entry_set_size(ae, 8);
+ archive_entry_xattr_add_entry(ae, "user.data1", "ABCDEFG", 7);
+ archive_entry_xattr_add_entry(ae, "user.data2", "XYZ", 3);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9));
+
+ /*
+ * "file2" is symbolic link to file
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 20);
+ archive_entry_set_ctime(ae, 4, 40);
+ archive_entry_set_mtime(ae, 5, 50);
+ archive_entry_copy_pathname(ae, "file2");
+ archive_entry_copy_symlink(ae, "file");
+ archive_entry_set_mode(ae, AE_IFLNK | 0755);
+ archive_entry_set_size(ae, 0);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+
+ /*
+ * "dir/file3" has a bunch of attributes and 8 bytes of data.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 20);
+ archive_entry_set_ctime(ae, 4, 40);
+ archive_entry_set_mtime(ae, 5, 50);
+ archive_entry_copy_pathname(ae, "dir/file");
+ archive_entry_set_mode(ae, AE_IFREG | 0755);
+ archive_entry_set_size(ae, 8);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ assertEqualIntA(a, 8, archive_write_data(a, "abcdefgh", 9));
+
+ /*
+ * "dir/dir2/file4" is hard link to file
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 20);
+ archive_entry_set_ctime(ae, 4, 40);
+ archive_entry_set_mtime(ae, 5, 50);
+ archive_entry_copy_pathname(ae, "dir/dir2/file4");
+ archive_entry_copy_hardlink(ae, "file");
+ archive_entry_set_mode(ae, AE_IFREG | 0755);
+ archive_entry_set_nlink(ae, 2);
+ archive_entry_set_size(ae, 0);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+
+ /*
+ * "dir/dir3" is a directory
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 20);
+ archive_entry_set_ctime(ae, 4, 40);
+ archive_entry_set_mtime(ae, 5, 50);
+ archive_entry_copy_pathname(ae, "dir/dir3");
+ archive_entry_set_mode(ae, AE_IFDIR | 0755);
+ archive_entry_unset_size(ae);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+
+ /*
+ * Add a wrong path "dir/dir2/file4/wrong"
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 20);
+ archive_entry_set_ctime(ae, 4, 40);
+ archive_entry_set_mtime(ae, 5, 50);
+ archive_entry_copy_pathname(ae, "dir/dir2/file4/wrong");
+ archive_entry_set_mode(ae, AE_IFREG | 0755);
+ archive_entry_set_nlink(ae, 1);
+ archive_entry_set_size(ae, 0);
+ assertEqualIntA(a, ARCHIVE_FAILED, archive_write_header(a, ae));
+ archive_entry_free(ae);
+
+ /*
+ * XXX TODO XXX Archive directory, other file types.
+ * Archive extended attributes, ACLs, other metadata.
+ * Verify they get read back correctly.
+ */
+
+ /* Close out the archive. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a));
+
+ /*
+ *
+ * Now, read the data back.
+ *
+ */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, 0, archive_read_support_format_all(a));
+ assertEqualIntA(a, 0, archive_read_support_filter_all(a));
+ assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used));
+
+ /*
+ * Read "file"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_atime_nsec(ae));
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(0, archive_entry_ctime_nsec(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_mtime_nsec(ae));
+ assertEqualString("file", archive_entry_pathname(ae));
+ assert((AE_IFREG | 0755) == archive_entry_mode(ae));
+ assertEqualInt(2, archive_entry_nlink(ae));
+ assertEqualInt(8, archive_entry_size(ae));
+ assertEqualInt(2, archive_entry_xattr_reset(ae));
+ assertEqualInt(ARCHIVE_OK,
+ archive_entry_xattr_next(ae, &name, &value, &size));
+ assertEqualString("user.data2", name);
+ assertEqualMem(value, "XYZ", 3);
+ assertEqualInt(ARCHIVE_OK,
+ archive_entry_xattr_next(ae, &name, &value, &size));
+ assertEqualString("user.data1", name);
+ assertEqualMem(value, "ABCDEFG", 7);
+ assertEqualIntA(a, 8, archive_read_data(a, buff2, 10));
+ assertEqualMem(buff2, "12345678", 8);
+
+ /*
+ * Read "file2"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assert(archive_entry_atime_is_set(ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_atime_nsec(ae));
+ assert(archive_entry_ctime_is_set(ae));
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(0, archive_entry_ctime_nsec(ae));
+ assert(archive_entry_mtime_is_set(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_mtime_nsec(ae));
+ assertEqualString("file2", archive_entry_pathname(ae));
+ assertEqualString("file", archive_entry_symlink(ae));
+ assert((AE_IFLNK | 0755) == archive_entry_mode(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+
+ /*
+ * Read "dir/file3"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_atime_nsec(ae));
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(0, archive_entry_ctime_nsec(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_mtime_nsec(ae));
+ assertEqualString("dir/file", archive_entry_pathname(ae));
+ assert((AE_IFREG | 0755) == archive_entry_mode(ae));
+ assertEqualInt(8, archive_entry_size(ae));
+ assertEqualIntA(a, 8, archive_read_data(a, buff2, 10));
+ assertEqualMem(buff2, "abcdefgh", 8);
+
+ /*
+ * Read "dir/dir2/file4"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assert(archive_entry_atime_is_set(ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_atime_nsec(ae));
+ assert(archive_entry_ctime_is_set(ae));
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(0, archive_entry_ctime_nsec(ae));
+ assert(archive_entry_mtime_is_set(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_mtime_nsec(ae));
+ assertEqualString("dir/dir2/file4", archive_entry_pathname(ae));
+ assertEqualString("file", archive_entry_hardlink(ae));
+ assert((AE_IFREG | 0755) == archive_entry_mode(ae));
+ assertEqualInt(2, archive_entry_nlink(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+
+ /*
+ * Read "dir/dir3"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assert(archive_entry_atime_is_set(ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_atime_nsec(ae));
+ assert(archive_entry_ctime_is_set(ae));
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(0, archive_entry_ctime_nsec(ae));
+ assert(archive_entry_mtime_is_set(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_mtime_nsec(ae));
+ assertEqualString("dir/dir3", archive_entry_pathname(ae));
+ assert((AE_IFDIR | 0755) == archive_entry_mode(ae));
+
+ /*
+ * Verify the end of the archive.
+ */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
+
+ free(buff);
+}
+
+DEFINE_TEST(test_write_format_xar)
+{
+ /* Default mode. */
+ test_xar(NULL);
+
+ /* Disable TOC checksum. */
+ test_xar("!toc-checksum");
+ /* Specify TOC checksum type to sha1. */
+ test_xar("toc-checksum=sha1");
+ /* Specify TOC checksum type to md5. */
+ test_xar("toc-checksum=md5");
+
+ /* Disable file checksum. */
+ test_xar("!checksum");
+ /* Specify file checksum type to sha1. */
+ test_xar("checksum=sha1");
+ /* Specify file checksum type to md5. */
+ test_xar("checksum=md5");
+
+ /* Disable compression. */
+ test_xar("!compression");
+ /* Specify compression type to gzip. */
+ test_xar("compression=gzip");
+ test_xar("compression=gzip,compression-level=1");
+ test_xar("compression=gzip,compression-level=9");
+ /* Specify compression type to bzip2. */
+ test_xar("compression=bzip2");
+ test_xar("compression=bzip2,compression-level=1");
+ test_xar("compression=bzip2,compression-level=9");
+ /* Specify compression type to lzma. */
+ test_xar("compression=lzma");
+ test_xar("compression=lzma,compression-level=1");
+ test_xar("compression=lzma,compression-level=9");
+ /* Specify compression type to xz. */
+ test_xar("compression=xz");
+ test_xar("compression=xz,compression-level=1");
+ test_xar("compression=xz,compression-level=9");
+}
diff --git a/libarchive/test/test_write_format_xar_empty.c b/libarchive/test/test_write_format_xar_empty.c
new file mode 100644
index 000000000000..c9e6c4a221f1
--- /dev/null
+++ b/libarchive/test/test_write_format_xar_empty.c
@@ -0,0 +1,120 @@
+/*-
+ * Copyright (c) 2010-2011 Michihiro NAKAJIMA
+ * Copyright (c) 2008 Anselm Strauss
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Development supported by Google Summer of Code 2008.
+ */
+
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+DEFINE_TEST(test_write_format_xar_empty)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+ char buff[256];
+ size_t used;
+
+ /* Xar format: Create a new archive in memory. */
+ assert((a = archive_write_new()) != NULL);
+ if (archive_write_set_format_xar(a) != ARCHIVE_OK) {
+ skipping("xar is not supported on this platform");
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a));
+ return;
+ }
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_none(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_bytes_per_block(a, 1));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_bytes_in_last_block(a, 1));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ /* Add "." entry which must be ignored. */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 0);
+ archive_entry_set_ctime(ae, 4, 0);
+ archive_entry_set_mtime(ae, 5, 0);
+ archive_entry_copy_pathname(ae, ".");
+ archive_entry_set_mode(ae, S_IFDIR | 0755);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+
+ /* Add ".." entry which must be ignored. */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 0);
+ archive_entry_set_ctime(ae, 4, 0);
+ archive_entry_set_mtime(ae, 5, 0);
+ archive_entry_copy_pathname(ae, "..");
+ archive_entry_set_mode(ae, S_IFDIR | 0755);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+
+ /* Add "/" entry which must be ignored. */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 0);
+ archive_entry_set_ctime(ae, 4, 0);
+ archive_entry_set_mtime(ae, 5, 0);
+ archive_entry_copy_pathname(ae, "/");
+ archive_entry_set_mode(ae, S_IFDIR | 0755);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+
+ /* Add "../" entry which must be ignored. */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 0);
+ archive_entry_set_ctime(ae, 4, 0);
+ archive_entry_set_mtime(ae, 5, 0);
+ archive_entry_copy_pathname(ae, "../");
+ archive_entry_set_mode(ae, S_IFDIR | 0755);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+
+ /* Add "../../." entry which must be ignored. */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 0);
+ archive_entry_set_ctime(ae, 4, 0);
+ archive_entry_set_mtime(ae, 5, 0);
+ archive_entry_copy_pathname(ae, "../../.");
+ archive_entry_set_mode(ae, S_IFDIR | 0755);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+
+ /* Add "..//.././" entry which must be ignored. */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 0);
+ archive_entry_set_ctime(ae, 4, 0);
+ archive_entry_set_mtime(ae, 5, 0);
+ archive_entry_copy_pathname(ae, "..//.././");
+ archive_entry_set_mode(ae, S_IFDIR | 0755);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+
+ /* Close out the archive without writing anything. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* Verify the correct format for an empy Xar archive. */
+ assertEqualInt(used, 0);
+}
diff --git a/libarchive/test/test_write_format_zip.c b/libarchive/test/test_write_format_zip.c
index 250ddba91317..d62bce8da7f1 100644
--- a/libarchive/test/test_write_format_zip.c
+++ b/libarchive/test/test_write_format_zip.c
@@ -28,15 +28,96 @@
* Development supported by Google Summer of Code 2008.
*/
-/* TODO: reader does not yet restore permissions. */
-
#include "test.h"
__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_format_zip.c 201247 2009-12-30 05:59:21Z kientzle $");
-DEFINE_TEST(test_write_format_zip)
+static void
+verify_contents(struct archive *a, int expect_details)
{
char filedata[64];
struct archive_entry *ae;
+
+ /*
+ * Read and verify first file.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(1, archive_entry_mtime(ae));
+ /* Zip doesn't store high-resolution mtime. */
+ assertEqualInt(0, archive_entry_mtime_nsec(ae));
+ assertEqualInt(0, archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_ctime(ae));
+ assertEqualString("file", archive_entry_pathname(ae));
+ if (expect_details) {
+ assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae));
+ assertEqualInt(8, archive_entry_size(ae));
+ } else {
+ assertEqualInt(0, archive_entry_size(ae));
+ }
+ assertEqualIntA(a, 8,
+ archive_read_data(a, filedata, sizeof(filedata)));
+ assertEqualMem(filedata, "12345678", 8);
+
+
+ /*
+ * Read the second file back.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(1, archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_mtime_nsec(ae));
+ assertEqualInt(0, archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_ctime(ae));
+ assertEqualString("file2", archive_entry_pathname(ae));
+ if (expect_details) {
+ assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae));
+ assertEqualInt(4, archive_entry_size(ae));
+ } else {
+ assertEqualInt(0, archive_entry_size(ae));
+ }
+ assertEqualIntA(a, 4,
+ archive_read_data(a, filedata, sizeof(filedata)));
+ assertEqualMem(filedata, "1234", 4);
+
+ /*
+ * Read the third file back.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(1, archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_mtime_nsec(ae));
+ assertEqualInt(0, archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_ctime(ae));
+ assertEqualString("symlink", archive_entry_pathname(ae));
+ if (expect_details) {
+ assertEqualInt(AE_IFLNK | 0755, archive_entry_mode(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualString("file1", archive_entry_symlink(ae));
+ } else {
+ assertEqualInt(AE_IFREG | 0777, archive_entry_mode(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ }
+
+ /*
+ * Read the dir entry back.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(11, archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_mtime_nsec(ae));
+ assertEqualInt(0, archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_ctime(ae));
+ assertEqualString("dir/", archive_entry_pathname(ae));
+ if (expect_details)
+ assertEqualInt(AE_IFDIR | 0755, archive_entry_mode(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualIntA(a, 0, archive_read_data(a, filedata, 10));
+
+ /* Verify the end of the archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+DEFINE_TEST(test_write_format_zip)
+{
+ struct archive_entry *ae;
struct archive *a;
size_t used;
size_t buffsize = 1000000;
@@ -49,12 +130,12 @@ DEFINE_TEST(test_write_format_zip)
assert((a = archive_write_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_zip(a));
#ifdef HAVE_ZLIB_H
- compression_type = "zip:compression=deflate";
+ compression_type = "deflate";
#else
- compression_type = "zip:compression=store";
+ compression_type = "store";
#endif
assertEqualIntA(a, ARCHIVE_OK,
- archive_write_set_format_options(a, compression_type));
+ archive_write_set_format_option(a, "zip", "compression", compression_type));
assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_none(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_write_open_memory(a, buff, buffsize, &used));
@@ -68,7 +149,7 @@ DEFINE_TEST(test_write_format_zip)
assertEqualInt(10, archive_entry_mtime_nsec(ae));
archive_entry_copy_pathname(ae, "file");
assertEqualString("file", archive_entry_pathname(ae));
- archive_entry_set_mode(ae, S_IFREG | 0755);
+ archive_entry_set_mode(ae, AE_IFREG | 0755);
assertEqualInt((S_IFREG | 0755), archive_entry_mode(ae));
archive_entry_set_size(ae, 8);
@@ -86,7 +167,7 @@ DEFINE_TEST(test_write_format_zip)
assertEqualInt(10, archive_entry_mtime_nsec(ae));
archive_entry_copy_pathname(ae, "file2");
assertEqualString("file2", archive_entry_pathname(ae));
- archive_entry_set_mode(ae, S_IFREG | 0755);
+ archive_entry_set_mode(ae, AE_IFREG | 0755);
assertEqualInt((S_IFREG | 0755), archive_entry_mode(ae));
archive_entry_set_size(ae, 4);
@@ -95,6 +176,24 @@ DEFINE_TEST(test_write_format_zip)
assertEqualInt(4, archive_write_data(a, "1234", 5));
/*
+ * Write symbolic like file to it.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_mtime(ae, 1, 10);
+ assertEqualInt(1, archive_entry_mtime(ae));
+ assertEqualInt(10, archive_entry_mtime_nsec(ae));
+ archive_entry_copy_pathname(ae, "symlink");
+ assertEqualString("symlink", archive_entry_pathname(ae));
+ archive_entry_copy_symlink(ae, "file1");
+ assertEqualString("file1", archive_entry_symlink(ae));
+ archive_entry_set_mode(ae, AE_IFLNK | 0755);
+ assertEqualInt((AE_IFLNK | 0755), archive_entry_mode(ae));
+ archive_entry_set_size(ae, 4);
+
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+
+ /*
* Write a directory to it.
*/
assert((ae = archive_entry_new()) != NULL);
@@ -111,70 +210,32 @@ DEFINE_TEST(test_write_format_zip)
/* Close out the archive. */
assertEqualInt(ARCHIVE_OK, archive_write_close(a));
- assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/*
* Now, read the data back.
*/
- ae = NULL;
+ /* With the standard memory reader. */
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
- assertEqualIntA(a, ARCHIVE_OK,
- archive_read_support_compression_all(a));
- assertEqualIntA(a, ARCHIVE_OK,
- archive_read_open_memory(a, buff, used));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used));
+ verify_contents(a, 1);
- /*
- * Read and verify first file.
- */
- assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
- assertEqualInt(1, archive_entry_mtime(ae));
- /* Zip doesn't store high-resolution mtime. */
- assertEqualInt(0, archive_entry_mtime_nsec(ae));
- assertEqualInt(0, archive_entry_atime(ae));
- assertEqualInt(0, archive_entry_ctime(ae));
- assertEqualString("file", archive_entry_pathname(ae));
- //assertEqualInt((S_IFREG | 0755), archive_entry_mode(ae));
- assertEqualInt(0, archive_entry_size(ae));
- assertEqualIntA(a, 8,
- archive_read_data(a, filedata, sizeof(filedata)));
- assertEqualMem(filedata, "12345678", 8);
-
-
- /*
- * Read the second file back.
- */
- if (!assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae))){
- free(buff);
- return;
- }
- assertEqualInt(1, archive_entry_mtime(ae));
- assertEqualInt(0, archive_entry_mtime_nsec(ae));
- assertEqualInt(0, archive_entry_atime(ae));
- assertEqualInt(0, archive_entry_ctime(ae));
- assertEqualString("file2", archive_entry_pathname(ae));
- //assert((S_IFREG | 0755) == archive_entry_mode(ae));
- assertEqualInt(0, archive_entry_size(ae));
- assertEqualIntA(a, 4,
- archive_read_data(a, filedata, sizeof(filedata)));
- assertEqualMem(filedata, "1234", 4);
+ /* With the test memory reader -- streaming mode. */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, buff, used, 7));
+ /* Streaming reader doesn't see mode information from Central Directory. */
+ verify_contents(a, 0);
- /*
- * Read the dir entry back.
- */
- assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
- assertEqualInt(11, archive_entry_mtime(ae));
- assertEqualInt(0, archive_entry_mtime_nsec(ae));
- assertEqualInt(0, archive_entry_atime(ae));
- assertEqualInt(0, archive_entry_ctime(ae));
- assertEqualString("dir/", archive_entry_pathname(ae));
- //assertEqualInt((S_IFDIR | 0755), archive_entry_mode(ae));
- assertEqualInt(0, archive_entry_size(ae));
- assertEqualIntA(a, 0, archive_read_data(a, filedata, 10));
+ /* With the test memory reader -- seeking mode. */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, used, 7));
+ verify_contents(a, 1);
- /* Verify the end of the archive. */
- assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
- assertEqualInt(ARCHIVE_OK, archive_read_close(a));
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
free(buff);
}
diff --git a/libarchive/test/test_write_format_zip_empty.c b/libarchive/test/test_write_format_zip_empty.c
index 459664e23479..156726080520 100644
--- a/libarchive/test/test_write_format_zip_empty.c
+++ b/libarchive/test/test_write_format_zip_empty.c
@@ -33,24 +33,46 @@ __FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_format_zip_empty.c 20124
DEFINE_TEST(test_write_format_zip_empty)
{
struct archive *a;
+ struct archive_entry *ae;
char buff[256];
size_t used;
/* Zip format: Create a new archive in memory. */
assert((a = archive_write_new()) != NULL);
- assertA(0 == archive_write_set_format_zip(a));
- assertA(0 == archive_write_set_compression_none(a));
- assertA(0 == archive_write_set_bytes_per_block(a, 1));
- assertA(0 == archive_write_set_bytes_in_last_block(a, 1));
- assertA(0 == archive_write_open_memory(a, buff, sizeof(buff), &used));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_zip(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_none(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_bytes_per_block(a, 1));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_bytes_in_last_block(a, 1));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff), &used));
/* Close out the archive without writing anything. */
- assertA(0 == archive_write_close(a));
- assertA(0 == archive_write_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/* Verify the correct format for an empy Zip archive. */
assertEqualInt(used, 22);
assertEqualMem(buff,
"PK\005\006\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",
22);
+
+ /* Verify that we read this kind of empty archive correctly. */
+ /* Try with the standard memory reader, and with the test
+ memory reader with and without seek support. */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, 22));
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
+ assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, buff, 22, 1));
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
+ assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, 22, 22));
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
}
diff --git a/libarchive/test/test_write_format_zip_no_compression.c b/libarchive/test/test_write_format_zip_no_compression.c
index 4a61a76eb6af..9c570c942489 100644
--- a/libarchive/test/test_write_format_zip_no_compression.c
+++ b/libarchive/test/test_write_format_zip_no_compression.c
@@ -98,7 +98,7 @@ DEFINE_TEST(test_write_format_zip_no_compression)
/* Create new ZIP archive in memory without padding. */
assert((a = archive_write_new()) != NULL);
assertA(0 == archive_write_set_format_zip(a));
- assertA(0 == archive_write_set_format_options(a, "zip:compression=store"));
+ assertA(0 == archive_write_set_options(a, "zip:compression=store"));
assertA(0 == archive_write_set_compression_none(a));
assertA(0 == archive_write_set_bytes_per_block(a, 1));
assertA(0 == archive_write_set_bytes_in_last_block(a, 1));
@@ -135,8 +135,8 @@ DEFINE_TEST(test_write_format_zip_no_compression)
archive_entry_free(entry);
/* Close the archive . */
- assertA(0 == archive_write_close(a));
- assertA(0 == archive_write_finish(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
/* Remember the end of the archive in memory. */
buffend = buff + used;
@@ -191,8 +191,8 @@ DEFINE_TEST(test_write_format_zip_no_compression)
assertEqualInt(p[4], 7); /* 'UT' flags */
assertEqualInt(i4(p + 5), t); /* 'UT' mtime */
p = p + 9;
- assertEqualInt(i2(p), 0x7855); /* 'Ux' extension header */
- assertEqualInt(i2(p + 2), 0); /* 'Ux' size */
+ assertEqualInt(i2(p), 0x7875); /* 'ux' extension header */
+ assertEqualInt(i2(p + 2), 0); /* 'ux' size */
p = p + 4;
/* Verify local header of file entry. */
@@ -207,7 +207,7 @@ DEFINE_TEST(test_write_format_zip_no_compression)
assertEqualInt(i4(q + 18), sizeof(file_data1) + sizeof(file_data2)); /* Compressed size */
assertEqualInt(i4(q + 22), sizeof(file_data1) + sizeof(file_data2)); /* Uncompressed size */
assertEqualInt(i2(q + 26), strlen(file_name)); /* Pathname length */
- assertEqualInt(i2(q + 28), 25); /* Extra field length */
+ assertEqualInt(i2(q + 28), 32); /* Extra field length */
assertEqualMem(q + 30, file_name, strlen(file_name)); /* Pathname */
q = q + 30 + strlen(file_name);
assertEqualInt(i2(q), 0x5455); /* 'UT' extension header */
@@ -217,11 +217,14 @@ DEFINE_TEST(test_write_format_zip_no_compression)
assertEqualInt(i4(q + 9), t); /* 'UT' atime */
assertEqualInt(i4(q + 13), t); /* 'UT' ctime */
q = q + 17;
- assertEqualInt(i2(q), 0x7855); /* 'Ux' extension header */
- assertEqualInt(i2(q + 2), 4); /* 'Ux' size */
- assertEqualInt(i2(q + 4), file_uid); /* 'Ux' UID */
- assertEqualInt(i2(q + 6), file_gid); /* 'Ux' GID */
- q = q + 8;
+ assertEqualInt(i2(q), 0x7875); /* 'ux' extension header */
+ assertEqualInt(i2(q + 2), 11); /* 'ux' size */
+ assertEqualInt(q[4], 1); /* 'ux' version */
+ assertEqualInt(q[5], 4); /* 'ux' uid size */
+ assertEqualInt(i4(q + 6), file_uid); /* 'Ux' UID */
+ assertEqualInt(q[10], 4); /* 'ux' gid size */
+ assertEqualInt(i4(q + 11), file_gid); /* 'Ux' GID */
+ q = q + 15;
/* Verify data of file entry. */
assertEqualMem(q, file_data1, sizeof(file_data1));
@@ -261,9 +264,9 @@ DEFINE_TEST(test_write_format_zip_no_compression)
assertEqualInt(p[4], 7); /* 'UT' flags */
assertEqualInt(i4(p + 5), t); /* 'UT' mtime */
p = p + 9;
- assertEqualInt(i2(p), 0x7855); /* 'Ux' extension header */
- assertEqualInt(i2(p + 2), 0); /* 'Ux' size */
- p = p + 4;
+ assertEqualInt(i2(p), 0x7875); /* 'ux' extension header */
+ assertEqualInt(i2(p + 2), 0); /* 'ux' size */
+ /*p = p + 4;*/
/* Verify local header of folder entry. */
assertEqualMem(q, "PK\003\004", 4); /* Signature */
@@ -276,7 +279,7 @@ DEFINE_TEST(test_write_format_zip_no_compression)
assertEqualInt(i4(q + 18), 0); /* Compressed size */
assertEqualInt(i4(q + 22), 0); /* Uncompressed size */
assertEqualInt(i2(q + 26), strlen(folder_name)); /* Pathname length */
- assertEqualInt(i2(q + 28), 25); /* Extra field length */
+ assertEqualInt(i2(q + 28), 32); /* Extra field length */
assertEqualMem(q + 30, folder_name, strlen(folder_name)); /* Pathname */
q = q + 30 + strlen(folder_name);
assertEqualInt(i2(q), 0x5455); /* 'UT' extension header */
@@ -286,11 +289,14 @@ DEFINE_TEST(test_write_format_zip_no_compression)
assertEqualInt(i4(q + 9), t); /* 'UT' atime */
assertEqualInt(i4(q + 13), t); /* 'UT' ctime */
q = q + 17;
- assertEqualInt(i2(q), 0x7855); /* 'Ux' extension header */
- assertEqualInt(i2(q + 2), 4); /* 'Ux' size */
- assertEqualInt(i2(q + 4), folder_uid); /* 'Ux' UID */
- assertEqualInt(i2(q + 6), folder_gid); /* 'Ux' GID */
- q = q + 8;
+ assertEqualInt(i2(q), 0x7875); /* 'ux' extension header */
+ assertEqualInt(i2(q + 2), 11); /* 'ux' size */
+ assertEqualInt(q[4], 1); /* 'ux' version */
+ assertEqualInt(q[5], 4); /* 'ux' uid size */
+ assertEqualInt(i4(q + 6), folder_uid); /* 'ux' UID */
+ assertEqualInt(q[10], 4); /* 'ux' gid size */
+ assertEqualInt(i4(q + 11), folder_gid); /* 'ux' GID */
+ q = q + 15;
/* There should not be any data in the folder entry,
* meaning next is the data descriptor header. */
@@ -300,5 +306,5 @@ DEFINE_TEST(test_write_format_zip_no_compression)
assertEqualInt(i4(q + 4), crc); /* CRC-32 */
assertEqualInt(i4(q + 8), 0); /* Compressed size */
assertEqualInt(i4(q + 12), 0); /* Uncompressed size */
- q = q + 16;
+ /*q = q + 16;*/
}
diff --git a/libarchive/test/test_write_open_memory.c b/libarchive/test/test_write_open_memory.c
index 696db6c963ad..e9a01de08829 100644
--- a/libarchive/test/test_write_open_memory.c
+++ b/libarchive/test/test_write_open_memory.c
@@ -45,32 +45,40 @@ DEFINE_TEST(test_write_open_memory)
/* Make sure that we get failure on too-small buffers, success on
* large enough ones. */
for (i = 100; i < 1600; i++) {
- size_t s;
+ size_t used;
size_t blocksize = 94;
assert((a = archive_write_new()) != NULL);
- assertA(0 == archive_write_set_format_ustar(a));
- assertA(0 == archive_write_set_bytes_in_last_block(a, 1));
- assertA(0 == archive_write_set_bytes_per_block(a, (int)blocksize));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_format_ustar(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_bytes_in_last_block(a, 1));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_bytes_per_block(a, (int)blocksize));
buff[i] = 0xAE;
- assertA(0 == archive_write_open_memory(a, buff, i, &s));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_open_memory(a, buff, i, &used));
/* If buffer is smaller than a tar header, this should fail. */
if (i < (511/blocksize)*blocksize)
- assertA(ARCHIVE_FATAL == archive_write_header(a,ae));
+ assertEqualIntA(a, ARCHIVE_FATAL,
+ archive_write_header(a,ae));
else
- assertA(0 == archive_write_header(a, ae));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_header(a, ae));
/* If buffer is smaller than a tar header plus 1024 byte
* end-of-archive marker, then this should fail. */
+ failure("buffer size=%d\n", (int)i);
if (i < 1536)
- assertA(ARCHIVE_FATAL == archive_write_close(a));
- else
- assertA(0 == archive_write_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_write_finish(a);
-#else
- assert(0 == archive_write_finish(a));
-#endif
- assert(buff[i] == 0xAE);
- assert(s <= i);
+ assertEqualIntA(a, ARCHIVE_FATAL,
+ archive_write_close(a));
+ else {
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(used, archive_position_compressed(a));
+ assertEqualInt(archive_position_compressed(a),
+ archive_position_uncompressed(a));
+ }
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+ assertEqualInt(buff[i], 0xAE);
+ assert(used <= i);
}
archive_entry_free(ae);
}
diff --git a/libarchive/test/test_zip_filename_encoding.c b/libarchive/test/test_zip_filename_encoding.c
new file mode 100644
index 000000000000..7ee17196f59d
--- /dev/null
+++ b/libarchive/test/test_zip_filename_encoding.c
@@ -0,0 +1,543 @@
+/*-
+ * Copyright (c) 2011 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+#include <locale.h>
+
+static void
+test_zip_filename_encoding_UTF8(void)
+{
+ struct archive *a;
+ struct archive_entry *entry;
+ char buff[4096];
+ size_t used;
+
+ if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
+ skipping("en_US.UTF-8 locale not available on this system.");
+ return;
+ }
+
+ /*
+ * Verify that UTF-8 filenames are correctly stored with
+ * hdrcharset=UTF-8 option.
+ */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a));
+ if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) {
+ skipping("This system cannot convert character-set"
+ " for UTF-8.");
+ archive_write_free(a);
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set a UTF-8 filename. */
+ archive_entry_set_pathname(entry, "\xD0\xBF\xD1\x80\xD0\xB8");
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* A bit 11 of general purpose flag should be 0x08,
+ * which indicates the filename charset is UTF-8. */
+ assertEqualInt(0x08, buff[7]);
+ assertEqualMem(buff + 30, "\xD0\xBF\xD1\x80\xD0\xB8", 6);
+
+ /*
+ * Verify that UTF-8 filenames are correctly stored without
+ * hdrcharset=UTF-8 option.
+ */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a));
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set a UTF-8 filename. */
+ archive_entry_set_pathname(entry, "\xD0\xBF\xD1\x80\xD0\xB8");
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* A bit 11 of general purpose flag should be 0x08,
+ * which indicates the filename charset is UTF-8. */
+ assertEqualInt(0x08, buff[7]);
+ assertEqualMem(buff + 30, "\xD0\xBF\xD1\x80\xD0\xB8", 6);
+
+ /*
+ * Verify that A bit 11 of general purpose flag is not set
+ * when ASCII filenames are stored.
+ */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a));
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set an ASCII filename. */
+ archive_entry_set_pathname(entry, "abcABC");
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* A bit 11 of general purpose flag should be 0,
+ * which indicates the filename charset is unknown. */
+ assertEqualInt(0, buff[7]);
+ assertEqualMem(buff + 30, "abcABC", 6);
+}
+
+static void
+test_zip_filename_encoding_KOI8R(void)
+{
+ struct archive *a;
+ struct archive_entry *entry;
+ char buff[4096];
+ size_t used;
+
+ if (NULL == setlocale(LC_ALL, "ru_RU.KOI8-R")) {
+ skipping("KOI8-R locale not available on this system.");
+ return;
+ }
+
+ /*
+ * Verify that KOI8-R filenames are correctly translated to UTF-8.
+ */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a));
+ if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) {
+ skipping("This system cannot convert character-set"
+ " from KOI8-R to UTF-8.");
+ archive_write_free(a);
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set a KOI8-R filename. */
+ archive_entry_set_pathname(entry, "\xD0\xD2\xC9");
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* A bit 11 of general purpose flag should be 0x08,
+ * which indicates the filename charset is UTF-8. */
+ assertEqualInt(0x08, buff[7]);
+ /* Above three characters in KOI8-R should translate to the following
+ * three characters (two bytes each) in UTF-8. */
+ assertEqualMem(buff + 30, "\xD0\xBF\xD1\x80\xD0\xB8", 6);
+
+ /*
+ * Verify that KOI8-R filenames are not translated to UTF-8.
+ */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a));
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set a KOI8-R filename. */
+ archive_entry_set_pathname(entry, "\xD0\xD2\xC9");
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* A bit 11 of general purpose flag should be 0,
+ * which indicates the filename charset is unknown. */
+ assertEqualInt(0, buff[7]);
+ /* Above three characters in KOI8-R should not translate to
+ * any character-set. */
+ assertEqualMem(buff + 30, "\xD0\xD2\xC9", 3);
+
+ /*
+ * Verify that A bit 11 of general purpose flag is not set
+ * when ASCII filenames are stored even if hdrcharset=UTF-8
+ * is specified.
+ */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a));
+ if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) {
+ skipping("This system cannot convert character-set"
+ " from KOI8-R to UTF-8.");
+ archive_write_free(a);
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set an ASCII filename. */
+ archive_entry_set_pathname(entry, "abcABC");
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* A bit 11 of general purpose flag should be 0,
+ * which indicates the filename charset is unknown. */
+ assertEqualInt(0, buff[7]);
+ assertEqualMem(buff + 30, "abcABC", 6);
+}
+
+/*
+ * Do not translate CP1251 into CP866 if non Windows platform.
+ */
+static void
+test_zip_filename_encoding_ru_RU_CP1251(void)
+{
+ struct archive *a;
+ struct archive_entry *entry;
+ char buff[4096];
+ size_t used;
+
+ if (NULL == setlocale(LC_ALL, "ru_RU.CP1251")) {
+ skipping("Russian_Russia locale not available on this system.");
+ return;
+ }
+
+ /*
+ * Verify that CP1251 filenames are not translated into any
+ * other character-set, in particular, CP866.
+ */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a));
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set a CP1251 filename. */
+ archive_entry_set_pathname(entry, "\xEF\xF0\xE8");
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* A bit 11 of general purpose flag should be 0,
+ * which indicates the filename charset is unknown. */
+ assertEqualInt(0, buff[7]);
+ /* Above three characters in CP1251 should not translate into
+ * any other character-set. */
+ assertEqualMem(buff + 30, "\xEF\xF0\xE8", 3);
+}
+
+/*
+ * Other archiver applications on Windows translate CP1251 filenames
+ * into CP866 filenames and store it in the zip file.
+ * Test above behavior works well.
+ */
+static void
+test_zip_filename_encoding_Russian_Russia(void)
+{
+ struct archive *a;
+ struct archive_entry *entry;
+ char buff[4096];
+ size_t used;
+
+ if (NULL == setlocale(LC_ALL, "Russian_Russia")) {
+ skipping("Russian_Russia locale not available on this system.");
+ return;
+ }
+
+ /*
+ * Verify that Russian_Russia(CP1251) filenames are correctly translated
+ * to UTF-8.
+ */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a));
+ if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) {
+ skipping("This system cannot convert character-set"
+ " from Russian_Russia.CP1251 to UTF-8.");
+ archive_write_free(a);
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set a CP1251 filename. */
+ archive_entry_set_pathname(entry, "\xEF\xF0\xE8");
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* A bit 11 of general purpose flag should be 0x08,
+ * which indicates the filename charset is UTF-8. */
+ assertEqualInt(0x08, buff[7]);
+ /* Above three characters in CP1251 should translate to the following
+ * three characters (two bytes each) in UTF-8. */
+ assertEqualMem(buff + 30, "\xD0\xBF\xD1\x80\xD0\xB8", 6);
+
+ /*
+ * Verify that Russian_Russia(CP1251) filenames are correctly translated
+ * to CP866.
+ */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a));
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set a CP1251 filename. */
+ archive_entry_set_pathname(entry, "\xEF\xF0\xE8");
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* A bit 11 of general purpose flag should be 0,
+ * which indicates the filename charset is unknown. */
+ assertEqualInt(0, buff[7]);
+ /* Above three characters in CP1251 should translate to the following
+ * three characters in CP866. */
+ assertEqualMem(buff + 30, "\xAF\xE0\xA8", 3);
+}
+
+static void
+test_zip_filename_encoding_EUCJP(void)
+{
+ struct archive *a;
+ struct archive_entry *entry;
+ char buff[4096];
+ size_t used;
+
+ if (NULL == setlocale(LC_ALL, "ja_JP.eucJP")) {
+ skipping("eucJP locale not available on this system.");
+ return;
+ }
+
+ /*
+ * Verify that EUC-JP filenames are correctly translated to UTF-8.
+ */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a));
+ if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) {
+ skipping("This system cannot convert character-set"
+ " from eucJP to UTF-8.");
+ archive_write_free(a);
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set an EUC-JP filename. */
+ archive_entry_set_pathname(entry, "\xC9\xBD.txt");
+ /* Check the Unicode version. */
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* A bit 11 of general purpose flag should be 0x08,
+ * which indicates the filename charset is UTF-8. */
+ assertEqualInt(0x08, buff[7]);
+ /* Check UTF-8 version. */
+ assertEqualMem(buff + 30, "\xE8\xA1\xA8.txt", 7);
+
+ /*
+ * Verify that EUC-JP filenames are not translated to UTF-8.
+ */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a));
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set an EUC-JP filename. */
+ archive_entry_set_pathname(entry, "\xC9\xBD.txt");
+ /* Check the Unicode version. */
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* A bit 11 of general purpose flag should be 0,
+ * which indicates the filename charset is unknown. */
+ assertEqualInt(0, buff[7]);
+ /* Above three characters in EUC-JP should not translate to
+ * any character-set. */
+ assertEqualMem(buff + 30, "\xC9\xBD.txt", 6);
+
+ /*
+ * Verify that A bit 11 of general purpose flag is not set
+ * when ASCII filenames are stored even if hdrcharset=UTF-8
+ * is specified.
+ */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a));
+ if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) {
+ skipping("This system cannot convert character-set"
+ " from eucJP to UTF-8.");
+ archive_write_free(a);
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set an ASCII filename. */
+ archive_entry_set_pathname(entry, "abcABC");
+ /* Check the Unicode version. */
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* A bit 11 of general purpose flag should be 0,
+ * which indicates the filename charset is unknown. */
+ assertEqualInt(0, buff[7]);
+ assertEqualMem(buff + 30, "abcABC", 6);
+}
+
+static void
+test_zip_filename_encoding_CP932(void)
+{
+ struct archive *a;
+ struct archive_entry *entry;
+ char buff[4096];
+ size_t used;
+
+ if (NULL == setlocale(LC_ALL, "Japanese_Japan") &&
+ NULL == setlocale(LC_ALL, "ja_JP.SJIS")) {
+ skipping("CP932/SJIS locale not available on this system.");
+ return;
+ }
+
+ /*
+ * Verify that EUC-JP filenames are correctly translated to UTF-8.
+ */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a));
+ if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) {
+ skipping("This system cannot convert character-set"
+ " from CP932/SJIS to UTF-8.");
+ archive_write_free(a);
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set a CP932/SJIS filename. */
+ archive_entry_set_pathname(entry, "\x95\x5C.txt");
+ /* Check the Unicode version. */
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* A bit 11 of general purpose flag should be 0x08,
+ * which indicates the filename charset is UTF-8. */
+ assertEqualInt(0x08, buff[7]);
+ /* Check UTF-8 version. */
+ assertEqualMem(buff + 30, "\xE8\xA1\xA8.txt", 7);
+
+ /*
+ * Verify that CP932/SJIS filenames are not translated to UTF-8.
+ */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a));
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set a CP932/SJIS filename. */
+ archive_entry_set_pathname(entry, "\x95\x5C.txt");
+ /* Check the Unicode version. */
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* A bit 11 of general purpose flag should be 0,
+ * which indicates the filename charset is unknown. */
+ assertEqualInt(0, buff[7]);
+ /* Above three characters in CP932/SJIS should not translate to
+ * any character-set. */
+ assertEqualMem(buff + 30, "\x95\x5C.txt", 6);
+
+ /*
+ * Verify that A bit 11 of general purpose flag is not set
+ * when ASCII filenames are stored even if hdrcharset=UTF-8
+ * is specified.
+ */
+ a = archive_write_new();
+ assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a));
+ if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) {
+ skipping("This system cannot convert character-set"
+ " from CP932/SJIS to UTF-8.");
+ archive_write_free(a);
+ return;
+ }
+ assertEqualInt(ARCHIVE_OK,
+ archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ entry = archive_entry_new2(a);
+ /* Set an ASCII filename. */
+ archive_entry_set_pathname(entry, "abcABC");
+ /* Check the Unicode version. */
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
+ archive_entry_free(entry);
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+ /* A bit 11 of general purpose flag should be 0,
+ * which indicates the filename charset is unknown. */
+ assertEqualInt(0, buff[7]);
+ assertEqualMem(buff + 30, "abcABC", 6);
+}
+
+DEFINE_TEST(test_zip_filename_encoding)
+{
+ test_zip_filename_encoding_UTF8();
+ test_zip_filename_encoding_KOI8R();
+ test_zip_filename_encoding_ru_RU_CP1251();
+ test_zip_filename_encoding_Russian_Russia();
+ test_zip_filename_encoding_EUCJP();
+ test_zip_filename_encoding_CP932();
+}
diff --git a/libarchive_fe/line_reader.c b/libarchive_fe/line_reader.c
index 4af60de4c07e..2d197d3dfb03 100644
--- a/libarchive_fe/line_reader.c
+++ b/libarchive_fe/line_reader.c
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2008 Tim Kientzle
+ * Copyright (c) 2010 Joerg Sonnenberger
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -74,14 +75,20 @@ lafe_line_reader(const char *pathname, int nullSeparator)
if (lr->f == NULL)
lafe_errc(1, errno, "Couldn't open %s", pathname);
lr->buff_length = 8192;
- lr->buff = malloc(lr->buff_length);
- if (lr->buff == NULL)
- lafe_errc(1, ENOMEM, "Can't read %s", pathname);
- lr->line_start = lr->line_end = lr->buff_end = lr->buff;
+ lr->line_start = lr->line_end = lr->buff_end = lr->buff = NULL;
return (lr);
}
+static void
+lafe_line_reader_find_eol(struct lafe_line_reader *lr)
+{
+
+ lr->line_end += strcspn(lr->line_end,
+ lr->nullSeparator ? "" : "\x0d\x0a");
+ *lr->line_end = '\0'; /* Noop if line_end == buff_end */
+}
+
const char *
lafe_line_reader_next(struct lafe_line_reader *lr)
{
@@ -91,36 +98,21 @@ lafe_line_reader_next(struct lafe_line_reader *lr)
for (;;) {
/* If there's a line in the buffer, return it immediately. */
while (lr->line_end < lr->buff_end) {
- if (lr->nullSeparator) {
- if (*lr->line_end == '\0') {
- line_start = lr->line_start;
- lr->line_start = lr->line_end + 1;
- lr->line_end = lr->line_start;
- return (line_start);
- }
- } else if (*lr->line_end == '\x0a' || *lr->line_end == '\x0d') {
- *lr->line_end = '\0';
- line_start = lr->line_start;
- lr->line_start = lr->line_end + 1;
- lr->line_end = lr->line_start;
- if (line_start[0] != '\0')
- return (line_start);
- }
- lr->line_end++;
+ line_start = lr->line_start;
+ lr->line_start = ++lr->line_end;
+ lafe_line_reader_find_eol(lr);
+
+ if (lr->nullSeparator || line_start[0] != '\0')
+ return (line_start);
}
/* If we're at end-of-file, process the final data. */
if (lr->f == NULL) {
- /* If there's more text, return one last line. */
- if (lr->line_end > lr->line_start) {
- *lr->line_end = '\0';
- line_start = lr->line_start;
- lr->line_start = lr->line_end + 1;
- lr->line_end = lr->line_start;
- return (line_start);
- }
- /* Otherwise, we're done. */
- return (NULL);
+ if (lr->line_start == lr->buff_end)
+ return (NULL); /* No more text */
+ line_start = lr->line_start;
+ lr->line_start = lr->buff_end;
+ return (line_start);
}
/* Buffer only has part of a line. */
@@ -138,7 +130,11 @@ lafe_line_reader_next(struct lafe_line_reader *lr)
lafe_errc(1, ENOMEM,
"Line too long in %s", lr->pathname);
lr->buff_length = new_buff_size;
- p = realloc(lr->buff, new_buff_size);
+ /*
+ * Allocate one extra byte to allow terminating
+ * the buffer.
+ */
+ p = realloc(lr->buff, new_buff_size + 1);
if (p == NULL)
lafe_errc(1, ENOMEM,
"Line too long in %s", lr->pathname);
@@ -151,6 +147,8 @@ lafe_line_reader_next(struct lafe_line_reader *lr)
bytes_wanted = lr->buff + lr->buff_length - lr->buff_end;
bytes_read = fread(lr->buff_end, 1, bytes_wanted, lr->f);
lr->buff_end += bytes_read;
+ *lr->buff_end = '\0'; /* Always terminate buffer */
+ lafe_line_reader_find_eol(lr);
if (ferror(lr->f))
lafe_errc(1, errno, "Can't read %s", lr->pathname);
diff --git a/libarchive_fe/matching.c b/libarchive_fe/matching.c
index f774ac773ca9..4ba608222f3f 100644
--- a/libarchive_fe/matching.c
+++ b/libarchive_fe/matching.c
@@ -140,7 +140,7 @@ add_pattern(struct match **list, const char *pattern)
strcpy(match->pattern, pattern);
/* Both "foo/" and "foo" should match "foo/bar". */
if (len && match->pattern[len - 1] == '/')
- match->pattern[strlen(match->pattern)-1] = '\0';
+ match->pattern[len - 1] = '\0';
match->next = *list;
*list = match;
match->matches = 0;
@@ -156,40 +156,41 @@ lafe_excluded(struct lafe_matching *matching, const char *pathname)
if (matching == NULL)
return (0);
+ /* Mark off any unmatched inclusions. */
+ /* In particular, if a filename does appear in the archive and
+ * is explicitly included and excluded, then we don't report
+ * it as missing even though we don't extract it.
+ */
+ matched = NULL;
+ for (match = matching->inclusions; match != NULL; match = match->next){
+ if (match->matches == 0
+ && match_inclusion(match, pathname)) {
+ matching->inclusions_unmatched_count--;
+ match->matches++;
+ matched = match;
+ }
+ }
+
/* Exclusions take priority */
for (match = matching->exclusions; match != NULL; match = match->next){
if (match_exclusion(match, pathname))
return (1);
}
- /* Then check for inclusions */
- matched = NULL;
+ /* It's not excluded and we found an inclusion above, so it's included. */
+ if (matched != NULL)
+ return (0);
+
+
+ /* We didn't find an unmatched inclusion, check the remaining ones. */
for (match = matching->inclusions; match != NULL; match = match->next){
- if (match_inclusion(match, pathname)) {
- /*
- * If this pattern has never been matched,
- * then we're done.
- */
- if (match->matches == 0) {
- match->matches++;
- matching->inclusions_unmatched_count--;
- return (0);
- }
- /*
- * Otherwise, remember the match but keep checking
- * in case we can tick off an unmatched pattern.
- */
- matched = match;
+ /* We looked at previously-unmatched inclusions already. */
+ if (match->matches > 0
+ && match_inclusion(match, pathname)) {
+ match->matches++;
+ return (0);
}
}
- /*
- * We didn't find a pattern that had never been matched, but
- * we did find a match, so count it and exit.
- */
- if (matched != NULL) {
- matched->matches++;
- return (0);
- }
/* If there were inclusions, default is to exclude. */
if (matching->inclusions != NULL)
@@ -219,11 +220,7 @@ match_exclusion(struct match *match, const char *pathname)
static int
match_inclusion(struct match *match, const char *pathname)
{
-#if 0
- return (lafe_pathmatch(match->pattern, pathname, 0));
-#else
return (lafe_pathmatch(match->pattern, pathname, PATHMATCH_NO_ANCHOR_END));
-#endif
}
void
diff --git a/libarchive_fe/pathmatch.c b/libarchive_fe/pathmatch.c
index e211362066ef..ff8a10508b28 100644
--- a/libarchive_fe/pathmatch.c
+++ b/libarchive_fe/pathmatch.c
@@ -132,7 +132,7 @@ pm(const char *p, const char *s, int flags)
}
return (*s == '\0');
case '?':
- /* ? always succeds, unless we hit end of 's' */
+ /* ? always succeeds, unless we hit end of 's' */
if (*s == '\0')
return (0);
break;
diff --git a/tar/CMakeLists.txt b/tar/CMakeLists.txt
index 2ed8161d9859..6682f0ad9662 100644
--- a/tar/CMakeLists.txt
+++ b/tar/CMakeLists.txt
@@ -3,7 +3,7 @@
# How to build bsdtar
#
############################################
-IF (ENABLE_TAR)
+IF(ENABLE_TAR)
SET(bsdtar_SOURCES
bsdtar.c
diff --git a/tar/bsdtar.1 b/tar/bsdtar.1
index 655412685d35..827a74195e3e 100644
--- a/tar/bsdtar.1
+++ b/tar/bsdtar.1
@@ -25,7 +25,7 @@
.\" $FreeBSD: src/usr.bin/tar/bsdtar.1,v 1.46 2008/12/06 07:37:55 kientzle Exp $
.\"
.Dd Oct 12, 2009
-.Dt BSDTAR 1
+.Dt TAR 1
.Os
.Sh NAME
.Nm tar
@@ -51,8 +51,8 @@
.Nm
creates and manipulates streaming archive files.
This implementation can extract from tar, pax, cpio, zip, jar, ar, xar,
-rpm and ISO 9660 cdrom images and can create tar, pax, cpio, ar, zip,
-and shar archives.
+rpm, 7-zip, and ISO 9660 cdrom images and can create tar, pax, cpio, ar, zip,
+7-zip, and shar archives.
.Pp
The first synopsis form shows a
.Dq bundled
@@ -153,7 +153,7 @@ Specify the block size, in 512-byte records, for tape drive I/O.
As a rule, this argument is only needed when reading from or writing
to tape drives, and usually not even then as the default block size of
20 records (10240 bytes) is very common.
-.It Fl C Ar directory
+.It Fl C Ar directory , Fl Fl cd Ar directory , Fl Fl directory Ar directory
In c and r mode, this changes the directory before adding
the following files.
In x mode, change directories after opening the archive
@@ -473,7 +473,7 @@ Attempt to restore the full permissions, including owner, file modes, file
flags and ACLs, if available, for each item extracted from the archive.
This is the default, if
.Nm
-is being run by root and can be overriden by also specifying
+is being run by root and can be overridden by also specifying
.Fl Fl no-same-owner
and
.Fl Fl no-same-permissions .
@@ -496,25 +496,11 @@ Extract files as sparse files.
For every block on disk, check first if it contains only NULL bytes and seek
over it otherwise.
This works similar to the conv=sparse option of dd.
-.It Fl Fl same-owner
-(x mode only)
-Extract owner and group IDs.
-This is the reverse of
-.Fl Fl no-same-owner
-and the default behavior if
-.Nm
-is run as root.
-.It Fl Fl strip-components Ar count
-(x mode only)
-Remove the specified number of leading path elements.
-Pathnames with fewer elements will be silently skipped.
-Note that the pathname is edited after checking inclusion/exclusion patterns
-but before security checks.
.It Fl s Ar pattern
Modify file or archive member names according to
.Pa pattern .
The pattern has the format
-.Ar /old/new/ Ns Op gps
+.Ar /old/new/ Ns Op ghHprRsS
where
.Ar old
is a basic regular expression,
@@ -530,12 +516,35 @@ Within
~ is substituted with the match, \e1 to \e9 with the content of
the corresponding captured group.
The optional trailing g specifies that matching should continue
-after the matched part and stopped on the first unmatched pattern.
+after the matched part and stop on the first unmatched pattern.
The optional trailing s specifies that the pattern applies to the value
of symbolic links.
The optional trailing p specifies that after a successful substitution
the original path name and the new path name should be printed to
standard error.
+Optional trailing H, R, or S characters suppress substitutions
+for hardlink targets, regular filenames, or symlink targets,
+respectively.
+Optional trailing h, r, or s characters enable substitutions
+for hardlink targets, regular filenames, or symlink targets,
+respectively.
+The default is
+.Ar hrs
+which applies substitutions to all names.
+In particular, it is never necessary to specify h, r, or s.
+.It Fl Fl same-owner
+(x mode only)
+Extract owner and group IDs.
+This is the reverse of
+.Fl Fl no-same-owner
+and the default behavior if
+.Nm
+is run as root.
+.It Fl Fl strip-components Ar count
+Remove the specified number of leading path elements.
+Pathnames with fewer elements will be silently skipped.
+Note that the pathname is edited after checking inclusion/exclusion patterns
+but before security checks.
.It Fl T Ar filename , Fl Fl files-from Ar filename
In x or t mode,
.Nm
diff --git a/tar/bsdtar.c b/tar/bsdtar.c
index 3b227bcce81e..c1fae6a0dc96 100644
--- a/tar/bsdtar.c
+++ b/tar/bsdtar.c
@@ -32,6 +32,9 @@ __FBSDID("$FreeBSD: src/usr.bin/tar/bsdtar.c,v 1.93 2008/11/08 04:43:24 kientzle
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
+#ifdef HAVE_COPYFILE_H
+#include <copyfile.h>
+#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
@@ -63,9 +66,6 @@ __FBSDID("$FreeBSD: src/usr.bin/tar/bsdtar.c,v 1.93 2008/11/08 04:43:24 kientzle
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
-#if HAVE_ZLIB_H
-#include <zlib.h>
-#endif
#include "bsdtar.h"
#include "err.h"
@@ -80,6 +80,10 @@ __FBSDID("$FreeBSD: src/usr.bin/tar/bsdtar.c,v 1.93 2008/11/08 04:43:24 kientzle
#if defined(_WIN32) && !defined(__CYGWIN__)
#define _PATH_DEFTAPE "\\\\.\\tape0"
#endif
+#if defined(__APPLE__)
+#undef _PATH_DEFTAPE
+#define _PATH_DEFTAPE "-" /* Mac OS has no tape support, default to stdio. */
+#endif
#ifndef _PATH_DEFTAPE
#define _PATH_DEFTAPE "/dev/tape"
@@ -89,8 +93,6 @@ __FBSDID("$FreeBSD: src/usr.bin/tar/bsdtar.c,v 1.93 2008/11/08 04:43:24 kientzle
int _CRT_glob = 0; /* Disable broken CRT globbing. */
#endif
-static struct bsdtar *_bsdtar;
-
#if defined(HAVE_SIGACTION) && (defined(SIGINFO) || defined(SIGUSR1))
static volatile int siginfo_occurred;
@@ -144,15 +146,15 @@ main(int argc, char **argv)
* Use a pointer for consistency, but stack-allocated storage
* for ease of cleanup.
*/
- _bsdtar = bsdtar = &bsdtar_storage;
+ bsdtar = &bsdtar_storage;
memset(bsdtar, 0, sizeof(*bsdtar));
bsdtar->fd = -1; /* Mark as "unused" */
bsdtar->gid = -1;
bsdtar->uid = -1;
option_o = 0;
-#if defined(HAVE_SIGACTION) && (defined(SIGINFO) || defined(SIGUSR1))
- { /* Catch SIGINFO and SIGUSR1, if they exist. */
+#if defined(HAVE_SIGACTION)
+ { /* Set up signal handling. */
struct sigaction sa;
sa.sa_handler = siginfo_handler;
sigemptyset(&sa.sa_mask);
@@ -166,6 +168,11 @@ main(int argc, char **argv)
if (sigaction(SIGUSR1, &sa, NULL))
lafe_errc(1, errno, "sigaction(SIGUSR1) failed");
#endif
+#ifdef SIGPIPE
+ /* Ignore SIGPIPE signals. */
+ sa.sa_handler = SIG_IGN;
+ sigaction(SIGPIPE, &sa, NULL);
+#endif
}
#endif
@@ -204,6 +211,11 @@ main(int argc, char **argv)
if (bsdtar->filename == NULL)
bsdtar->filename = _PATH_DEFTAPE;
+ /* Default block size settings. */
+ bsdtar->bytes_per_block = DEFAULT_BYTES_PER_BLOCK;
+ /* Allow library to default this unless user specifies -b. */
+ bsdtar->bytes_in_last_block = -1;
+
/* Default: preserve mod time on extract */
bsdtar->extract_flags = ARCHIVE_EXTRACT_TIME;
@@ -221,9 +233,20 @@ main(int argc, char **argv)
bsdtar->extract_flags |= ARCHIVE_EXTRACT_ACL;
bsdtar->extract_flags |= ARCHIVE_EXTRACT_XATTR;
bsdtar->extract_flags |= ARCHIVE_EXTRACT_FFLAGS;
+ bsdtar->extract_flags |= ARCHIVE_EXTRACT_MAC_METADATA;
}
#endif
+ /*
+ * Enable Mac OS "copyfile()" extension by default.
+ * This has no effect on other platforms.
+ */
+ bsdtar->enable_copyfile = 1;
+#ifdef COPYFILE_DISABLE_VAR
+ if (getenv(COPYFILE_DISABLE_VAR))
+ bsdtar->enable_copyfile = 0;
+#endif
+
bsdtar->argv = argv;
bsdtar->argc = argc;
@@ -239,14 +262,20 @@ main(int argc, char **argv)
/* libarchive doesn't need this; just ignore it. */
break;
case 'b': /* SUSv2 */
- t = atoi(bsdtar->optarg);
+ t = atoi(bsdtar->argument);
if (t <= 0 || t > 8192)
lafe_errc(1, 0,
"Argument to -b is out of range (1..8192)");
bsdtar->bytes_per_block = 512 * t;
+ /* Explicit -b forces last block size. */
+ bsdtar->bytes_in_last_block = bsdtar->bytes_per_block;
break;
case 'C': /* GNU tar */
- set_chdir(bsdtar, bsdtar->optarg);
+ if (strlen(bsdtar->argument) == 0)
+ lafe_errc(1, 0,
+ "Meaningless option: -C ''");
+
+ set_chdir(bsdtar, bsdtar->argument);
break;
case 'c': /* SUSv2 */
set_mode(bsdtar, opt);
@@ -257,28 +286,29 @@ main(int argc, char **argv)
case OPTION_CHROOT: /* NetBSD */
bsdtar->option_chroot = 1;
break;
+ case OPTION_DISABLE_COPYFILE: /* Mac OS X */
+ bsdtar->enable_copyfile = 0;
+ break;
case OPTION_EXCLUDE: /* GNU tar */
- if (lafe_exclude(&bsdtar->matching, bsdtar->optarg))
+ if (lafe_exclude(&bsdtar->matching, bsdtar->argument))
lafe_errc(1, 0,
- "Couldn't exclude %s\n", bsdtar->optarg);
+ "Couldn't exclude %s\n", bsdtar->argument);
break;
case OPTION_FORMAT: /* GNU tar, others */
- bsdtar->create_format = bsdtar->optarg;
+ bsdtar->create_format = bsdtar->argument;
break;
case 'f': /* SUSv2 */
- bsdtar->filename = bsdtar->optarg;
- if (strcmp(bsdtar->filename, "-") == 0)
- bsdtar->filename = NULL;
+ bsdtar->filename = bsdtar->argument;
break;
case OPTION_GID: /* cpio */
- t = atoi(bsdtar->optarg);
+ t = atoi(bsdtar->argument);
if (t < 0)
lafe_errc(1, 0,
"Argument to --gid must be positive");
bsdtar->gid = t;
break;
case OPTION_GNAME: /* cpio */
- bsdtar->gname = bsdtar->optarg;
+ bsdtar->gname = bsdtar->argument;
break;
case 'H': /* BSD convention */
bsdtar->symlink_mode = 'H';
@@ -303,18 +333,18 @@ main(int argc, char **argv)
* permissions without having to create those
* permissions on disk.
*/
- bsdtar->names_from_file = bsdtar->optarg;
+ bsdtar->names_from_file = bsdtar->argument;
break;
case OPTION_INCLUDE:
/*
- * Noone else has the @archive extension, so
- * noone else needs this to filter entries
+ * No one else has the @archive extension, so
+ * no one else needs this to filter entries
* when transforming archives.
*/
- if (lafe_include(&bsdtar->matching, bsdtar->optarg))
+ if (lafe_include(&bsdtar->matching, bsdtar->argument))
lafe_errc(1, 0,
"Failed to add %s to inclusion list",
- bsdtar->optarg);
+ bsdtar->argument);
break;
case 'j': /* GNU tar */
if (bsdtar->create_compression != '\0')
@@ -343,7 +373,8 @@ main(int argc, char **argv)
/* GNU tar 1.13 used -l for --one-file-system */
bsdtar->option_warn_links = 1;
break;
- case OPTION_LZMA:
+ case OPTION_LZIP: /* GNU tar beginning with 1.23 */
+ case OPTION_LZMA: /* GNU tar beginning with 1.20 */
if (bsdtar->create_compression != '\0')
lafe_errc(1, 0,
"Can't specify both -%c and -%c", opt,
@@ -364,28 +395,32 @@ main(int argc, char **argv)
* TODO: Add corresponding "older" options to reverse these.
*/
case OPTION_NEWER_CTIME: /* GNU tar */
- bsdtar->newer_ctime_sec = get_date(now, bsdtar->optarg);
+ bsdtar->newer_ctime_filter = 1;
+ bsdtar->newer_ctime_sec = get_date(now, bsdtar->argument);
break;
case OPTION_NEWER_CTIME_THAN:
{
struct stat st;
- if (stat(bsdtar->optarg, &st) != 0)
+ if (stat(bsdtar->argument, &st) != 0)
lafe_errc(1, 0,
- "Can't open file %s", bsdtar->optarg);
+ "Can't open file %s", bsdtar->argument);
+ bsdtar->newer_ctime_filter = 1;
bsdtar->newer_ctime_sec = st.st_ctime;
bsdtar->newer_ctime_nsec =
ARCHIVE_STAT_CTIME_NANOS(&st);
}
break;
case OPTION_NEWER_MTIME: /* GNU tar */
- bsdtar->newer_mtime_sec = get_date(now, bsdtar->optarg);
+ bsdtar->newer_mtime_filter = 1;
+ bsdtar->newer_mtime_sec = get_date(now, bsdtar->argument);
break;
case OPTION_NEWER_MTIME_THAN:
{
struct stat st;
- if (stat(bsdtar->optarg, &st) != 0)
+ if (stat(bsdtar->argument, &st) != 0)
lafe_errc(1, 0,
- "Can't open file %s", bsdtar->optarg);
+ "Can't open file %s", bsdtar->argument);
+ bsdtar->newer_mtime_filter = 1;
bsdtar->newer_mtime_sec = st.st_mtime;
bsdtar->newer_mtime_nsec =
ARCHIVE_STAT_MTIME_NANOS(&st);
@@ -402,6 +437,7 @@ main(int argc, char **argv)
bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_ACL;
bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_XATTR;
bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_FFLAGS;
+ bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_MAC_METADATA;
break;
case OPTION_NULL: /* GNU tar */
bsdtar->option_null++;
@@ -409,6 +445,7 @@ main(int argc, char **argv)
case OPTION_NUMERIC_OWNER: /* GNU tar */
bsdtar->uname = "";
bsdtar->gname = "";
+ bsdtar->option_numeric_owner++;
break;
case 'O': /* GNU tar */
bsdtar->option_stdout = 1;
@@ -420,7 +457,7 @@ main(int argc, char **argv)
bsdtar->option_dont_traverse_mounts = 1;
break;
case OPTION_OPTIONS:
- bsdtar->option_options = bsdtar->optarg;
+ bsdtar->option_options = bsdtar->argument;
break;
#if 0
/*
@@ -442,6 +479,7 @@ main(int argc, char **argv)
bsdtar->extract_flags |= ARCHIVE_EXTRACT_ACL;
bsdtar->extract_flags |= ARCHIVE_EXTRACT_XATTR;
bsdtar->extract_flags |= ARCHIVE_EXTRACT_FFLAGS;
+ bsdtar->extract_flags |= ARCHIVE_EXTRACT_MAC_METADATA;
break;
case OPTION_POSIX: /* GNU tar */
bsdtar->create_format = "pax";
@@ -457,7 +495,7 @@ main(int argc, char **argv)
break;
case 's': /* NetBSD pax-as-tar */
#if HAVE_REGEX_H
- add_substitution(bsdtar, bsdtar->optarg);
+ add_substitution(bsdtar, bsdtar->argument);
#else
lafe_warnc(0,
"-s is not supported by this version of bsdtar");
@@ -468,10 +506,16 @@ main(int argc, char **argv)
bsdtar->extract_flags |= ARCHIVE_EXTRACT_OWNER;
break;
case OPTION_STRIP_COMPONENTS: /* GNU tar 1.15 */
- bsdtar->strip_components = atoi(bsdtar->optarg);
+ errno = 0;
+ bsdtar->strip_components = strtol(bsdtar->argument,
+ NULL, 0);
+ if (errno)
+ lafe_errc(1, 0,
+ "Invalid --strip-components argument: %s",
+ bsdtar->argument);
break;
case 'T': /* GNU tar */
- bsdtar->names_from_file = bsdtar->optarg;
+ bsdtar->names_from_file = bsdtar->argument;
break;
case 't': /* SUSv2 */
set_mode(bsdtar, opt);
@@ -488,14 +532,14 @@ main(int argc, char **argv)
set_mode(bsdtar, opt);
break;
case OPTION_UID: /* cpio */
- t = atoi(bsdtar->optarg);
+ t = atoi(bsdtar->argument);
if (t < 0)
lafe_errc(1, 0,
"Argument to --uid must be positive");
bsdtar->uid = t;
break;
case OPTION_UNAME: /* cpio */
- bsdtar->uname = bsdtar->optarg;
+ bsdtar->uname = bsdtar->argument;
break;
case 'v': /* SUSv2 */
bsdtar->verbose++;
@@ -515,10 +559,10 @@ main(int argc, char **argv)
bsdtar->option_interactive = 1;
break;
case 'X': /* GNU tar */
- if (lafe_exclude_from_file(&bsdtar->matching, bsdtar->optarg))
+ if (lafe_exclude_from_file(&bsdtar->matching, bsdtar->argument))
lafe_errc(1, 0,
"failed to process exclusions from file %s",
- bsdtar->optarg);
+ bsdtar->argument);
break;
case 'x': /* SUSv2 */
set_mode(bsdtar, opt);
@@ -545,7 +589,7 @@ main(int argc, char **argv)
bsdtar->create_compression = opt;
break;
case OPTION_USE_COMPRESS_PROGRAM:
- bsdtar->compress_program = bsdtar->optarg;
+ bsdtar->compress_program = bsdtar->argument;
break;
default:
usage();
@@ -617,8 +661,10 @@ main(int argc, char **argv)
buff[1] = bsdtar->symlink_mode;
only_mode(bsdtar, buff, "cru");
}
- if (bsdtar->strip_components != 0)
- only_mode(bsdtar, "--strip-components", "xt");
+
+ /* Filename "-" implies stdio. */
+ if (strcmp(bsdtar->filename, "-") == 0)
+ bsdtar->filename = NULL;
switch(bsdtar->mode) {
case 'c':
@@ -691,7 +737,7 @@ version(void)
{
printf("bsdtar %s - %s\n",
BSDTAR_VERSION_STRING,
- archive_version());
+ archive_version_string());
exit(0);
}
diff --git a/tar/bsdtar.h b/tar/bsdtar.h
index 893ebca5d4a5..82f9f789aa9f 100644
--- a/tar/bsdtar.h
+++ b/tar/bsdtar.h
@@ -46,11 +46,14 @@ struct bsdtar {
const char *create_format; /* -F format */
char *pending_chdir; /* -C dir */
const char *names_from_file; /* -T file */
+ int newer_ctime_filter; /* --newer/--newer-than */
time_t newer_ctime_sec; /* --newer/--newer-than */
long newer_ctime_nsec; /* --newer/--newer-than */
+ int newer_mtime_filter; /* --newer-mtime/--newer-mtime-than */
time_t newer_mtime_sec; /* --newer-mtime */
long newer_mtime_nsec; /* --newer-mtime-than */
int bytes_per_block; /* -b block_size */
+ int bytes_in_last_block; /* See -b handling. */
int verbose; /* -v */
int extract_flags; /* Flags for extract operation */
int strip_components; /* Remove this many leading dirs */
@@ -71,12 +74,18 @@ struct bsdtar {
char option_interactive; /* -w */
char option_no_owner; /* -o */
char option_no_subdirs; /* -n */
+ char option_numeric_owner; /* --numeric-owner */
char option_null; /* --null */
char option_stdout; /* -O */
char option_totals; /* --totals */
char option_unlink_first; /* -U */
char option_warn_links; /* --check-links */
char day_first; /* show day before month in -tv output */
+ char enable_copyfile; /* For Mac OS */
+
+ /* Option parser state */
+ int getopt_state;
+ char *getopt_word;
/* If >= 0, then close this when done. */
int fd;
@@ -84,7 +93,7 @@ struct bsdtar {
/* Miscellaneous state information */
int argc;
char **argv;
- const char *optarg;
+ const char *argument;
size_t gs_width; /* For 'list_item' in read.c */
size_t u_width; /* for 'list_item' in read.c */
uid_t user_uid; /* UID running this program */
@@ -101,6 +110,7 @@ struct bsdtar {
struct archive_dir *archive_dir; /* for write.c */
struct name_cache *gname_cache; /* for write.c */
char *buff; /* for write.c */
+ size_t buff_size; /* for write.c */
struct lafe_matching *matching; /* for matching.c */
struct security *security; /* for read.c */
struct name_cache *uname_cache; /* for write.c */
@@ -112,6 +122,7 @@ struct bsdtar {
enum {
OPTION_CHECK_LINKS = 1,
OPTION_CHROOT,
+ OPTION_DISABLE_COPYFILE,
OPTION_EXCLUDE,
OPTION_FORMAT,
OPTION_GID,
@@ -119,6 +130,7 @@ enum {
OPTION_HELP,
OPTION_INCLUDE,
OPTION_KEEP_NEWER_FILES,
+ OPTION_LZIP,
OPTION_LZMA,
OPTION_NEWER_CTIME,
OPTION_NEWER_CTIME_THAN,
@@ -141,7 +153,6 @@ enum {
OPTION_VERSION
};
-
int bsdtar_getopt(struct bsdtar *);
void do_chdir(struct bsdtar *);
int edit_pathname(struct bsdtar *, struct archive_entry *);
@@ -160,6 +171,6 @@ int yes(const char *fmt, ...);
#if HAVE_REGEX_H
void add_substitution(struct bsdtar *, const char *);
-int apply_substitution(struct bsdtar *, const char *, char **, int);
+int apply_substitution(struct bsdtar *, const char *, char **, int, int);
void cleanup_substitution(struct bsdtar *);
#endif
diff --git a/tar/bsdtar_platform.h b/tar/bsdtar_platform.h
index fce9c99815a2..45228f504f84 100644
--- a/tar/bsdtar_platform.h
+++ b/tar/bsdtar_platform.h
@@ -67,10 +67,10 @@
#endif
/*
- * Include "dirent.h" (or it's equivalent on several different platforms).
+ * Include "dirent.h" (or its equivalent on several different platforms).
*
* This is slightly modified from the GNU autoconf recipe.
- * In particular, FreeBSD includes d_namlen in it's dirent structure,
+ * In particular, FreeBSD includes d_namlen in its dirent structure,
* so my configure script includes an explicit test for the d_namlen
* field.
*/
diff --git a/tar/bsdtar_windows.h b/tar/bsdtar_windows.h
index 092ea6959d83..f0611d79abdc 100644
--- a/tar/bsdtar_windows.h
+++ b/tar/bsdtar_windows.h
@@ -26,35 +26,35 @@
*/
#ifndef BSDTAR_WINDOWS_H
-#define BSDTAR_WINDOWS_H 1
+#define BSDTAR_WINDOWS_H 1
#include <direct.h>
#include <windows.h>
#ifndef PRId64
-#define PRId64 "I64"
+#define PRId64 "I64"
#endif
-#define geteuid() 0
+#define geteuid() 0
#ifndef S_IFIFO
-#define S_IFIFO 0010000 /* pipe */
+#define S_IFIFO 0010000 /* pipe */
#endif
#include <string.h> /* Must include before redefining 'strdup' */
#if !defined(__BORLANDC__)
-#define strdup _strdup
+#define strdup _strdup
#endif
#if !defined(__BORLANDC__)
-#define getcwd _getcwd
+#define getcwd _getcwd
#endif
-#define chdir __tar_chdir
+#define chdir __tar_chdir
int __tar_chdir(const char *);
#ifndef S_ISREG
-#define S_ISREG(a) (a & _S_IFREG)
+#define S_ISREG(a) (a & _S_IFREG)
#endif
#ifndef S_ISBLK
-#define S_ISBLK(a) (0)
+#define S_ISBLK(a) (0)
#endif
#endif /* BSDTAR_WINDOWS_H */
diff --git a/tar/cmdline.c b/tar/cmdline.c
index f0431554c521..83bbda13629f 100644
--- a/tar/cmdline.c
+++ b/tar/cmdline.c
@@ -58,7 +58,7 @@ static const char *short_options
* a small change to the code below.
*/
-static struct option {
+static const struct bsdtar_option {
const char *name;
int required; /* 1 if this option requires an argument. */
int equivalent; /* Equivalent short option. */
@@ -77,6 +77,7 @@ static struct option {
{ "create", 0, 'c' },
{ "dereference", 0, 'L' },
{ "directory", 1, 'C' },
+ { "disable-copyfile", 0, OPTION_DISABLE_COPYFILE },
{ "exclude", 1, OPTION_EXCLUDE },
{ "exclude-from", 1, 'X' },
{ "extract", 0, 'x' },
@@ -90,11 +91,12 @@ static struct option {
{ "gzip", 0, 'z' },
{ "help", 0, OPTION_HELP },
{ "include", 1, OPTION_INCLUDE },
- { "interactive", 0, 'w' },
{ "insecure", 0, 'P' },
+ { "interactive", 0, 'w' },
{ "keep-newer-files", 0, OPTION_KEEP_NEWER_FILES },
{ "keep-old-files", 0, 'k' },
{ "list", 0, 't' },
+ { "lzip", 0, OPTION_LZIP },
{ "lzma", 0, OPTION_LZMA },
{ "modification-time", 0, 'm' },
{ "newer", 1, OPTION_NEWER_CTIME },
@@ -103,11 +105,11 @@ static struct option {
{ "newer-mtime", 1, OPTION_NEWER_MTIME },
{ "newer-mtime-than", 1, OPTION_NEWER_MTIME_THAN },
{ "newer-than", 1, OPTION_NEWER_CTIME_THAN },
- { "nodump", 0, OPTION_NODUMP },
- { "norecurse", 0, 'n' },
{ "no-recursion", 0, 'n' },
{ "no-same-owner", 0, OPTION_NO_SAME_OWNER },
{ "no-same-permissions", 0, OPTION_NO_SAME_PERMISSIONS },
+ { "nodump", 0, OPTION_NODUMP },
+ { "norecurse", 0, 'n' },
{ "null", 0, OPTION_NULL },
{ "numeric-owner", 0, OPTION_NUMERIC_OWNER },
{ "one-file-system", 0, OPTION_ONE_FILE_SYSTEM },
@@ -171,7 +173,7 @@ static struct option {
*
* TODO: If we want to support arbitrary command-line options from -T
* input (as GNU tar does), we may need to extend this to handle option
- * words from sources other than argv/arc. I'm not really sure if I
+ * words from sources other than argv/argc. I'm not really sure if I
* like that feature of GNU tar, so it's certainly not a priority.
*/
@@ -180,19 +182,17 @@ bsdtar_getopt(struct bsdtar *bsdtar)
{
enum { state_start = 0, state_old_tar, state_next_word,
state_short, state_long };
- static int state = state_start;
- static char *opt_word;
- const struct option *popt, *match = NULL, *match2 = NULL;
+ const struct bsdtar_option *popt, *match = NULL, *match2 = NULL;
const char *p, *long_prefix = "--";
size_t optlength;
int opt = '?';
int required = 0;
- bsdtar->optarg = NULL;
+ bsdtar->argument = NULL;
/* First time through, initialize everything. */
- if (state == state_start) {
+ if (bsdtar->getopt_state == state_start) {
/* Skip program name. */
++bsdtar->argv;
--bsdtar->argc;
@@ -200,10 +200,10 @@ bsdtar_getopt(struct bsdtar *bsdtar)
return (-1);
/* Decide between "new style" and "old style" arguments. */
if (bsdtar->argv[0][0] == '-') {
- state = state_next_word;
+ bsdtar->getopt_state = state_next_word;
} else {
- state = state_old_tar;
- opt_word = *bsdtar->argv++;
+ bsdtar->getopt_state = state_old_tar;
+ bsdtar->getopt_word = *bsdtar->argv++;
--bsdtar->argc;
}
}
@@ -211,20 +211,20 @@ bsdtar_getopt(struct bsdtar *bsdtar)
/*
* We're parsing old-style tar arguments
*/
- if (state == state_old_tar) {
+ if (bsdtar->getopt_state == state_old_tar) {
/* Get the next option character. */
- opt = *opt_word++;
+ opt = *bsdtar->getopt_word++;
if (opt == '\0') {
/* New-style args can follow old-style. */
- state = state_next_word;
+ bsdtar->getopt_state = state_next_word;
} else {
/* See if it takes an argument. */
p = strchr(short_options, opt);
if (p == NULL)
return ('?');
if (p[1] == ':') {
- bsdtar->optarg = *bsdtar->argv;
- if (bsdtar->optarg == NULL) {
+ bsdtar->argument = *bsdtar->argv;
+ if (bsdtar->argument == NULL) {
lafe_warnc(0,
"Option %c requires an argument",
opt);
@@ -239,7 +239,7 @@ bsdtar_getopt(struct bsdtar *bsdtar)
/*
* We're ready to look at the next word in argv.
*/
- if (state == state_next_word) {
+ if (bsdtar->getopt_state == state_next_word) {
/* No more arguments, so no more options. */
if (bsdtar->argv[0] == NULL)
return (-1);
@@ -253,28 +253,28 @@ bsdtar_getopt(struct bsdtar *bsdtar)
return (-1);
}
/* Get next word for parsing. */
- opt_word = *bsdtar->argv++;
+ bsdtar->getopt_word = *bsdtar->argv++;
--bsdtar->argc;
- if (opt_word[1] == '-') {
+ if (bsdtar->getopt_word[1] == '-') {
/* Set up long option parser. */
- state = state_long;
- opt_word += 2; /* Skip leading '--' */
+ bsdtar->getopt_state = state_long;
+ bsdtar->getopt_word += 2; /* Skip leading '--' */
} else {
/* Set up short option parser. */
- state = state_short;
- ++opt_word; /* Skip leading '-' */
+ bsdtar->getopt_state = state_short;
+ ++bsdtar->getopt_word; /* Skip leading '-' */
}
}
/*
* We're parsing a group of POSIX-style single-character options.
*/
- if (state == state_short) {
+ if (bsdtar->getopt_state == state_short) {
/* Peel next option off of a group of short options. */
- opt = *opt_word++;
+ opt = *bsdtar->getopt_word++;
if (opt == '\0') {
/* End of this group; recurse to get next option. */
- state = state_next_word;
+ bsdtar->getopt_state = state_next_word;
return bsdtar_getopt(bsdtar);
}
@@ -287,11 +287,11 @@ bsdtar_getopt(struct bsdtar *bsdtar)
/* If it takes an argument, parse that. */
if (required) {
- /* If arg is run-in, opt_word already points to it. */
- if (opt_word[0] == '\0') {
+ /* If arg is run-in, bsdtar->getopt_word already points to it. */
+ if (bsdtar->getopt_word[0] == '\0') {
/* Otherwise, pick up the next word. */
- opt_word = *bsdtar->argv;
- if (opt_word == NULL) {
+ bsdtar->getopt_word = *bsdtar->argv;
+ if (bsdtar->getopt_word == NULL) {
lafe_warnc(0,
"Option -%c requires an argument",
opt);
@@ -301,36 +301,36 @@ bsdtar_getopt(struct bsdtar *bsdtar)
--bsdtar->argc;
}
if (opt == 'W') {
- state = state_long;
+ bsdtar->getopt_state = state_long;
long_prefix = "-W "; /* For clearer errors. */
} else {
- state = state_next_word;
- bsdtar->optarg = opt_word;
+ bsdtar->getopt_state = state_next_word;
+ bsdtar->argument = bsdtar->getopt_word;
}
}
}
/* We're reading a long option, including -W long=arg convention. */
- if (state == state_long) {
+ if (bsdtar->getopt_state == state_long) {
/* After this long option, we'll be starting a new word. */
- state = state_next_word;
+ bsdtar->getopt_state = state_next_word;
/* Option name ends at '=' if there is one. */
- p = strchr(opt_word, '=');
+ p = strchr(bsdtar->getopt_word, '=');
if (p != NULL) {
- optlength = (size_t)(p - opt_word);
- bsdtar->optarg = (char *)(uintptr_t)(p + 1);
+ optlength = (size_t)(p - bsdtar->getopt_word);
+ bsdtar->argument = (char *)(uintptr_t)(p + 1);
} else {
- optlength = strlen(opt_word);
+ optlength = strlen(bsdtar->getopt_word);
}
/* Search the table for an unambiguous match. */
for (popt = tar_longopts; popt->name != NULL; popt++) {
/* Short-circuit if first chars don't match. */
- if (popt->name[0] != opt_word[0])
+ if (popt->name[0] != bsdtar->getopt_word[0])
continue;
/* If option is a prefix of name in table, record it.*/
- if (strncmp(opt_word, popt->name, optlength) == 0) {
+ if (strncmp(bsdtar->getopt_word, popt->name, optlength) == 0) {
match2 = match; /* Record up to two matches. */
match = popt;
/* If it's an exact match, we're done. */
@@ -345,22 +345,22 @@ bsdtar_getopt(struct bsdtar *bsdtar)
if (match == NULL) {
lafe_warnc(0,
"Option %s%s is not supported",
- long_prefix, opt_word);
+ long_prefix, bsdtar->getopt_word);
return ('?');
}
if (match2 != NULL) {
lafe_warnc(0,
"Ambiguous option %s%s (matches --%s and --%s)",
- long_prefix, opt_word, match->name, match2->name);
+ long_prefix, bsdtar->getopt_word, match->name, match2->name);
return ('?');
}
/* We've found a unique match; does it need an argument? */
if (match->required) {
/* Argument required: get next word if necessary. */
- if (bsdtar->optarg == NULL) {
- bsdtar->optarg = *bsdtar->argv;
- if (bsdtar->optarg == NULL) {
+ if (bsdtar->argument == NULL) {
+ bsdtar->argument = *bsdtar->argv;
+ if (bsdtar->argument == NULL) {
lafe_warnc(0,
"Option %s%s requires an argument",
long_prefix, match->name);
@@ -371,7 +371,7 @@ bsdtar_getopt(struct bsdtar *bsdtar)
}
} else {
/* Argument forbidden: fail if there is one. */
- if (bsdtar->optarg != NULL) {
+ if (bsdtar->argument != NULL) {
lafe_warnc(0,
"Option %s%s does not allow an argument",
long_prefix, match->name);
diff --git a/tar/getdate.c b/tar/getdate.c
index ffaa679ba1a3..0e15d9c8a5be 100644
--- a/tar/getdate.c
+++ b/tar/getdate.c
@@ -864,7 +864,7 @@ nexttoken(char **in, time_t *value)
}
}
-#define TM_YEAR_ORIGIN 1900
+#define TM_YEAR_ORIGIN 1900
/* Yield A - B, measured in seconds. */
static long
diff --git a/tar/read.c b/tar/read.c
index 0470599885c2..2ca7a534cb14 100644
--- a/tar/read.c
+++ b/tar/read.c
@@ -76,12 +76,12 @@ struct progress_data {
static void list_item_verbose(struct bsdtar *, FILE *,
struct archive_entry *);
-static void read_archive(struct bsdtar *bsdtar, char mode);
+static void read_archive(struct bsdtar *bsdtar, char mode, struct archive *);
void
tar_mode_t(struct bsdtar *bsdtar)
{
- read_archive(bsdtar, 't');
+ read_archive(bsdtar, 't', NULL);
if (lafe_unmatched_inclusions_warn(bsdtar->matching, "Not found in archive") != 0)
bsdtar->return_value = 1;
}
@@ -89,10 +89,20 @@ tar_mode_t(struct bsdtar *bsdtar)
void
tar_mode_x(struct bsdtar *bsdtar)
{
- read_archive(bsdtar, 'x');
+ struct archive *writer;
+
+ writer = archive_write_disk_new();
+ if (writer == NULL)
+ lafe_errc(1, ENOMEM, "Cannot allocate disk writer object");
+ if (!bsdtar->option_numeric_owner)
+ archive_write_disk_set_standard_lookup(writer);
+ archive_write_disk_set_options(writer, bsdtar->extract_flags);
+
+ read_archive(bsdtar, 'x', writer);
if (lafe_unmatched_inclusions_warn(bsdtar->matching, "Not found in archive") != 0)
bsdtar->return_value = 1;
+ archive_write_free(writer);
}
static void
@@ -135,14 +145,15 @@ progress_func(void *cookie)
* Handle 'x' and 't' modes.
*/
static void
-read_archive(struct bsdtar *bsdtar, char mode)
+read_archive(struct bsdtar *bsdtar, char mode, struct archive *writer)
{
struct progress_data progress_data;
FILE *out;
struct archive *a;
struct archive_entry *entry;
- const struct stat *st;
int r;
+ time_t sec;
+ long nsec;
while (*bsdtar->argv) {
lafe_include(&bsdtar->matching, *bsdtar->argv);
@@ -155,15 +166,13 @@ read_archive(struct bsdtar *bsdtar, char mode)
a = archive_read_new();
if (bsdtar->compress_program != NULL)
- archive_read_support_compression_program(a, bsdtar->compress_program);
+ archive_read_support_filter_program(a, bsdtar->compress_program);
else
- archive_read_support_compression_all(a);
+ archive_read_support_filter_all(a);
archive_read_support_format_all(a);
if (ARCHIVE_OK != archive_read_set_options(a, bsdtar->option_options))
lafe_errc(1, 0, "%s", archive_error_string(a));
- if (archive_read_open_file(a, bsdtar->filename,
- bsdtar->bytes_per_block != 0 ? bsdtar->bytes_per_block :
- DEFAULT_BYTES_PER_BLOCK))
+ if (archive_read_open_file(a, bsdtar->filename, bsdtar->bytes_per_block))
lafe_errc(1, 0, "Error opening archive: %s",
archive_error_string(a));
@@ -225,21 +234,36 @@ read_archive(struct bsdtar *bsdtar, char mode)
/*
* Exclude entries that are too old.
*/
- st = archive_entry_stat(entry);
- if (bsdtar->newer_ctime_sec > 0) {
- if (st->st_ctime < bsdtar->newer_ctime_sec)
+ if (bsdtar->newer_ctime_filter) {
+ /* Use ctime if format provides, else mtime. */
+ if (archive_entry_ctime_is_set(entry)) {
+ sec = archive_entry_ctime(entry);
+ nsec = archive_entry_ctime_nsec(entry);
+ } else if (archive_entry_mtime_is_set(entry)) {
+ sec = archive_entry_mtime(entry);
+ nsec = archive_entry_mtime_nsec(entry);
+ } else {
+ sec = 0;
+ nsec = 0;
+ }
+ if (sec < bsdtar->newer_ctime_sec)
continue; /* Too old, skip it. */
- if (st->st_ctime == bsdtar->newer_ctime_sec
- && ARCHIVE_STAT_CTIME_NANOS(st)
- <= bsdtar->newer_ctime_nsec)
+ if (sec == bsdtar->newer_ctime_sec
+ && nsec <= bsdtar->newer_ctime_nsec)
continue; /* Too old, skip it. */
}
- if (bsdtar->newer_mtime_sec > 0) {
- if (st->st_mtime < bsdtar->newer_mtime_sec)
+ if (bsdtar->newer_mtime_filter) {
+ if (archive_entry_mtime_is_set(entry)) {
+ sec = archive_entry_mtime(entry);
+ nsec = archive_entry_mtime_nsec(entry);
+ } else {
+ sec = 0;
+ nsec = 0;
+ }
+ if (sec < bsdtar->newer_mtime_sec)
continue; /* Too old, skip it. */
- if (st->st_mtime == bsdtar->newer_mtime_sec
- && ARCHIVE_STAT_MTIME_NANOS(st)
- <= bsdtar->newer_mtime_nsec)
+ if (sec == bsdtar->newer_mtime_sec
+ && nsec <= bsdtar->newer_mtime_nsec)
continue; /* Too old, skip it. */
}
@@ -310,13 +334,12 @@ read_archive(struct bsdtar *bsdtar, char mode)
fflush(stderr);
}
- // TODO siginfo_printinfo(bsdtar, 0);
+ /* TODO siginfo_printinfo(bsdtar, 0); */
if (bsdtar->option_stdout)
r = archive_read_data_into_fd(a, 1);
else
- r = archive_read_extract(a, entry,
- bsdtar->extract_flags);
+ r = archive_read_extract2(a, entry, writer);
if (r != ARCHIVE_OK) {
if (!bsdtar->verbose)
safe_fprintf(stderr, "%s",
@@ -345,7 +368,7 @@ read_archive(struct bsdtar *bsdtar, char mode)
fprintf(stdout, "Archive Format: %s, Compression: %s\n",
archive_format_name(a), archive_compression_name(a));
- archive_read_finish(a);
+ archive_read_free(a);
}
@@ -427,11 +450,11 @@ list_item_verbose(struct bsdtar *bsdtar, FILE *out, struct archive_entry *entry)
/* Format the time using 'ls -l' conventions. */
tim = archive_entry_mtime(entry);
-#define HALF_YEAR (time_t)365 * 86400 / 2
+#define HALF_YEAR (time_t)365 * 86400 / 2
#if defined(_WIN32) && !defined(__CYGWIN__)
-#define DAY_FMT "%d" /* Windows' strftime function does not support %e format. */
+#define DAY_FMT "%d" /* Windows' strftime function does not support %e format. */
#else
-#define DAY_FMT "%e" /* Day number without leading zeros */
+#define DAY_FMT "%e" /* Day number without leading zeros */
#endif
if (tim < now - HALF_YEAR || tim > now + HALF_YEAR)
fmt = bsdtar->day_first ? DAY_FMT " %b %Y" : "%b " DAY_FMT " %Y";
diff --git a/tar/subst.c b/tar/subst.c
index 3982054193c2..0ef95b917d5d 100644
--- a/tar/subst.c
+++ b/tar/subst.c
@@ -44,7 +44,7 @@ struct subst_rule {
struct subst_rule *next;
regex_t re;
char *result;
- unsigned int global:1, print:1, symlink:1;
+ unsigned int global:1, print:1, regular:1, symlink:1, hardlink:1;
};
struct substitution {
@@ -117,9 +117,12 @@ add_substitution(struct bsdtar *bsdtar, const char *rule_text)
memcpy(rule->result, start_subst, end_pattern - start_subst);
rule->result[end_pattern - start_subst] = '\0';
- rule->global = 0;
- rule->print = 0;
- rule->symlink = 0;
+ /* Defaults */
+ rule->global = 0; /* Don't do multiple replacements. */
+ rule->print = 0; /* Don't print. */
+ rule->regular = 1; /* Rewrite regular filenames. */
+ rule->symlink = 1; /* Rewrite symlink targets. */
+ rule->hardlink = 1; /* Rewrite hardlink targets. */
while (*++end_pattern) {
switch (*end_pattern) {
@@ -127,14 +130,28 @@ add_substitution(struct bsdtar *bsdtar, const char *rule_text)
case 'G':
rule->global = 1;
break;
+ case 'h':
+ rule->hardlink = 1;
+ break;
+ case 'H':
+ rule->hardlink = 0;
+ break;
case 'p':
case 'P':
rule->print = 1;
break;
+ case 'r':
+ rule->regular = 1;
+ break;
+ case 'R':
+ rule->regular = 0;
+ break;
case 's':
- case 'S':
rule->symlink = 1;
break;
+ case 'S':
+ rule->symlink = 0;
+ break;
default:
lafe_errc(1, 0, "Invalid replacement flag %c", *end_pattern);
}
@@ -155,7 +172,8 @@ realloc_strncat(char **str, const char *append, size_t len)
new_str = malloc(old_len + len + 1);
if (new_str == NULL)
lafe_errc(1, errno, "Out of memory");
- memcpy(new_str, *str, old_len);
+ if (*str != NULL)
+ memcpy(new_str, *str, old_len);
memcpy(new_str + old_len, append, len);
new_str[old_len + len] = '\0';
free(*str);
@@ -176,14 +194,16 @@ realloc_strcat(char **str, const char *append)
new_str = malloc(old_len + strlen(append) + 1);
if (new_str == NULL)
lafe_errc(1, errno, "Out of memory");
- memcpy(new_str, *str, old_len);
+ if (*str != NULL)
+ memcpy(new_str, *str, old_len);
strcpy(new_str + old_len, append);
free(*str);
*str = new_str;
}
int
-apply_substitution(struct bsdtar *bsdtar, const char *name, char **result, int symlink_only)
+apply_substitution(struct bsdtar *bsdtar, const char *name, char **result,
+ int symlink_target, int hardlink_target)
{
const char *path = name;
regmatch_t matches[10];
@@ -201,8 +221,17 @@ apply_substitution(struct bsdtar *bsdtar, const char *name, char **result, int s
print_match = 0;
for (rule = subst->first_rule; rule != NULL; rule = rule->next) {
- if (symlink_only && !rule->symlink)
- continue;
+ if (symlink_target) {
+ if (!rule->symlink)
+ continue;
+ } else if (hardlink_target) {
+ if (!rule->hardlink)
+ continue;
+ } else { /* Regular filename. */
+ if (!rule->regular)
+ continue;
+ }
+
if (regexec(&rule->re, name, 10, matches, 0))
continue;
@@ -213,7 +242,9 @@ apply_substitution(struct bsdtar *bsdtar, const char *name, char **result, int s
for (i = 0, j = 0; rule->result[i] != '\0'; ++i) {
if (rule->result[i] == '~') {
realloc_strncat(result, rule->result + j, i - j);
- realloc_strncat(result, name, matches[0].rm_eo);
+ realloc_strncat(result,
+ name + matches[0].rm_so,
+ matches[0].rm_eo - matches[0].rm_so);
j = i + 1;
continue;
}
diff --git a/tar/test/CMakeLists.txt b/tar/test/CMakeLists.txt
index 6064e1424073..3329ff111da2 100644
--- a/tar/test/CMakeLists.txt
+++ b/tar/test/CMakeLists.txt
@@ -14,21 +14,32 @@ IF(ENABLE_TAR AND ENABLE_TEST)
test_empty_mtree.c
test_getdate.c
test_help.c
+ test_option_C_upper.c
+ test_option_H_upper.c
+ test_option_L_upper.c
+ test_option_O_upper.c
test_option_T_upper.c
+ test_option_U_upper.c
+ test_option_X_upper.c
+ test_option_b.c
+ test_option_exclude.c
+ test_option_gid_gname.c
+ test_option_k.c
+ test_option_keep_newer_files.c
+ test_option_n.c
+ test_option_newer_than.c
test_option_q.c
test_option_r.c
test_option_s.c
+ test_option_uid_uname.c
test_patterns.c
+ test_print_longpath.c
test_stdio.c
test_strip_components.c
test_symlink_dir.c
test_version.c
test_windows.c
)
- IF(WIN32 AND NOT CYGWIN)
- LIST(APPEND bsdtar_test_SOURCES ../bsdtar_windows.c)
- LIST(APPEND bsdtar_test_SOURCES ../bsdtar_windows.h)
- ENDIF(WIN32 AND NOT CYGWIN)
#
# Register target
@@ -48,7 +59,7 @@ IF(ENABLE_TAR AND ENABLE_TEST)
# test. We can use that to define the tests for cmake by
# defining a DEFINE_TEST macro and reading list.h in.
MACRO (DEFINE_TEST _testname)
- ADD_TEST_28(
+ ADD_TEST(
NAME bsdtar_${_testname}
COMMAND bsdtar_test -vv
-p $<TARGET_FILE:bsdtar>
@@ -64,4 +75,4 @@ IF(ENABLE_TAR AND ENABLE_TEST)
ADD_DEPENDENCIES(run_bsdtar_test bsdtar)
ADD_DEPENDENCIES(run_all_tests run_bsdtar_test)
-ENDIF (ENABLE_TAR AND ENABLE_TEST)
+ENDIF(ENABLE_TAR AND ENABLE_TEST)
diff --git a/tar/test/main.c b/tar/test/main.c
index 4f8309e59c65..b85940bf4b32 100644
--- a/tar/test/main.c
+++ b/tar/test/main.c
@@ -24,8 +24,18 @@
*/
#include "test.h"
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
#include <errno.h>
+#ifdef HAVE_ICONV_H
+#include <iconv.h>
+#endif
+#include <limits.h>
#include <locale.h>
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
#include <stdarg.h>
#include <time.h>
@@ -40,8 +50,10 @@ __FBSDID("$FreeBSD: src/usr.bin/tar/test/main.c,v 1.6 2008/11/05 06:40:53 kientz
#define KNOWNREF "test_patterns_2.tar.uu"
#define ENVBASE "BSDTAR" /* Prefix for environment variables. */
#define PROGRAM "bsdtar" /* Name of program being tested. */
-#undef LIBRARY /* Not testing a library. */
-#undef EXTRA_DUMP /* How to dump extra data */
+#define PROGRAM_ALIAS "tar" /* Generic alias for program */
+#undef LIBRARY /* Not testing a library. */
+#undef EXTRA_DUMP /* How to dump extra data */
+#undef EXTRA_ERRNO /* How to dump errno */
/* How to generate extra version info. */
#define EXTRA_VERSION (systemf("%s --version", testprog) ? "" : "")
@@ -151,7 +163,7 @@ my_GetFileInformationByName(const char *path, BY_HANDLE_FILE_INFORMATION *bhfi)
memset(bhfi, 0, sizeof(*bhfi));
h = CreateFile(path, FILE_READ_ATTRIBUTES, 0, NULL,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (h == INVALID_HANDLE_VALUE)
return (0);
r = GetFileInformationByHandle(h, bhfi);
@@ -180,6 +192,8 @@ invalid_parameter_handler(const wchar_t * expression,
static int dump_on_failure = 0;
/* Default is to remove temp dirs and log data for successful tests. */
static int keep_temp_files = 0;
+/* Default is to run the specified tests once and report errors. */
+static int until_failure = 0;
/* Default is to just report pass/fail for each test. */
static int verbosity = 0;
#define VERBOSITY_SUMMARY_ONLY -1 /* -q */
@@ -237,10 +251,14 @@ void
failure(const char *fmt, ...)
{
va_list ap;
- va_start(ap, fmt);
- vsprintf(msgbuff, fmt, ap);
- va_end(ap);
- nextmsg = msgbuff;
+ if (fmt == NULL) {
+ nextmsg = NULL;
+ } else {
+ va_start(ap, fmt);
+ vsprintf(msgbuff, fmt, ap);
+ va_end(ap);
+ nextmsg = msgbuff;
+ }
}
/*
@@ -252,15 +270,14 @@ failure(const char *fmt, ...)
* pass __FILE__, __LINE__ directly into the function instead of using
* this hook. I suspect this machinery is used so rarely that we
* would be better off just removing it entirely. That would simplify
- * the code here noticably.
+ * the code here noticeably.
*/
-static const char *test_filename;
-static int test_line;
-static void *test_extra;
-void assertion_setup(const char *filename, int line)
+static const char *skipping_filename;
+static int skipping_line;
+void skipping_setup(const char *filename, int line)
{
- test_filename = filename;
- test_line = line;
+ skipping_filename = filename;
+ skipping_line = line;
}
/* Called at the beginning of each assert() function. */
@@ -287,6 +304,7 @@ static struct line {
int count;
int skip;
} failed_lines[10000];
+const char *failed_filename;
/* Count this failure, setup up log destination and handle initial report. */
static void
@@ -296,19 +314,16 @@ failure_start(const char *filename, int line, const char *fmt, ...)
/* Record another failure for this line. */
++failures;
- /* test_filename = filename; */
+ failed_filename = filename;
failed_lines[line].count++;
/* Determine whether to log header to console. */
switch (verbosity) {
- case VERBOSITY_FULL:
- log_console = 1;
- break;
case VERBOSITY_LIGHT_REPORT:
log_console = (failed_lines[line].count < 2);
break;
default:
- log_console = 0;
+ log_console = (verbosity >= VERBOSITY_FULL);
}
/* Log file:line header for this failure */
@@ -344,14 +359,16 @@ failure_finish(void *extra)
{
(void)extra; /* UNUSED (maybe) */
#ifdef EXTRA_DUMP
- if (extra != NULL)
+ if (extra != NULL) {
+ logprintf(" errno: %d\n", EXTRA_ERRNO(extra));
logprintf(" detail: %s\n", EXTRA_DUMP(extra));
+ }
#endif
if (dump_on_failure) {
fprintf(stderr,
" *** forcing core dump so failure can be debugged ***\n");
- *(char *)(NULL) = 0;
+ abort();
exit(1);
}
}
@@ -366,12 +383,15 @@ test_skipping(const char *fmt, ...)
va_start(ap, fmt);
vsprintf(buff, fmt, ap);
va_end(ap);
+ /* Use failure() message if set. */
+ msg = nextmsg;
+ nextmsg = NULL;
/* failure_start() isn't quite right, but is awfully convenient. */
- failure_start(test_filename, test_line, "SKIPPING: %s", buff);
+ failure_start(skipping_filename, skipping_line, "SKIPPING: %s", buff);
--failures; /* Undo failures++ in failure_start() */
/* Don't failure_finish() here. */
/* Mark as skip, so doesn't count as failed test. */
- failed_lines[test_line].skip = 1;
+ failed_lines[skipping_line].skip = 1;
++skips;
}
@@ -422,13 +442,102 @@ assertion_equal_int(const char *file, int line,
return (0);
}
-static void strdump(const char *e, const char *p)
+/*
+ * Utility to convert a single UTF-8 sequence.
+ */
+static int
+_utf8_to_unicode(uint32_t *pwc, const char *s, size_t n)
+{
+ static const char utf8_count[256] = {
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 00 - 0F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 10 - 1F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 20 - 2F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 30 - 3F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40 - 4F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 50 - 5F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 60 - 6F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 70 - 7F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 80 - 8F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 90 - 9F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* A0 - AF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* B0 - BF */
+ 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,/* C0 - CF */
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,/* D0 - DF */
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,/* E0 - EF */
+ 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* F0 - FF */
+ };
+ int ch;
+ int cnt;
+ uint32_t wc;
+
+ *pwc = 0;
+
+ /* Sanity check. */
+ if (n == 0)
+ return (0);
+ /*
+ * Decode 1-4 bytes depending on the value of the first byte.
+ */
+ ch = (unsigned char)*s;
+ if (ch == 0)
+ return (0); /* Standard: return 0 for end-of-string. */
+ cnt = utf8_count[ch];
+
+ /* Invalide sequence or there are not plenty bytes. */
+ if (n < (size_t)cnt)
+ return (-1);
+
+ /* Make a Unicode code point from a single UTF-8 sequence. */
+ switch (cnt) {
+ case 1: /* 1 byte sequence. */
+ *pwc = ch & 0x7f;
+ return (cnt);
+ case 2: /* 2 bytes sequence. */
+ if ((s[1] & 0xc0) != 0x80) return (-1);
+ *pwc = ((ch & 0x1f) << 6) | (s[1] & 0x3f);
+ return (cnt);
+ case 3: /* 3 bytes sequence. */
+ if ((s[1] & 0xc0) != 0x80) return (-1);
+ if ((s[2] & 0xc0) != 0x80) return (-1);
+ wc = ((ch & 0x0f) << 12)
+ | ((s[1] & 0x3f) << 6)
+ | (s[2] & 0x3f);
+ if (wc < 0x800)
+ return (-1);/* Overlong sequence. */
+ break;
+ case 4: /* 4 bytes sequence. */
+ if (n < 4)
+ return (-1);
+ if ((s[1] & 0xc0) != 0x80) return (-1);
+ if ((s[2] & 0xc0) != 0x80) return (-1);
+ if ((s[3] & 0xc0) != 0x80) return (-1);
+ wc = ((ch & 0x07) << 18)
+ | ((s[1] & 0x3f) << 12)
+ | ((s[2] & 0x3f) << 6)
+ | (s[3] & 0x3f);
+ if (wc < 0x10000)
+ return (-1);/* Overlong sequence. */
+ break;
+ default:
+ return (-1);
+ }
+
+ /* The code point larger than 0x10FFFF is not leagal
+ * Unicode values. */
+ if (wc > 0x10FFFF)
+ return (-1);
+ /* Correctly gets a Unicode, returns used bytes. */
+ *pwc = wc;
+ return (cnt);
+}
+
+static void strdump(const char *e, const char *p, int ewidth, int utf8)
{
const char *q = p;
- logprintf(" %s = ", e);
+ logprintf(" %*s = ", ewidth, e);
if (p == NULL) {
- logprintf("NULL");
+ logprintf("NULL\n");
return;
}
logprintf("\"");
@@ -447,7 +556,37 @@ static void strdump(const char *e, const char *p)
}
}
logprintf("\"");
- logprintf(" (length %d)\n", q == NULL ? -1 : (int)strlen(q));
+ logprintf(" (length %d)", q == NULL ? -1 : (int)strlen(q));
+
+ /*
+ * If the current string is UTF-8, dump its code points.
+ */
+ if (utf8) {
+ size_t len;
+ uint32_t uc;
+ int n;
+ int cnt = 0;
+
+ p = q;
+ len = strlen(p);
+ logprintf(" [");
+ while ((n = _utf8_to_unicode(&uc, p, len)) > 0) {
+ if (p != q)
+ logprintf(" ");
+ logprintf("%04X", uc);
+ p += n;
+ len -= n;
+ cnt++;
+ }
+ logprintf("]");
+ logprintf(" (count %d", cnt);
+ if (n < 0) {
+ logprintf(",unknown %d bytes", len);
+ }
+ logprintf(")");
+
+ }
+ logprintf("\n");
}
/* Verify two strings are equal, dump them if not. */
@@ -455,14 +594,20 @@ int
assertion_equal_string(const char *file, int line,
const char *v1, const char *e1,
const char *v2, const char *e2,
- void *extra)
+ void *extra, int utf8)
{
+ int l1, l2;
+
assertion_count(file, line);
if (v1 == v2 || (v1 != NULL && v2 != NULL && strcmp(v1, v2) == 0))
return (1);
failure_start(file, line, "%s != %s", e1, e2);
- strdump(e1, v1);
- strdump(e2, v2);
+ l1 = strlen(e1);
+ l2 = strlen(e2);
+ if (l1 < l2)
+ l1 = l2;
+ strdump(e1, v1, l1, utf8);
+ strdump(e2, v2, l1, utf8);
failure_finish(extra);
return (0);
}
@@ -514,7 +659,9 @@ assertion_equal_wstring(const char *file, int line,
void *extra)
{
assertion_count(file, line);
- if (v1 == v2 || wcscmp(v1, v2) == 0)
+ if (v1 == v2)
+ return (1);
+ if (v1 != NULL && v2 != NULL && wcscmp(v1, v2) == 0)
return (1);
failure_start(file, line, "%s != %s", e1, e2);
wcsdump(e1, v1);
@@ -593,9 +740,9 @@ assertion_equal_mem(const char *file, int line,
offset += 16;
}
logprintf(" Dump of %s\n", e1);
- hexdump(v1, v2, l < 64 ? l : 64, offset);
+ hexdump(v1, v2, l < 128 ? l : 128, offset);
logprintf(" Dump of %s\n", e2);
- hexdump(v2, v1, l < 64 ? l : 64, offset);
+ hexdump(v2, v1, l < 128 ? l : 128, offset);
logprintf("\n");
failure_finish(extra);
return (0);
@@ -603,29 +750,24 @@ assertion_equal_mem(const char *file, int line,
/* Verify that the named file exists and is empty. */
int
-assertion_empty_file(const char *f1fmt, ...)
+assertion_empty_file(const char *filename, int line, const char *f1)
{
char buff[1024];
- char f1[1024];
struct stat st;
- va_list ap;
ssize_t s;
FILE *f;
- assertion_count(test_filename, test_line);
- va_start(ap, f1fmt);
- vsprintf(f1, f1fmt, ap);
- va_end(ap);
+ assertion_count(filename, line);
if (stat(f1, &st) != 0) {
- failure_start(test_filename, test_line, "Stat failed: %s", f1);
+ failure_start(filename, line, "Stat failed: %s", f1);
failure_finish(NULL);
return (0);
}
if (st.st_size == 0)
return (1);
- failure_start(test_filename, test_line, "File should be empty: %s", f1);
+ failure_start(filename, line, "File should be empty: %s", f1);
logprintf(" File size: %d\n", (int)st.st_size);
logprintf(" Contents:\n");
f = fopen(f1, "rb");
@@ -644,24 +786,19 @@ assertion_empty_file(const char *f1fmt, ...)
/* Verify that the named file exists and is not empty. */
int
-assertion_non_empty_file(const char *f1fmt, ...)
+assertion_non_empty_file(const char *filename, int line, const char *f1)
{
- char f1[1024];
struct stat st;
- va_list ap;
- assertion_count(test_filename, test_line);
- va_start(ap, f1fmt);
- vsprintf(f1, f1fmt, ap);
- va_end(ap);
+ assertion_count(filename, line);
if (stat(f1, &st) != 0) {
- failure_start(test_filename, test_line, "Stat failed: %s", f1);
+ failure_start(filename, line, "Stat failed: %s", f1);
failure_finish(NULL);
return (0);
}
if (st.st_size == 0) {
- failure_start(test_filename, test_line, "File empty: %s", f1);
+ failure_start(filename, line, "File empty: %s", f1);
failure_finish(NULL);
return (0);
}
@@ -671,19 +808,14 @@ assertion_non_empty_file(const char *f1fmt, ...)
/* Verify that two files have the same contents. */
/* TODO: hexdump the first bytes that actually differ. */
int
-assertion_equal_file(const char *fn1, const char *f2pattern, ...)
+assertion_equal_file(const char *filename, int line, const char *fn1, const char *fn2)
{
- char fn2[1024];
- va_list ap;
char buff1[1024];
char buff2[1024];
FILE *f1, *f2;
int n1, n2;
- assertion_count(test_filename, test_line);
- va_start(ap, f2pattern);
- vsprintf(fn2, f2pattern, ap);
- va_end(ap);
+ assertion_count(filename, line);
f1 = fopen(fn1, "rb");
f2 = fopen(fn2, "rb");
@@ -702,24 +834,18 @@ assertion_equal_file(const char *fn1, const char *f2pattern, ...)
}
fclose(f1);
fclose(f2);
- failure_start(test_filename, test_line, "Files not identical");
+ failure_start(filename, line, "Files not identical");
logprintf(" file1=\"%s\"\n", fn1);
logprintf(" file2=\"%s\"\n", fn2);
- failure_finish(test_extra);
+ failure_finish(NULL);
return (0);
}
/* Verify that the named file does exist. */
int
-assertion_file_exists(const char *fpattern, ...)
+assertion_file_exists(const char *filename, int line, const char *f)
{
- char f[1024];
- va_list ap;
-
- assertion_count(test_filename, test_line);
- va_start(ap, fpattern);
- vsprintf(f, fpattern, ap);
- va_end(ap);
+ assertion_count(filename, line);
#if defined(_WIN32) && !defined(__CYGWIN__)
if (!_access(f, 0))
@@ -728,22 +854,16 @@ assertion_file_exists(const char *fpattern, ...)
if (!access(f, F_OK))
return (1);
#endif
- failure_start(test_filename, test_line, "File should exist: %s", f);
- failure_finish(test_extra);
+ failure_start(filename, line, "File should exist: %s", f);
+ failure_finish(NULL);
return (0);
}
/* Verify that the named file doesn't exist. */
int
-assertion_file_not_exists(const char *fpattern, ...)
+assertion_file_not_exists(const char *filename, int line, const char *f)
{
- char f[1024];
- va_list ap;
-
- assertion_count(test_filename, test_line);
- va_start(ap, fpattern);
- vsprintf(f, fpattern, ap);
- va_end(ap);
+ assertion_count(filename, line);
#if defined(_WIN32) && !defined(__CYGWIN__)
if (_access(f, 0))
@@ -752,31 +872,26 @@ assertion_file_not_exists(const char *fpattern, ...)
if (access(f, F_OK))
return (1);
#endif
- failure_start(test_filename, test_line, "File should not exist: %s", f);
- failure_finish(test_extra);
+ failure_start(filename, line, "File should not exist: %s", f);
+ failure_finish(NULL);
return (0);
}
/* Compare the contents of a file to a block of memory. */
int
-assertion_file_contents(const void *buff, int s, const char *fpattern, ...)
+assertion_file_contents(const char *filename, int line, const void *buff, int s, const char *fn)
{
- char fn[1024];
- va_list ap;
char *contents;
FILE *f;
int n;
- assertion_count(test_filename, test_line);
- va_start(ap, fpattern);
- vsprintf(fn, fpattern, ap);
- va_end(ap);
+ assertion_count(filename, line);
f = fopen(fn, "rb");
if (f == NULL) {
- failure_start(test_filename, test_line,
+ failure_start(filename, line,
"File should exist: %s", fn);
- failure_finish(test_extra);
+ failure_finish(NULL);
return (0);
}
contents = malloc(s * 2);
@@ -786,7 +901,7 @@ assertion_file_contents(const void *buff, int s, const char *fpattern, ...)
free(contents);
return (1);
}
- failure_start(test_filename, test_line, "File contents don't match");
+ failure_start(filename, line, "File contents don't match");
logprintf(" file=\"%s\"\n", fn);
if (n > 0)
hexdump(contents, buff, n > 512 ? 512 : n, 0);
@@ -794,22 +909,28 @@ assertion_file_contents(const void *buff, int s, const char *fpattern, ...)
logprintf(" File empty, contents should be:\n");
hexdump(buff, NULL, s > 512 ? 512 : s, 0);
}
- failure_finish(test_extra);
+ failure_finish(NULL);
free(contents);
return (0);
}
/* Check the contents of a text file, being tolerant of line endings. */
int
-assertion_text_file_contents(const char *buff, const char *fn)
+assertion_text_file_contents(const char *filename, int line, const char *buff, const char *fn)
{
char *contents;
const char *btxt, *ftxt;
FILE *f;
int n, s;
- assertion_count(test_filename, test_line);
+ assertion_count(filename, line);
f = fopen(fn, "r");
+ if (f == NULL) {
+ failure_start(filename, line,
+ "File doesn't exist: %s", fn);
+ failure_finish(NULL);
+ return (0);
+ }
s = strlen(buff);
contents = malloc(s * 2 + 128);
n = fread(contents, 1, s * 2 + 128 - 1, f);
@@ -837,15 +958,17 @@ assertion_text_file_contents(const char *buff, const char *fn)
free(contents);
return (1);
}
- failure_start(test_filename, test_line, "Contents don't match");
+ failure_start(filename, line, "Contents don't match");
logprintf(" file=\"%s\"\n", fn);
- if (n > 0)
+ if (n > 0) {
hexdump(contents, buff, n, 0);
- else {
+ logprintf(" expected\n", fn);
+ hexdump(buff, contents, s, 0);
+ } else {
logprintf(" File empty, contents should be:\n");
hexdump(buff, NULL, s, 0);
}
- failure_finish(test_extra);
+ failure_finish(NULL);
free(contents);
return (0);
}
@@ -875,7 +998,7 @@ assertion_file_contains_lines_any_order(const char *file, int line,
return (0);
}
- // Make a copy of the provided lines and count up the expected file size.
+ /* Make a copy of the provided lines and count up the expected file size. */
expected_count = 0;
for (i = 0; lines[i] != NULL; ++i) {
}
@@ -885,7 +1008,7 @@ assertion_file_contains_lines_any_order(const char *file, int line,
expected[i] = strdup(lines[i]);
}
- // Break the file into lines
+ /* Break the file into lines */
actual_count = 0;
for (c = '\0', p = buff; p < buff + buff_size; ++p) {
if (*p == '\x0d' || *p == '\x0a')
@@ -902,7 +1025,7 @@ assertion_file_contains_lines_any_order(const char *file, int line,
}
}
- // Erase matching lines from both lists
+ /* Erase matching lines from both lists */
for (i = 0; i < expected_count; ++i) {
if (expected[i] == NULL)
continue;
@@ -918,7 +1041,7 @@ assertion_file_contains_lines_any_order(const char *file, int line,
}
}
- // If there's anything left, it's a failure
+ /* If there's anything left, it's a failure */
for (i = 0; i < expected_count; ++i) {
if (expected[i] != NULL)
++expected_failure;
@@ -1040,8 +1163,11 @@ assertion_file_time(const char *file, int line,
ftime.dwHighDateTime = 0;
assertion_count(file, line);
+ /* Note: FILE_FLAG_BACKUP_SEMANTICS applies to open
+ * a directory file. If not, CreateFile() will fail when
+ * the pathname is a directory. */
h = CreateFile(pathname, FILE_READ_ATTRIBUTES, 0, NULL,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (h == INVALID_HANDLE_VALUE) {
failure_start(file, line, "Can't access %s\n", pathname);
failure_finish(NULL);
@@ -1106,14 +1232,14 @@ assertion_file_time(const char *file, int line,
time_t now = time(NULL);
if (filet < now - 10 || filet > now + 1) {
failure_start(file, line,
- "File %s has %ctime %ld, %ld seconds ago\n",
+ "File %s has %ctime %lld, %lld seconds ago\n",
pathname, type, filet, now - filet);
failure_finish(NULL);
return (0);
}
} else if (filet != t || filet_nsec != nsec) {
failure_start(file, line,
- "File %s has %ctime %ld.%09ld, expected %ld.%09ld",
+ "File %s has %ctime %lld.%09lld, expected %lld.%09lld",
pathname, type, filet, filet_nsec, t, nsec);
failure_finish(NULL);
return (0);
@@ -1486,6 +1612,110 @@ assertion_umask(const char *file, int line, int mask)
return (1);
}
+/* Set times, report failures. */
+int
+assertion_utimes(const char *file, int line,
+ const char *pathname, long at, long at_nsec, long mt, long mt_nsec)
+{
+ int r;
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#define WINTIME(sec, nsec) ((Int32x32To64(sec, 10000000) + EPOC_TIME)\
+ + (((nsec)/1000)*10))
+ HANDLE h;
+ ULARGE_INTEGER wintm;
+ FILETIME fatime, fmtime;
+ FILETIME *pat, *pmt;
+
+ assertion_count(file, line);
+ h = CreateFileA(pathname,GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (h == INVALID_HANDLE_VALUE) {
+ failure_start(file, line, "Can't access %s\n", pathname);
+ failure_finish(NULL);
+ return (0);
+ }
+
+ if (at > 0 || at_nsec > 0) {
+ wintm.QuadPart = WINTIME(at, at_nsec);
+ fatime.dwLowDateTime = wintm.LowPart;
+ fatime.dwHighDateTime = wintm.HighPart;
+ pat = &fatime;
+ } else
+ pat = NULL;
+ if (mt > 0 || mt_nsec > 0) {
+ wintm.QuadPart = WINTIME(mt, mt_nsec);
+ fmtime.dwLowDateTime = wintm.LowPart;
+ fmtime.dwHighDateTime = wintm.HighPart;
+ pmt = &fmtime;
+ } else
+ pmt = NULL;
+ if (pat != NULL || pmt != NULL)
+ r = SetFileTime(h, NULL, pat, pmt);
+ else
+ r = 1;
+ CloseHandle(h);
+ if (r == 0) {
+ failure_start(file, line, "Can't SetFileTime %s\n", pathname);
+ failure_finish(NULL);
+ return (0);
+ }
+ return (1);
+#else /* defined(_WIN32) && !defined(__CYGWIN__) */
+ struct stat st;
+ struct timeval times[2];
+
+#if !defined(__FreeBSD__)
+ mt_nsec = at_nsec = 0; /* Generic POSIX only has whole seconds. */
+#endif
+ if (mt == 0 && mt_nsec == 0 && at == 0 && at_nsec == 0)
+ return (1);
+
+ r = lstat(pathname, &st);
+ if (r < 0) {
+ failure_start(file, line, "Can't stat %s\n", pathname);
+ failure_finish(NULL);
+ return (0);
+ }
+
+ if (mt == 0 && mt_nsec == 0) {
+ mt = st.st_mtime;
+#if defined(__FreeBSD__)
+ mt_nsec = st.st_mtimespec.tv_nsec;
+ /* FreeBSD generally only stores to microsecond res, so round. */
+ mt_nsec = (mt_nsec / 1000) * 1000;
+#endif
+ }
+ if (at == 0 && at_nsec == 0) {
+ at = st.st_atime;
+#if defined(__FreeBSD__)
+ at_nsec = st.st_atimespec.tv_nsec;
+ /* FreeBSD generally only stores to microsecond res, so round. */
+ at_nsec = (at_nsec / 1000) * 1000;
+#endif
+ }
+
+ times[1].tv_sec = mt;
+ times[1].tv_usec = mt_nsec / 1000;
+
+ times[0].tv_sec = at;
+ times[0].tv_usec = at_nsec / 1000;
+
+#ifdef HAVE_LUTIMES
+ r = lutimes(pathname, times);
+#else
+ r = utimes(pathname, times);
+#endif
+ if (r < 0) {
+ failure_start(file, line, "Can't utimes %s\n", pathname);
+ failure_finish(NULL);
+ return (0);
+ }
+ return (1);
+#endif /* defined(_WIN32) && !defined(__CYGWIN__) */
+}
+
/*
*
* UTILITIES for use by tests.
@@ -1711,6 +1941,27 @@ extract_reference_file(const char *name)
fclose(in);
}
+int
+is_LargeInode(const char *file)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ BY_HANDLE_FILE_INFORMATION bhfi;
+ int r;
+
+ r = my_GetFileInformationByName(file, &bhfi);
+ if (r != 0)
+ return (0);
+ return (bhfi.nFileIndexHigh & 0x0000FFFFUL);
+#else
+ struct stat st;
+ int64_t ino;
+
+ if (stat(file, &st) < 0)
+ return (0);
+ ino = (int64_t)st.st_ino;
+ return (ino > 0xffffffff);
+#endif
+}
/*
*
* TEST management
@@ -1740,7 +1991,7 @@ struct { void (*func)(void); const char *name; int failures; } tests[] = {
* Summarize repeated failures in the just-completed test.
*/
static void
-test_summarize(const char *filename, int failed)
+test_summarize(int failed)
{
unsigned int i;
@@ -1759,9 +2010,10 @@ test_summarize(const char *filename, int failed)
for (i = 0; i < sizeof(failed_lines)/sizeof(failed_lines[0]); i++) {
if (failed_lines[i].count > 1 && !failed_lines[i].skip)
logprintf("%s:%d: Summary: Failed %d times\n",
- filename, i, failed_lines[i].count);
+ failed_filename, i, failed_lines[i].count);
}
/* Clear the failure history for the next file. */
+ failed_filename = NULL;
memset(failed_lines, 0, sizeof(failed_lines));
}
@@ -1771,6 +2023,7 @@ test_summarize(const char *filename, int failed)
static int
test_run(int i, const char *tmpdir)
{
+ char workdir[1024];
char logfilename[64];
int failures_before = failures;
int oldumask;
@@ -1797,11 +2050,12 @@ test_run(int i, const char *tmpdir)
logfile = fopen(logfilename, "w");
fprintf(logfile, "%s\n\n", tests[i].name);
/* Chdir() to a work dir for this specific test. */
- if (!assertMakeDir(tests[i].name, 0755)
- || !assertChdir(tests[i].name)) {
+ snprintf(workdir, sizeof(workdir), "%s/%s", tmpdir, tests[i].name);
+ testworkdir = workdir;
+ if (!assertMakeDir(testworkdir, 0755)
+ || !assertChdir(testworkdir)) {
fprintf(stderr,
- "ERROR: Can't chdir to work dir %s/%s\n",
- tmpdir, tests[i].name);
+ "ERROR: Can't chdir to work dir %s\n", testworkdir);
exit(1);
}
/* Explicitly reset the locale before each test. */
@@ -1815,6 +2069,7 @@ test_run(int i, const char *tmpdir)
/*
* Clean up and report afterwards.
*/
+ testworkdir = NULL;
/* Restore umask */
umask(oldumask);
/* Reset locale. */
@@ -1827,7 +2082,7 @@ test_run(int i, const char *tmpdir)
}
/* Report per-test summaries. */
tests[i].failures = failures - failures_before;
- test_summarize(test_filename, tests[i].failures);
+ test_summarize(tests[i].failures);
/* Close the per-test log file. */
fclose(logfile);
logfile = NULL;
@@ -1887,6 +2142,7 @@ usage(const char *program)
printf(" -q Quiet.\n");
printf(" -r <dir> Path to dir containing reference files.\n");
printf(" Default: Current directory.\n");
+ printf(" -u Keep running specifies tests until one fails.\n");
printf(" -v Verbose.\n");
printf("Available tests:\n");
for (i = 0; i < limit; i++)
@@ -1913,7 +2169,11 @@ get_refdir(const char *d)
}
/* Get the current dir. */
+#ifdef PATH_MAX
+ pwd = getcwd(NULL, PATH_MAX);/* Solaris getcwd needs the size. */
+#else
pwd = getcwd(NULL, 0);
+#endif
while (pwd[strlen(pwd) - 1] == '\n')
pwd[strlen(pwd) - 1] = '\0';
@@ -1940,6 +2200,14 @@ get_refdir(const char *d)
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
+#if defined(PROGRAM_ALIAS)
+ snprintf(buff, sizeof(buff), "%s/%s/test", pwd, PROGRAM_ALIAS);
+ p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
+ if (p != NULL) goto success;
+ strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
+ strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
+#endif
+
if (memcmp(pwd, "/usr/obj", 8) == 0) {
snprintf(buff, sizeof(buff), "%s", pwd + 8);
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
@@ -1972,16 +2240,26 @@ int
main(int argc, char **argv)
{
static const int limit = sizeof(tests) / sizeof(tests[0]);
- int i, tests_run = 0, tests_failed = 0, option;
+ int i = 0, j = 0, start, end, tests_run = 0, tests_failed = 0, option;
time_t now;
char *refdir_alloc = NULL;
const char *progname;
+ char **saved_argv;
const char *tmp, *option_arg, *p;
- char tmpdir[256];
+ char tmpdir[256], *pwd, *testprogdir, *tmp2 = NULL;
char tmpdir_timestamp[256];
(void)argc; /* UNUSED */
+ /* Get the current dir. */
+#ifdef PATH_MAX
+ pwd = getcwd(NULL, PATH_MAX);/* Solaris getcwd needs the size. */
+#else
+ pwd = getcwd(NULL, 0);
+#endif
+ while (pwd[strlen(pwd) - 1] == '\n')
+ pwd[strlen(pwd) - 1] = '\0';
+
#if defined(HAVE__CrtSetReportMode)
/* To stop to run the default invalid parameter handler. */
_set_invalid_parameter_handler(invalid_parameter_handler);
@@ -1994,11 +2272,35 @@ main(int argc, char **argv)
* tree.
*/
progname = p = argv[0];
+ if ((testprogdir = (char *)malloc(strlen(progname) + 1)) == NULL)
+ {
+ fprintf(stderr, "ERROR: Out of memory.");
+ exit(1);
+ }
+ strcpy(testprogdir, progname);
while (*p != '\0') {
/* Support \ or / dir separators for Windows compat. */
if (*p == '/' || *p == '\\')
+ {
progname = p + 1;
+ i = j;
+ }
++p;
+ j++;
+ }
+ testprogdir[i] = '\0';
+ if (testprogdir[0] != '/')
+ {
+ /* Fixup path for relative directories. */
+ if ((testprogdir = (char *)realloc(testprogdir,
+ strlen(pwd) + 1 + strlen(testprogdir) + 1)) == NULL)
+ {
+ fprintf(stderr, "ERROR: Out of memory.");
+ exit(1);
+ }
+ strcpy(testprogdir + strlen(pwd) + 1, testprogdir);
+ strcpy(testprogdir, pwd);
+ testprogdir[strlen(pwd)] = '/';
}
#ifdef PROGRAM
@@ -2073,6 +2375,9 @@ main(int argc, char **argv)
case 'r':
refdir = option_arg;
break;
+ case 'u':
+ until_failure++;
+ break;
case 'v':
verbosity++;
break;
@@ -2088,9 +2393,18 @@ main(int argc, char **argv)
* Sanity-check that our options make sense.
*/
#ifdef PROGRAM
- if (testprogfile == NULL) {
- fprintf(stderr, "Program executable required\n");
- usage(progname);
+ if (testprogfile == NULL)
+ {
+ if ((tmp2 = (char *)malloc(strlen(testprogdir) + 1 +
+ strlen(PROGRAM) + 1)) == NULL)
+ {
+ fprintf(stderr, "ERROR: Out of memory.");
+ exit(1);
+ }
+ strcpy(tmp2, testprogdir);
+ strcat(tmp2, "/");
+ strcat(tmp2, PROGRAM);
+ testprogfile = tmp2;
}
{
@@ -2113,6 +2427,16 @@ main(int argc, char **argv)
}
#endif
+#if !defined(_WIN32) && defined(SIGPIPE)
+ { /* Ignore SIGPIPE signals */
+ struct sigaction sa;
+ sa.sa_handler = SIG_IGN;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ sigaction(SIGPIPE, &sa, NULL);
+ }
+#endif
+
/*
* Create a temp directory for the following tests.
* Include the time the tests started as part of the name,
@@ -2165,42 +2489,88 @@ main(int argc, char **argv)
/*
* Run some or all of the individual tests.
*/
- if (*argv == NULL) {
- /* Default: Run all tests. */
- for (i = 0; i < limit; i++) {
- if (test_run(i, tmpdir))
- tests_failed++;
- tests_run++;
- }
- } else {
- while (*(argv) != NULL) {
- if (**argv >= '0' && **argv <= '9') {
- i = atoi(*argv);
- if (i < 0 || i >= limit) {
- printf("*** INVALID Test %s\n", *argv);
- free(refdir_alloc);
- usage(progname);
- /* usage() never returns */
+ saved_argv = argv;
+ do {
+ argv = saved_argv;
+ if (*argv == NULL) {
+ /* Default: Run all tests. */
+ for (i = 0; i < limit; i++) {
+ tests_run++;
+ if (test_run(i, tmpdir)) {
+ tests_failed++;
+ if (until_failure)
+ goto finish;
}
- } else {
- for (i = 0; i < limit; ++i) {
- if (strcmp(*argv, tests[i].name) == 0)
- break;
+ }
+ } else {
+ while (*(argv) != NULL) {
+ if (**argv >= '0' && **argv <= '9') {
+ char *p = *argv;
+ start = 0;
+ while (*p >= '0' && *p <= '9') {
+ start *= 10;
+ start += *p - '0';
+ ++p;
+ }
+ if (*p == '\0') {
+ end = start;
+ } else if (*p == '-') {
+ ++p;
+ if (*p == '\0') {
+ end = limit - 1;
+ } else {
+ end = 0;
+ while (*p >= '0' && *p <= '9') {
+ end *= 10;
+ end += *p - '0';
+ ++p;
+ }
+ }
+ } else {
+ printf("*** INVALID Test %s\n", *argv);
+ free(refdir_alloc);
+ usage(progname);
+ return (1);
+ }
+ if (start < 0 || end >= limit || start > end) {
+ printf("*** INVALID Test %s\n", *argv);
+ free(refdir_alloc);
+ usage(progname);
+ return (1);
+ }
+ } else {
+ for (start = 0; start < limit; ++start) {
+ if (strcmp(*argv, tests[start].name) == 0)
+ break;
+ }
+ end = start;
+ if (start >= limit) {
+ printf("*** INVALID Test ``%s''\n",
+ *argv);
+ free(refdir_alloc);
+ usage(progname);
+ /* usage() never returns */
+ }
}
- if (i >= limit) {
- printf("*** INVALID Test ``%s''\n",
- *argv);
- free(refdir_alloc);
- usage(progname);
- /* usage() never returns */
+ while (start <= end) {
+ tests_run++;
+ if (test_run(start, tmpdir)) {
+ tests_failed++;
+ if (until_failure)
+ goto finish;
+ }
+ ++start;
}
+ argv++;
}
- if (test_run(i, tmpdir))
- tests_failed++;
- tests_run++;
- argv++;
}
- }
+ } while (until_failure);
+
+finish:
+ /* Must be freed after all tests run */
+ free(tmp2);
+ free(testprogdir);
+ free(pwd);
/*
* Report summary statistics.
diff --git a/tar/test/test.h b/tar/test/test.h
index d93695925421..f8682d5a8014 100644
--- a/tar/test/test.h
+++ b/tar/test/test.h
@@ -48,9 +48,6 @@
#include <sys/types.h> /* Windows requires this before sys/stat.h */
#include <sys/stat.h>
-#ifdef USE_DMALLOC
-#include <dmalloc.h>
-#endif
#if HAVE_DIRENT_H
#include <dirent.h>
#endif
@@ -63,6 +60,9 @@
#ifdef HAVE_IO_H
#include <io.h>
#endif
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -83,13 +83,11 @@
/* Windows (including Visual Studio and MinGW but not Cygwin) */
#if defined(_WIN32) && !defined(__CYGWIN__)
-#include "../bsdtar_windows.h"
#if !defined(__BORLANDC__)
+#undef chdir
+#define chdir _chdir
#define strdup _strdup
#endif
-#define LOCALE_DE "deu"
-#else
-#define LOCALE_DE "de_DE.UTF-8"
#endif
/* Visual Studio */
@@ -97,13 +95,11 @@
#define snprintf sprintf_s
#endif
-/* Cygwin */
-#if defined(__CYGWIN__)
-/* Cygwin-1.7.x is lazy about populating nlinks, so don't
- * expect it to be accurate. */
-# define NLINKS_INACCURATE_FOR_DIRS
+#if defined(__BORLANDC__)
+#pragma warn -8068 /* Constant out of range in comparison. */
#endif
+/* Haiku OS and QNX */
#if defined(__HAIKU__) || defined(__QNXNTO__)
/* Haiku and QNX have typedefs in stdint.h (needed for int64_t) */
#include <stdint.h>
@@ -139,24 +135,24 @@
assertion_equal_int(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
/* Assert two strings are the same. Reports value of each one if not. */
#define assertEqualString(v1,v2) \
- assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
+ assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL, 0)
+#define assertEqualUTF8String(v1,v2) \
+ assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL, 1)
/* As above, but v1 and v2 are wchar_t * */
#define assertEqualWString(v1,v2) \
assertion_equal_wstring(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
/* As above, but raw blocks of bytes. */
#define assertEqualMem(v1, v2, l) \
assertion_equal_mem(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (l), #l, NULL)
-/* Assert two files are the same; allow printf-style expansion of second name.
- * See below for comments about variable arguments here...
- */
-#define assertEqualFile \
- assertion_setup(__FILE__, __LINE__);assertion_equal_file
-/* Assert that a file is empty; supports printf-style arguments. */
-#define assertEmptyFile \
- assertion_setup(__FILE__, __LINE__);assertion_empty_file
-/* Assert that a file is not empty; supports printf-style arguments. */
-#define assertNonEmptyFile \
- assertion_setup(__FILE__, __LINE__);assertion_non_empty_file
+/* Assert two files are the same. */
+#define assertEqualFile(f1, f2) \
+ assertion_equal_file(__FILE__, __LINE__, (f1), (f2))
+/* Assert that a file is empty. */
+#define assertEmptyFile(pathname) \
+ assertion_empty_file(__FILE__, __LINE__, (pathname))
+/* Assert that a file is not empty. */
+#define assertNonEmptyFile(pathname) \
+ assertion_non_empty_file(__FILE__, __LINE__, (pathname))
#define assertFileAtime(pathname, sec, nsec) \
assertion_file_atime(__FILE__, __LINE__, pathname, sec, nsec)
#define assertFileAtimeRecent(pathname) \
@@ -166,14 +162,14 @@
#define assertFileBirthtimeRecent(pathname) \
assertion_file_birthtime_recent(__FILE__, __LINE__, pathname)
/* Assert that a file exists; supports printf-style arguments. */
-#define assertFileExists \
- assertion_setup(__FILE__, __LINE__);assertion_file_exists
-/* Assert that a file exists; supports printf-style arguments. */
-#define assertFileNotExists \
- assertion_setup(__FILE__, __LINE__);assertion_file_not_exists
-/* Assert that file contents match a string; supports printf-style arguments. */
-#define assertFileContents \
- assertion_setup(__FILE__, __LINE__);assertion_file_contents
+#define assertFileExists(pathname) \
+ assertion_file_exists(__FILE__, __LINE__, pathname)
+/* Assert that a file exists. */
+#define assertFileNotExists(pathname) \
+ assertion_file_not_exists(__FILE__, __LINE__, pathname)
+/* Assert that file contents match a string. */
+#define assertFileContents(data, data_size, pathname) \
+ assertion_file_contents(__FILE__, __LINE__, data, data_size, pathname)
#define assertFileMtime(pathname, sec, nsec) \
assertion_file_mtime(__FILE__, __LINE__, pathname, sec, nsec)
#define assertFileMtimeRecent(pathname) \
@@ -182,10 +178,10 @@
assertion_file_nlinks(__FILE__, __LINE__, pathname, nlinks)
#define assertFileSize(pathname, size) \
assertion_file_size(__FILE__, __LINE__, pathname, size)
-#define assertTextFileContents \
- assertion_setup(__FILE__, __LINE__);assertion_text_file_contents
+#define assertTextFileContents(text, pathname) \
+ assertion_text_file_contents(__FILE__, __LINE__, text, pathname)
#define assertFileContainsLinesAnyOrder(pathname, lines) \
- assertion_file_contains_lines_any_order(__FILE__, __LINE__, pathname, lines)
+ assertion_file_contains_lines_any_order(__FILE__, __LINE__, pathname, lines)
#define assertIsDir(pathname, mode) \
assertion_is_dir(__FILE__, __LINE__, pathname, mode)
#define assertIsHardlink(path1, path2) \
@@ -207,6 +203,8 @@
assertion_make_symlink(__FILE__, __LINE__, newfile, linkto)
#define assertUmask(mask) \
assertion_umask(__FILE__, __LINE__, mask)
+#define assertUtimes(pathname, atime, atime_nsec, mtime, mtime_nsec) \
+ assertion_utimes(__FILE__, __LINE__, pathname, atime, atime_nsec, mtime, mtime_nsec)
/*
* This would be simple with C99 variadic macros, but I don't want to
@@ -215,29 +213,29 @@
* but effective.
*/
#define skipping \
- assertion_setup(__FILE__, __LINE__);test_skipping
+ skipping_setup(__FILE__, __LINE__);test_skipping
/* Function declarations. These are defined in test_utility.c. */
void failure(const char *fmt, ...);
int assertion_assert(const char *, int, int, const char *, void *);
int assertion_chdir(const char *, int, const char *);
-int assertion_empty_file(const char *, ...);
-int assertion_equal_file(const char *, const char *, ...);
+int assertion_empty_file(const char *, int, const char *);
+int assertion_equal_file(const char *, int, const char *, const char *);
int assertion_equal_int(const char *, int, long long, const char *, long long, const char *, void *);
int assertion_equal_mem(const char *, int, const void *, const char *, const void *, const char *, size_t, const char *, void *);
-int assertion_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *);
+int assertion_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *, int);
int assertion_equal_wstring(const char *, int, const wchar_t *v1, const char *, const wchar_t *v2, const char *, void *);
int assertion_file_atime(const char *, int, const char *, long, long);
int assertion_file_atime_recent(const char *, int, const char *);
int assertion_file_birthtime(const char *, int, const char *, long, long);
int assertion_file_birthtime_recent(const char *, int, const char *);
int assertion_file_contains_lines_any_order(const char *, int, const char *, const char **);
-int assertion_file_contents(const void *, int, const char *, ...);
-int assertion_file_exists(const char *, ...);
+int assertion_file_contents(const char *, int, const void *, int, const char *);
+int assertion_file_exists(const char *, int, const char *);
int assertion_file_mtime(const char *, int, const char *, long, long);
int assertion_file_mtime_recent(const char *, int, const char *);
int assertion_file_nlinks(const char *, int, const char *, int);
-int assertion_file_not_exists(const char *, ...);
+int assertion_file_not_exists(const char *, int, const char *);
int assertion_file_size(const char *, int, const char *, long);
int assertion_is_dir(const char *, int, const char *, int);
int assertion_is_hardlink(const char *, int, const char *, const char *);
@@ -248,11 +246,12 @@ int assertion_make_dir(const char *, int, const char *, int);
int assertion_make_file(const char *, int, const char *, int, const char *);
int assertion_make_hardlink(const char *, int, const char *newpath, const char *);
int assertion_make_symlink(const char *, int, const char *newpath, const char *);
-int assertion_non_empty_file(const char *, ...);
-int assertion_text_file_contents(const char *buff, const char *f);
+int assertion_non_empty_file(const char *, int, const char *);
+int assertion_text_file_contents(const char *, int, const char *buff, const char *f);
int assertion_umask(const char *, int, int);
-void assertion_setup(const char *, int);
+int assertion_utimes(const char *, int, const char *, long, long, long, long );
+void skipping_setup(const char *, int);
void test_skipping(const char *fmt, ...);
/* Like sprintf, then system() */
@@ -270,6 +269,9 @@ int canGzip(void);
/* Return true if this platform can run the "gunzip" program. */
int canGunzip(void);
+/* Return true if the file has large i-node number(>0xffffffff). */
+int is_LargeInode(const char *);
+
/* Suck file into string allocated via malloc(). Call free() when done. */
/* Supports printf-style args: slurpfile(NULL, "%s/myfile", refdir); */
char *slurpfile(size_t *, const char *fmt, ...);
@@ -277,6 +279,9 @@ char *slurpfile(size_t *, const char *fmt, ...);
/* Extracts named reference file to the current directory. */
void extract_reference_file(const char *);
+/* Path to working directory for current test */
+const char *testworkdir;
+
/*
* Special interfaces for program test harness.
*/
@@ -286,3 +291,7 @@ const char *testprogfile;
/* Name of exe to use in printf-formatted command strings. */
/* On Windows, this includes leading/trailing quotes. */
const char *testprog;
+
+#ifdef USE_DMALLOC
+#include <dmalloc.h>
+#endif
diff --git a/tar/test/test_0.c b/tar/test/test_0.c
index c9277da16bc9..b73c7a3f4fab 100644
--- a/tar/test/test_0.c
+++ b/tar/test/test_0.c
@@ -40,15 +40,23 @@ DEFINE_TEST(test_0)
struct stat st;
failure("File %s does not exist?!", testprog);
- if (!assertEqualInt(0, stat(testprogfile, &st)))
+ if (!assertEqualInt(0, stat(testprogfile, &st))) {
+ fprintf(stderr,
+ "\nFile %s does not exist; aborting test.\n\n",
+ testprog);
exit(1);
+ }
failure("%s is not executable?!", testprog);
- if (!assert((st.st_mode & 0111) != 0))
+ if (!assert((st.st_mode & 0111) != 0)) {
+ fprintf(stderr,
+ "\nFile %s not executable; aborting test.\n\n",
+ testprog);
exit(1);
+ }
/*
- * Try to succesfully run the program; this requires that
+ * Try to successfully run the program; this requires that
* we know some option that will succeed.
*/
if (0 == systemf("%s --version >" DEV_NULL, testprog)) {
diff --git a/tar/test/test_basic.c b/tar/test/test_basic.c
index 4dc7cf6364f4..8832787ee63d 100644
--- a/tar/test/test_basic.c
+++ b/tar/test/test_basic.c
@@ -25,48 +25,49 @@
#include "test.h"
__FBSDID("$FreeBSD: src/usr.bin/tar/test/test_basic.c,v 1.2 2008/05/26 17:10:10 kientzle Exp $");
-
-static void
-basic_tar(const char *target, const char *pack_options,
- const char *unpack_options, const char *flist)
+static const char *
+make_files(void)
{
- int r;
-
- assertMakeDir(target, 0775);
+ FILE *f;
- /* Use the tar program to create an archive. */
- r = systemf("%s cf - %s %s >%s/archive 2>%s/pack.err", testprog, pack_options, flist, target, target);
- failure("Error invoking %s cf -", testprog, pack_options);
- assertEqualInt(r, 0);
+ /* File with 10 bytes content. */
+ f = fopen("file", "wb");
+ assert(f != NULL);
+ assertEqualInt(10, fwrite("123456789", 1, 10, f));
+ fclose(f);
- assertChdir(target);
+ /* hardlink to above file. */
+ assertMakeHardlink("linkfile", "file");
+ assertIsHardlink("file", "linkfile");
- /* Verify that nothing went to stderr. */
- assertEmptyFile("pack.err");
+ /* Symlink to above file. */
+ if (canSymlink())
+ assertMakeSymlink("symlink", "file");
- /*
- * Use tar to unpack the archive into another directory.
- */
- r = systemf("%s xf archive %s >unpack.out 2>unpack.err", testprog, unpack_options);
- failure("Error invoking %s xf archive %s", testprog, unpack_options);
- assertEqualInt(r, 0);
+ /* Directory. */
+ assertMakeDir("dir", 0775);
- /* Verify that nothing went to stderr. */
- assertEmptyFile("unpack.err");
+ return canSymlink()
+ ? "file linkfile symlink dir"
+ : "file linkfile dir";
+}
- /*
- * Verify unpacked files.
- */
+static void
+verify_files(const char *target)
+{
+ assertChdir(target);
/* Regular file with 2 links. */
assertIsReg("file", -1);
assertFileSize("file", 10);
+ assertFileContents("123456789", 10, "file");
failure("%s", target);
assertFileNLinks("file", 2);
/* Another name for the same file. */
assertIsReg("linkfile", -1);
assertFileSize("linkfile", 10);
+ assertFileContents("123456789", 10, "linkfile");
assertFileNLinks("linkfile", 2);
assertIsHardlink("file", "linkfile");
@@ -79,37 +80,50 @@ basic_tar(const char *target, const char *pack_options,
assertChdir("..");
}
-DEFINE_TEST(test_basic)
+static void
+run_tar(const char *target, const char *pack_options,
+ const char *unpack_options, const char *flist)
{
- FILE *f;
- const char *flist;
+ int r;
- assertUmask(0);
+ assertMakeDir(target, 0775);
- /* File with 10 bytes content. */
- f = fopen("file", "wb");
- assert(f != NULL);
- assertEqualInt(10, fwrite("123456789", 1, 10, f));
- fclose(f);
+ /* Use the tar program to create an archive. */
+ r = systemf("%s cf - %s %s >%s/archive 2>%s/pack.err", testprog, pack_options, flist, target, target);
+ failure("Error invoking %s cf -", testprog, pack_options);
+ assertEqualInt(r, 0);
- /* hardlink to above file. */
- assertMakeHardlink("linkfile", "file");
- assertIsHardlink("file", "linkfile");
+ assertChdir(target);
- /* Symlink to above file. */
- if (canSymlink())
- assertMakeSymlink("symlink", "file");
+ /* Verify that nothing went to stderr. */
+ assertEmptyFile("pack.err");
- /* Directory. */
- assertMakeDir("dir", 0775);
+ /*
+ * Use tar to unpack the archive into another directory.
+ */
+ r = systemf("%s xf archive %s >unpack.out 2>unpack.err",
+ testprog, unpack_options);
+ failure("Error invoking %s xf archive %s", testprog, unpack_options);
+ assertEqualInt(r, 0);
- if (canSymlink())
- flist = "file linkfile symlink dir";
- else
- flist = "file linkfile dir";
+ /* Verify that nothing went to stderr. */
+ assertEmptyFile("unpack.err");
+ assertChdir("..");
+}
+
+DEFINE_TEST(test_basic)
+{
+ const char *flist;
+
+ assertUmask(0);
+ flist = make_files();
/* Archive/dearchive with a variety of options. */
- basic_tar("copy", "", "", flist);
+ run_tar("copy", "", "", flist);
+ verify_files("copy");
+
+ run_tar("copy_ustar", "--format=ustar", "", flist);
+ verify_files("copy_ustar");
+
/* tar doesn't handle cpio symlinks correctly */
- /* basic_tar("copy_odc", "--format=odc", ""); */
- basic_tar("copy_ustar", "--format=ustar", "", flist);
+ /* run_tar("copy_odc", "--format=odc", ""); */
}
diff --git a/tar/test/test_option_C_upper.c b/tar/test/test_option_C_upper.c
new file mode 100644
index 000000000000..dae985446892
--- /dev/null
+++ b/tar/test/test_option_C_upper.c
@@ -0,0 +1,149 @@
+/*-
+ * Copyright (c) 2010 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+DEFINE_TEST(test_option_C_upper)
+{
+ int r;
+
+ assertMakeDir("d1", 0755);
+ assertMakeDir("d2", 0755);
+ assertMakeFile("d1/file1", 0644, "d1/file1");
+ assertMakeFile("d1/file2", 0644, "d1/file2");
+ assertMakeFile("d2/file1", 0644, "d2/file1");
+ assertMakeFile("d2/file2", 0644, "d2/file2");
+
+ /*
+ * Test 1: Basic use of -C
+ */
+ assertMakeDir("test1", 0755);
+ assertChdir("test1");
+ assertEqualInt(0, systemf("%s -cf archive.tar -C ../d1 file1 -C ../d2 file2", testprog));
+ assertEqualInt(0,
+ systemf("%s -xf archive.tar >test.out 2>test.err", testprog));
+ assertFileContents("d1/file1", 8, "file1");
+ assertFileContents("d2/file2", 8, "file2");
+ assertEmptyFile("test.out");
+ assertEmptyFile("test.err");
+ assertChdir("..");
+
+
+ /*
+ * Test 2: Multiple -C
+ */
+ assertMakeDir("test2", 0755);
+ assertChdir("test2");
+ assertEqualInt(0, systemf("%s -cf archive.tar -C .. -C d1 file1 -C .. -C d2 file2", testprog));
+ assertEqualInt(0,
+ systemf("%s -xf archive.tar >test.out 2>test.err", testprog));
+ assertFileContents("d1/file1", 8, "file1");
+ assertFileContents("d2/file2", 8, "file2");
+ assertEmptyFile("test.out");
+ assertEmptyFile("test.err");
+ assertChdir("..");
+
+ /*
+ * Test 3: -C fail
+ */
+ assertMakeDir("test3", 0755);
+ assertChdir("test3");
+ r = systemf("%s -cf archive.tar -C ../XXX file1 -C ../d2 file2 2>write.err", testprog);
+ assert(r != 0);
+ assertNonEmptyFile("write.err");
+ assertEqualInt(0,
+ systemf("%s -xf archive.tar >test.out 2>test.err", testprog));
+ assertFileNotExists("file1");
+ assertFileNotExists("file2");
+ assertEmptyFile("test.out");
+ assertEmptyFile("test.err");
+ assertChdir("..");
+
+ /*
+ * Test 4: Absolute -C
+ */
+ assertMakeDir("test4", 0755);
+ assertChdir("test4");
+ assertEqualInt(0,
+ systemf("%s -cf archive.tar -C %s/d1 file1",
+ testprog, testworkdir));
+ assertEqualInt(0,
+ systemf("%s -xf archive.tar >test.out 2>test.err", testprog));
+ assertFileContents("d1/file1", 8, "file1");
+ assertEmptyFile("test.out");
+ assertEmptyFile("test.err");
+ assertChdir("..");
+
+ /*
+ * Test 5: Unnecessary -C ignored even if directory named doesn't exist
+ */
+ assertMakeDir("test5", 0755);
+ assertChdir("test5");
+ assertEqualInt(0,
+ systemf("%s -cf archive.tar -C XXX -C %s/d1 file1",
+ testprog, testworkdir));
+ assertEqualInt(0,
+ systemf("%s -xf archive.tar >test.out 2>test.err", testprog));
+ assertFileContents("d1/file1", 8, "file1");
+ assertEmptyFile("test.out");
+ assertEmptyFile("test.err");
+ assertChdir("..");
+
+ /*
+ * Test 6: Necessary -C not ignored if directory doesn't exist
+ */
+ assertMakeDir("test6", 0755);
+ assertChdir("test6");
+ r = systemf("%s -cf archive.tar -C XXX -C ../d1 file1 2>write.err",
+ testprog, testworkdir);
+ assert(r != 0);
+ assertNonEmptyFile("write.err");
+ assertEqualInt(0,
+ systemf("%s -xf archive.tar >test.out 2>test.err", testprog));
+ assertEmptyFile("test.out");
+ assertEmptyFile("test.err");
+ assertChdir("..");
+
+ /*
+ * Test 7: -C used without specifying directory
+ */
+ assertMakeDir("test7", 0755);
+ assertChdir("test7");
+ r = systemf("%s -cf archive.tar ../d1/file1 -C 2>write.err", testprog);
+ assert(r != 0);
+ assertNonEmptyFile("write.err");
+ assertChdir("..");
+
+ /*
+ * Test 8: -C used with meaningless option ''
+ */
+ assertMakeDir("test8", 0755);
+ assertChdir("test8");
+ r = systemf("%s -cf archive.tar ../d1/file1 -C \"\" 2>write.err",
+ testprog);
+ assert(r != 0);
+ assertNonEmptyFile("write.err");
+ assertChdir("..");
+}
diff --git a/tar/test/test_option_H_upper.c b/tar/test/test_option_H_upper.c
new file mode 100644
index 000000000000..7ddd917b7b94
--- /dev/null
+++ b/tar/test/test_option_H_upper.c
@@ -0,0 +1,92 @@
+/*-
+ * Copyright (c) 2010 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+DEFINE_TEST(test_option_H_upper)
+{
+
+ if (!canSymlink()) {
+ skipping("Can't test symlinks on this filesystem");
+ return;
+ }
+
+ /*
+ * Create a sample archive.
+ */
+ assertMakeDir("in", 0755);
+ assertChdir("in");
+ assertMakeDir("d1", 0755);
+ assertMakeSymlink("ld1", "d1");
+ assertMakeFile("d1/file1", 0644, "d1/file1");
+ assertMakeFile("d1/file2", 0644, "d1/file2");
+ assertMakeSymlink("d1/link1", "file1");
+ assertMakeSymlink("d1/linkX", "fileX");
+ assertMakeSymlink("link2", "d1/file2");
+ assertMakeSymlink("linkY", "d1/fileY");
+ assertChdir("..");
+
+ /* Test 1: Without -H */
+ assertMakeDir("test1", 0755);
+ assertEqualInt(0,
+ systemf("%s -cf test1/archive.tar -C in . >test1/c.out 2>test1/c.err", testprog));
+ assertChdir("test1");
+ assertEqualInt(0,
+ systemf("%s -xf archive.tar >c.out 2>c.err", testprog));
+ assertIsSymlink("ld1", "d1");
+ assertIsSymlink("d1/link1", "file1");
+ assertIsSymlink("d1/linkX", "fileX");
+ assertIsSymlink("link2", "d1/file2");
+ assertIsSymlink("linkY", "d1/fileY");
+ assertChdir("..");
+
+ /* Test 2: With -H, no symlink on command line. */
+ assertMakeDir("test2", 0755);
+ assertEqualInt(0,
+ systemf("%s -cf test2/archive.tar -H -C in . >test2/c.out 2>test2/c.err", testprog));
+ assertChdir("test2");
+ assertEqualInt(0,
+ systemf("%s -xf archive.tar >c.out 2>c.err", testprog));
+ assertIsSymlink("ld1", "d1");
+ assertIsSymlink("d1/link1", "file1");
+ assertIsSymlink("d1/linkX", "fileX");
+ assertIsSymlink("link2", "d1/file2");
+ assertIsSymlink("linkY", "d1/fileY");
+ assertChdir("..");
+
+ /* Test 3: With -H, some symlinks on command line. */
+ assertMakeDir("test3", 0755);
+ assertEqualInt(0,
+ systemf("%s -cf test3/archive.tar -H -C in ld1 d1 link2 linkY >test2/c.out 2>test2/c.err", testprog));
+ assertChdir("test3");
+ assertEqualInt(0,
+ systemf("%s -xf archive.tar >c.out 2>c.err", testprog));
+ assertIsDir("ld1", 0755);
+ assertIsSymlink("d1/linkX", "fileX");
+ assertIsSymlink("d1/link1", "file1");
+ assertIsReg("link2", 0644);
+ assertIsSymlink("linkY", "d1/fileY");
+ assertChdir("..");
+}
diff --git a/tar/test/test_option_L_upper.c b/tar/test/test_option_L_upper.c
new file mode 100644
index 000000000000..57abe412cd2d
--- /dev/null
+++ b/tar/test/test_option_L_upper.c
@@ -0,0 +1,92 @@
+/*-
+ * Copyright (c) 2010 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+DEFINE_TEST(test_option_L_upper)
+{
+
+ if (!canSymlink()) {
+ skipping("Can't test symlinks on this filesystem");
+ return;
+ }
+
+ /*
+ * Create a sample archive.
+ */
+ assertMakeDir("in", 0755);
+ assertChdir("in");
+ assertMakeDir("d1", 0755);
+ assertMakeSymlink("ld1", "d1");
+ assertMakeFile("d1/file1", 0644, "d1/file1");
+ assertMakeFile("d1/file2", 0644, "d1/file2");
+ assertMakeSymlink("d1/link1", "file1");
+ assertMakeSymlink("d1/linkX", "fileX");
+ assertMakeSymlink("link2", "d1/file2");
+ assertMakeSymlink("linkY", "d1/fileY");
+ assertChdir("..");
+
+ /* Test 1: Without -L */
+ assertMakeDir("test1", 0755);
+ assertEqualInt(0,
+ systemf("%s -cf test1/archive.tar -C in . >test1/c.out 2>test1/c.err", testprog));
+ assertChdir("test1");
+ assertEqualInt(0,
+ systemf("%s -xf archive.tar >c.out 2>c.err", testprog));
+ assertIsSymlink("ld1", "d1");
+ assertIsSymlink("d1/link1", "file1");
+ assertIsSymlink("d1/linkX", "fileX");
+ assertIsSymlink("link2", "d1/file2");
+ assertIsSymlink("linkY", "d1/fileY");
+ assertChdir("..");
+
+ /* Test 2: With -L, no symlink on command line. */
+ assertMakeDir("test2", 0755);
+ assertEqualInt(0,
+ systemf("%s -cf test2/archive.tar -L -C in . >test2/c.out 2>test2/c.err", testprog));
+ assertChdir("test2");
+ assertEqualInt(0,
+ systemf("%s -xf archive.tar >c.out 2>c.err", testprog));
+ assertIsDir("ld1", 0755);
+ assertIsReg("d1/link1", 0644);
+ assertIsSymlink("d1/linkX", "fileX");
+ assertIsReg("link2", 0644);
+ assertIsSymlink("linkY", "d1/fileY");
+ assertChdir("..");
+
+ /* Test 3: With -L, some symlinks on command line. */
+ assertMakeDir("test3", 0755);
+ assertEqualInt(0,
+ systemf("%s -cf test3/archive.tar -L -C in ld1 d1 link2 linkY >test2/c.out 2>test2/c.err", testprog));
+ assertChdir("test3");
+ assertEqualInt(0,
+ systemf("%s -xf archive.tar >c.out 2>c.err", testprog));
+ assertIsDir("ld1", 0755);
+ assertIsReg("d1/link1", 0644);
+ assertIsSymlink("d1/linkX", "fileX");
+ assertIsReg("link2", 0644);
+ assertIsSymlink("linkY", "d1/fileY");
+ assertChdir("..");
+}
diff --git a/tar/test/test_option_O_upper.c b/tar/test/test_option_O_upper.c
new file mode 100644
index 000000000000..b9c8c0cad109
--- /dev/null
+++ b/tar/test/test_option_O_upper.c
@@ -0,0 +1,87 @@
+/*-
+ * Copyright (c) 2010 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+static const char *test4out[] = {"file1", "file2", NULL};
+static const char *test5err[] = {"file1", "file2", NULL};
+
+DEFINE_TEST(test_option_O_upper)
+{
+ assertMakeFile("file1", 0644, "file1");
+ assertMakeFile("file2", 0644, "file2");
+ assertEqualInt(0, systemf("%s -cf archive.tar file1 file2", testprog));
+
+ /* Test 1: -x without -O */
+ assertMakeDir("test1", 0755);
+ assertChdir("test1");
+ assertEqualInt(0,
+ systemf("%s -xf ../archive.tar >test.out 2>test.err", testprog));
+ assertFileContents("file1", 5, "file1");
+ assertFileContents("file2", 5, "file2");
+ assertEmptyFile("test.out");
+ assertEmptyFile("test.err");
+ assertChdir("..");
+
+ /* Test 2: -x with -O */
+ assertMakeDir("test2", 0755);
+ assertChdir("test2");
+ assertEqualInt(0,
+ systemf("%s -xOf ../archive.tar file1 >test.out 2>test.err", testprog));
+ assertFileNotExists("file1");
+ assertFileNotExists("file2");
+ assertFileContents("file1", 5, "test.out");
+ assertEmptyFile("test.err");
+ assertChdir("..");
+
+ /* Test 3: -x with -O and multiple files */
+ assertMakeDir("test3", 0755);
+ assertChdir("test3");
+ assertEqualInt(0,
+ systemf("%s -xOf ../archive.tar >test.out 2>test.err", testprog));
+ assertFileNotExists("file1");
+ assertFileNotExists("file2");
+ assertFileContents("file1file2", 10, "test.out");
+ assertEmptyFile("test.err");
+ assertChdir("..");
+
+ /* Test 4: -t without -O */
+ assertMakeDir("test4", 0755);
+ assertChdir("test4");
+ assertEqualInt(0,
+ systemf("%s -tf ../archive.tar >test.out 2>test.err", testprog));
+ assertFileContainsLinesAnyOrder("test.out", test4out);
+ assertEmptyFile("test.err");
+ assertChdir("..");
+
+ /* Test 5: -t with -O */
+ assertMakeDir("test5", 0755);
+ assertChdir("test5");
+ assertEqualInt(0,
+ systemf("%s -tOf ../archive.tar >test.out 2>test.err", testprog));
+ assertEmptyFile("test.out");
+ assertFileContainsLinesAnyOrder("test.err", test5err);
+ assertChdir("..");
+}
diff --git a/tar/test/test_option_T_upper.c b/tar/test/test_option_T_upper.c
index 3d2a8b1e2a53..f2b65d7bdc23 100644
--- a/tar/test/test_option_T_upper.c
+++ b/tar/test/test_option_T_upper.c
@@ -26,41 +26,33 @@
__FBSDID("$FreeBSD: src/usr.bin/tar/test/test_option_T.c,v 1.3 2008/08/15 06:12:02 kientzle Exp $");
static int
-touch(const char *fn, int fail)
+tryMakeFile(const char *fn)
{
FILE *f = fopen(fn, "w");
- if (fail) {
- failure("Couldn't create file '%s', errno=%d (%s)\n",
- fn, errno, strerror(errno));
- if (!assert(f != NULL))
- return (0); /* Failure. */
- } else {
- if (f == NULL)
- return (0); /* Soft failure. */
- }
+ if (f == NULL)
+ return (0);
fclose(f);
- return (1); /* Success */
+ return (1);
}
DEFINE_TEST(test_option_T_upper)
{
FILE *f;
int r;
- struct stat st;
int gnarlyFilesSupported;
- /* Create a simple dir heirarchy; bail if anything fails. */
+ /* Create a simple dir hierarchy; bail if anything fails. */
if (!assertMakeDir("d1", 0755)) return;
if (!assertMakeDir("d1/d2", 0755)) return;
- if (!touch("f", 1)) return;
- if (!touch("d1/f1", 1)) return;
- if (!touch("d1/f2", 1)) return;
- if (!touch("d1/d2/f3", 1)) return;
- if (!touch("d1/d2/f4", 1)) return;
- if (!touch("d1/d2/f5", 1)) return;
- if (!touch("d1/d2/f6", 1)) return;
+ if (!assertMakeFile("f", 0644, "")) return;
+ if (!assertMakeFile("d1/f1", 0644, "")) return;
+ if (!assertMakeFile("d1/f2", 0644, "")) return;
+ if (!assertMakeFile("d1/d2/f3", 0644, "")) return;
+ if (!assertMakeFile("d1/d2/f4", 0644, "")) return;
+ if (!assertMakeFile("d1/d2/f5", 0644, "")) return;
+ if (!assertMakeFile("d1/d2/f6", 0644, "")) return;
/* Some platforms don't permit such things; just skip it. */
- gnarlyFilesSupported = touch("d1/d2/f\x0a", 0);
+ gnarlyFilesSupported = tryMakeFile("d1/d2/f\x0a");
/* Populate a file list */
f = fopen("filelist", "w+");
@@ -79,12 +71,12 @@ DEFINE_TEST(test_option_T_upper)
return;
/* Use null-terminated names. */
fprintf(f, "d1/d2/f3");
- fwrite("\0", 1, 1, f);
+ assertEqualInt(1, fwrite("\0", 1, 1, f));
fprintf(f, "d1/d2/f5");
- fwrite("\0", 1, 1, f);
+ assertEqualInt(1, fwrite("\0", 1, 1, f));
if (gnarlyFilesSupported) {
fprintf(f, "d1/d2/f\x0a");
- fwrite("\0", 1, 1, f);
+ assertEqualInt(1, fwrite("\0", 1, 1, f));
}
fclose(f);
@@ -160,28 +152,8 @@ DEFINE_TEST(test_option_T_upper)
assertMakeDir("test4_out", 0755);
assertMakeDir("test4_out2", 0755);
assertMakeDir("test4/d1", 0755);
- assertEqualInt(1, touch("test4/d1/foo", 0));
+ assertMakeFile("test4/d1/foo", 0644, "");
- /* Does bsdtar support -s option ? */
- systemf("%s -cf - -s /foo/bar/ test4/d1/foo > check.out 2> check.err",
- testprog);
- assertEqualInt(0, stat("check.err", &st));
- if (st.st_size == 0) {
- systemf("%s -cf - -s /foo/bar/ test4/d1/foo | %s -xf - -C test4_out",
- testprog, testprog);
- assertEmptyFile("test4_out/test4/d1/bar");
- systemf("%s -cf - -s /d1/d2/ test4/d1/foo | %s -xf - -C test4_out",
- testprog, testprog);
- assertEmptyFile("test4_out/test4/d2/foo");
- systemf("%s -cf - -s ,test4/d1/foo,, test4/d1/foo | %s -tvf - > test4.lst",
- testprog, testprog);
- assertEmptyFile("test4.lst");
- systemf("%s -cf - test4/d1/foo | %s -xf - -s /foo/bar/ -C test4_out2",
- testprog, testprog);
- assertEmptyFile("test4_out2/test4/d1/bar");
- } else {
- skipping("bsdtar does not support -s option on this platform");
- }
/* TODO: Include some use of -C directory-changing within the filelist. */
/* I'm pretty sure -C within the filelist is broken on extract. */
diff --git a/tar/test/test_option_U_upper.c b/tar/test/test_option_U_upper.c
new file mode 100644
index 000000000000..4d77cb03810a
--- /dev/null
+++ b/tar/test/test_option_U_upper.c
@@ -0,0 +1,159 @@
+/*-
+ * Copyright (c) 2010 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+DEFINE_TEST(test_option_U_upper)
+{
+ int r;
+
+ assertMakeFile("file1", 0644, "file1");
+ assertMakeDir("d1", 0755);
+ assertMakeFile("d1/file1", 0644, "d1/file1");
+ assertEqualInt(0, systemf("%s -cf archive.tar file1 d1/file1", testprog));
+
+ /*
+ * bsdtar's man page used to claim that -x without -U would
+ * not break hard links. This was and is nonsense. The first
+ * two tests here simply verify that existing hard links get
+ * broken regardless.
+ */
+
+ /* Test 1: -x without -U */
+ assertMakeDir("test1", 0755);
+ assertChdir("test1");
+ assertMakeFile("file1", 0644, "file1new");
+ assertMakeHardlink("file2", "file1");
+ assertEqualInt(0,
+ systemf("%s -xf ../archive.tar >test.out 2>test.err", testprog));
+ assertFileContents("file1", 5, "file1");
+ assertFileContents("file1new", 8, "file2");
+ assertEmptyFile("test.out");
+ assertEmptyFile("test.err");
+ assertChdir("..");
+
+
+ /* Test 2: -x with -U */
+ assertMakeDir("test2", 0755);
+ assertChdir("test2");
+ assertMakeFile("file1", 0644, "file1new");
+ assertMakeHardlink("file2", "file1");
+ assertEqualInt(0,
+ systemf("%s -xUf ../archive.tar >test.out 2>test.err", testprog));
+ assertFileContents("file1", 5, "file1");
+ assertFileContents("file1new", 8, "file2");
+ assertEmptyFile("test.out");
+ assertEmptyFile("test.err");
+ assertChdir("..");
+
+ /*
+ * -U does make a difference in how bsdtar handles unwanted symlinks,
+ * though. It interacts with -P.
+ */
+ if (!canSymlink())
+ return;
+
+ /* Test 3: Intermediate dir symlink causes error by default */
+ assertMakeDir("test3", 0755);
+ assertChdir("test3");
+ assertMakeDir("realDir", 0755);
+ assertMakeSymlink("d1", "realDir");
+ r = systemf("%s -xf ../archive.tar d1/file1 >test.out 2>test.err", testprog);
+ assert(r != 0);
+ assertIsSymlink("d1", "realDir");
+ assertFileNotExists("d1/file1");
+ assertEmptyFile("test.out");
+ assertNonEmptyFile("test.err");
+ assertChdir("..");
+
+ /* Test 4: Intermediate dir symlink gets removed with -U */
+ assertMakeDir("test4", 0755);
+ assertChdir("test4");
+ assertMakeDir("realDir", 0755);
+ assertMakeSymlink("d1", "realDir");
+ assertEqualInt(0,
+ systemf("%s -xUf ../archive.tar >test.out 2>test.err", testprog));
+ assertIsDir("d1", -1);
+ assertFileContents("d1/file1", 8, "d1/file1");
+ assertEmptyFile("test.out");
+ assertEmptyFile("test.err");
+ assertChdir("..");
+
+ /* Test 5: Intermediate dir symlink is followed with -P */
+ assertMakeDir("test5", 0755);
+ assertChdir("test5");
+ assertMakeDir("realDir", 0755);
+ assertMakeSymlink("d1", "realDir");
+ assertEqualInt(0,
+ systemf("%s -xPf ../archive.tar d1/file1 >test.out 2>test.err", testprog));
+ assertIsSymlink("d1", "realDir");
+ assertFileContents("d1/file1", 8, "d1/file1");
+ assertEmptyFile("test.out");
+ assertEmptyFile("test.err");
+ assertChdir("..");
+
+ /* Test 6: Intermediate dir symlink is followed with -PU */
+ assertMakeDir("test6", 0755);
+ assertChdir("test6");
+ assertMakeDir("realDir", 0755);
+ assertMakeSymlink("d1", "realDir");
+ assertEqualInt(0,
+ systemf("%s -xPUf ../archive.tar d1/file1 >test.out 2>test.err", testprog));
+ assertIsSymlink("d1", "realDir");
+ assertFileContents("d1/file1", 8, "d1/file1");
+ assertEmptyFile("test.out");
+ assertEmptyFile("test.err");
+ assertChdir("..");
+
+ /* Test 7: Final file symlink replaced by default */
+ assertMakeDir("test7", 0755);
+ assertChdir("test7");
+ assertMakeDir("d1", 0755);
+ assertMakeFile("d1/realfile1", 0644, "realfile1");
+ assertMakeSymlink("d1/file1", "d1/realfile1");
+ assertEqualInt(0,
+ systemf("%s -xf ../archive.tar d1/file1 >test.out 2>test.err", testprog));
+ assertIsReg("d1/file1", 0644);
+ assertFileContents("d1/file1", 8, "d1/file1");
+ assertFileContents("realfile1", 9, "d1/realfile1");
+ assertEmptyFile("test.out");
+ assertEmptyFile("test.err");
+ assertChdir("..");
+
+ /* Test 8: Final file symlink replaced with -PU */
+ assertMakeDir("test8", 0755);
+ assertChdir("test8");
+ assertMakeDir("d1", 0755);
+ assertMakeFile("d1/realfile1", 0644, "realfile1");
+ assertMakeSymlink("d1/file1", "d1/realfile1");
+ assertEqualInt(0,
+ systemf("%s -xPUf ../archive.tar d1/file1 >test.out 2>test.err", testprog));
+ assertIsReg("d1/file1", 0644);
+ assertFileContents("d1/file1", 8, "d1/file1");
+ assertFileContents("realfile1", 9, "d1/realfile1");
+ assertEmptyFile("test.out");
+ assertEmptyFile("test.err");
+ assertChdir("..");
+}
diff --git a/tar/test/test_option_X_upper.c b/tar/test/test_option_X_upper.c
new file mode 100644
index 000000000000..1aa21fc90a67
--- /dev/null
+++ b/tar/test/test_option_X_upper.c
@@ -0,0 +1,145 @@
+/*-
+ * Copyright (c) 2010 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+DEFINE_TEST(test_option_X_upper)
+{
+ int r;
+
+ /*
+ * Create a sample archive.
+ */
+ assertMakeFile("file1", 0644, "file1");
+ assertMakeFile("file2", 0644, "file2");
+ assertMakeFile("file3a", 0644, "file3a");
+ assertMakeFile("file4a", 0644, "file4a");
+ assertEqualInt(0,
+ systemf("%s -cf archive.tar file1 file2 file3a file4a", testprog));
+
+ /*
+ * Now, try extracting from the test archive with various -X usage.
+ */
+
+ /* Test 1: Without -X */
+ assertMakeDir("test1", 0755);
+ assertChdir("test1");
+ r = systemf("%s -xf ../archive.tar >test.out 2>test.err",
+ testprog);
+ if (!assertEqualInt(0, r))
+ return;
+
+ assertFileContents("file1", 5, "file1");
+ assertFileContents("file2", 5, "file2");
+ assertFileContents("file3a", 6, "file3a");
+ assertFileContents("file4a", 6, "file4a");
+ assertEmptyFile("test.out");
+ assertEmptyFile("test.err");
+ assertChdir("..");
+
+ /* Test 2: Use -X to skip one file */
+ assertMakeDir("test2", 0755);
+ assertChdir("test2");
+ assertMakeFile("exclusions", 0644, "file1\n");
+ assertEqualInt(0,
+ systemf("%s -xf ../archive.tar -X exclusions >test.out 2>test.err", testprog));
+ assertFileNotExists("file1");
+ assertFileContents("file2", 5, "file2");
+ assertFileContents("file3a", 6, "file3a");
+ assertFileContents("file4a", 6, "file4a");
+ assertEmptyFile("test.out");
+ assertEmptyFile("test.err");
+ assertChdir("..");
+
+ /* Test 3: Use -X to skip multiple files */
+ assertMakeDir("test3", 0755);
+ assertChdir("test3");
+ assertMakeFile("exclusions", 0644, "file1\nfile2\n");
+ assertEqualInt(0,
+ systemf("%s -xf ../archive.tar -X exclusions >test.out 2>test.err", testprog));
+ assertFileNotExists("file1");
+ assertFileNotExists("file2");
+ assertFileContents("file3a", 6, "file3a");
+ assertFileContents("file4a", 6, "file4a");
+ assertEmptyFile("test.out");
+ assertEmptyFile("test.err");
+ assertChdir("..");
+
+ /* Test 4: Omit trailing \n */
+ assertMakeDir("test4", 0755);
+ assertChdir("test4");
+ assertMakeFile("exclusions", 0644, "file1\nfile2");
+ assertEqualInt(0,
+ systemf("%s -xf ../archive.tar -X exclusions >test.out 2>test.err", testprog));
+ assertFileNotExists("file1");
+ assertFileNotExists("file2");
+ assertFileContents("file3a", 6, "file3a");
+ assertFileContents("file4a", 6, "file4a");
+ assertEmptyFile("test.out");
+ assertEmptyFile("test.err");
+ assertChdir("..");
+
+ /* Test 5: include/exclude without overlap */
+ assertMakeDir("test5", 0755);
+ assertChdir("test5");
+ assertMakeFile("exclusions", 0644, "file1\nfile2");
+ assertEqualInt(0,
+ systemf("%s -xf ../archive.tar -X exclusions file3a >test.out 2>test.err", testprog));
+ assertFileNotExists("file1");
+ assertFileNotExists("file2");
+ assertFileContents("file3a", 6, "file3a");
+ assertFileNotExists("file4a");
+ assertEmptyFile("test.out");
+ assertEmptyFile("test.err");
+ assertChdir("..");
+
+ /* Test 6: Overlapping include/exclude */
+ assertMakeDir("test6", 0755);
+ assertChdir("test6");
+ assertMakeFile("exclusions", 0644, "file1\nfile2");
+ assertEqualInt(0,
+ systemf("%s -xf ../archive.tar -X exclusions file1 file3a >test.out 2>test.err", testprog));
+ assertFileNotExists("file1");
+ assertFileNotExists("file2");
+ assertFileContents("file3a", 6, "file3a");
+ assertFileNotExists("file4a");
+ assertEmptyFile("test.out");
+ assertEmptyFile("test.err");
+ assertChdir("..");
+
+ /* Test 7: with pattern */
+ assertMakeDir("test7", 0755);
+ assertChdir("test7");
+ assertMakeFile("exclusions", 0644, "file*a\nfile1");
+ assertEqualInt(0,
+ systemf("%s -xf ../archive.tar -X exclusions >test.out 2>test.err", testprog));
+ assertFileNotExists("file1");
+ assertFileContents("file2", 5, "file2");
+ assertFileNotExists("file3a");
+ assertFileNotExists("file4a");
+ assertEmptyFile("test.out");
+ assertEmptyFile("test.err");
+ assertChdir("..");
+}
diff --git a/tar/test/test_option_b.c b/tar/test/test_option_b.c
new file mode 100644
index 000000000000..be2ae65c75a8
--- /dev/null
+++ b/tar/test/test_option_b.c
@@ -0,0 +1,74 @@
+/*-
+ * Copyright (c) 2010 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+DEFINE_TEST(test_option_b)
+{
+ assertMakeFile("file1", 0644, "file1");
+ if (systemf("cat file1 > test_cat.out 2> test_cat.err") != 0) {
+ skipping("Platform doesn't have cat");
+ return;
+ }
+
+ /*
+ * Bsdtar does not pad if the output is going directly to a disk file.
+ */
+ assertEqualInt(0, systemf("%s -cf archive1.tar file1 >test1.out 2>test1.err", testprog));
+ failure("bsdtar does not pad archives written directly to regular files");
+ assertFileSize("archive1.tar", 2048);
+ assertEmptyFile("test1.out");
+ assertEmptyFile("test1.err");
+
+ /*
+ * Bsdtar does pad to the block size if the output is going to a socket.
+ */
+ /* Default is -b 20 */
+ assertEqualInt(0, systemf("%s -cf - file1 2>test2.err | cat >archive2.tar ", testprog));
+ failure("bsdtar does pad archives written to pipes");
+ assertFileSize("archive2.tar", 10240);
+ assertEmptyFile("test2.err");
+
+ assertEqualInt(0, systemf("%s -cf - -b 20 file1 2>test3.err | cat >archive3.tar ", testprog));
+ assertFileSize("archive3.tar", 10240);
+ assertEmptyFile("test3.err");
+
+ assertEqualInt(0, systemf("%s -cf - -b 10 file1 2>test4.err | cat >archive4.tar ", testprog));
+ assertFileSize("archive4.tar", 5120);
+ assertEmptyFile("test4.err");
+
+ assertEqualInt(0, systemf("%s -cf - -b 1 file1 2>test5.err | cat >archive5.tar ", testprog));
+ assertFileSize("archive5.tar", 2048);
+ assertEmptyFile("test5.err");
+
+ assertEqualInt(0, systemf("%s -cf - -b 8192 file1 2>test6.err | cat >archive6.tar ", testprog));
+ assertFileSize("archive6.tar", 4194304);
+ assertEmptyFile("test6.err");
+
+ /*
+ * Note: It's not possible to verify at this level that blocks
+ * are getting written with the
+ */
+}
diff --git a/tar/test/test_option_exclude.c b/tar/test/test_option_exclude.c
new file mode 100644
index 000000000000..1345f70aa160
--- /dev/null
+++ b/tar/test/test_option_exclude.c
@@ -0,0 +1,142 @@
+/*-
+ * Copyright (c) 2010 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+DEFINE_TEST(test_option_exclude)
+{
+ int r;
+
+ assertMakeFile("file1", 0644, "file1");
+ assertMakeFile("file2", 0644, "file2");
+ assertEqualInt(0, systemf("%s -cf archive.tar file1 file2", testprog));
+
+ /*
+ * Now, try extracting from the test archive with various --exclude options.
+ */
+
+ /* Test 1: Without --exclude */
+ assertMakeDir("test1", 0755);
+ assertChdir("test1");
+ assertEqualInt(0,
+ systemf("%s -xf ../archive.tar >test.out 2>test.err", testprog));
+ assertFileContents("file1", 5, "file1");
+ assertFileContents("file2", 5, "file2");
+ assertEmptyFile("test.out");
+ assertEmptyFile("test.err");
+ assertChdir("..");
+
+ /* Test 2: Selecting just one file */
+ assertMakeDir("test2", 0755);
+ assertChdir("test2");
+ assertEqualInt(0,
+ systemf("%s -xf ../archive.tar file1 >test.out 2>test.err", testprog));
+ assertFileContents("file1", 5, "file1");
+ assertFileNotExists("file2");
+ assertEmptyFile("test.out");
+ assertEmptyFile("test.err");
+ assertChdir("..");
+
+ /* Test 3: Use --exclude to skip one file */
+ assertMakeDir("test3", 0755);
+ assertChdir("test3");
+ assertEqualInt(0,
+ systemf("%s -xf ../archive.tar --exclude file1 >test.out 2>test.err", testprog));
+ assertFileNotExists("file1");
+ assertFileContents("file2", 5, "file2");
+ assertEmptyFile("test.out");
+ assertEmptyFile("test.err");
+ assertChdir("..");
+
+ /* Test 4: Selecting one valid and one invalid file */
+ assertMakeDir("test4", 0755);
+ assertChdir("test4");
+ r = systemf("%s -xf ../archive.tar file1 file3 >test.out 2>test.err", testprog);
+ assert(r != 0);
+ assertFileContents("file1", 5, "file1");
+ assertFileNotExists("file2");
+ assertFileNotExists("file3");
+ assertEmptyFile("test.out");
+ assertNonEmptyFile("test.err");
+ assertChdir("..");
+
+ /* Test 5: Selecting one valid file twice */
+ assertMakeDir("test5", 0755);
+ assertChdir("test5");
+ assertEqualInt(0,
+ systemf("%s -xf ../archive.tar file1 file1 >test.out 2>test.err", testprog));
+ assertFileContents("file1", 5, "file1");
+ assertFileNotExists("file2");
+ assertEmptyFile("test.out");
+ assertEmptyFile("test.err");
+ assertChdir("..");
+
+ /* Test 6: Include and exclude the same file */
+ assertMakeDir("test6", 0755);
+ assertChdir("test6");
+ assertEqualInt(0,
+ systemf("%s -xf ../archive.tar --exclude file1 file1 >test.out 2>test.err", testprog));
+ assertFileNotExists("file1");
+ assertFileNotExists("file2");
+ assertEmptyFile("test.out");
+ assertEmptyFile("test.err");
+ assertChdir("..");
+
+ /* Test 7: Exclude a non-existent file */
+ assertMakeDir("test7", 0755);
+ assertChdir("test7");
+ assertEqualInt(0,
+ systemf("%s -xf ../archive.tar --exclude file3 file1 >test.out 2>test.err", testprog));
+ assertFileContents("file1", 5, "file1");
+ assertFileNotExists("file2");
+ assertFileNotExists("file3");
+ assertEmptyFile("test.out");
+ assertEmptyFile("test.err");
+ assertChdir("..");
+
+ /* Test 8: Include a non-existent file */
+ assertMakeDir("test8", 0755);
+ assertChdir("test8");
+ r = systemf("%s -xf ../archive.tar file3 >test.out 2>test.err", testprog);
+ assert(r != 0);
+ assertFileNotExists("file1");
+ assertFileNotExists("file2");
+ assertFileNotExists("file3");
+ assertEmptyFile("test.out");
+ assertNonEmptyFile("test.err");
+ assertChdir("..");
+
+ /* Test 9: Include a non-existent file plus an exclusion */
+ assertMakeDir("test9", 0755);
+ assertChdir("test9");
+ r = systemf("%s -xf ../archive.tar --exclude file1 file3 >test.out 2>test.err", testprog);
+ assert(r != 0);
+ assertFileNotExists("file1");
+ assertFileNotExists("file2");
+ assertFileNotExists("file3");
+ assertEmptyFile("test.out");
+ assertNonEmptyFile("test.err");
+ assertChdir("..");
+}
diff --git a/tar/test/test_option_gid_gname.c b/tar/test/test_option_gid_gname.c
new file mode 100644
index 000000000000..e45da5b91463
--- /dev/null
+++ b/tar/test/test_option_gid_gname.c
@@ -0,0 +1,88 @@
+/*-
+ * Copyright (c) 2003-2010 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+DEFINE_TEST(test_option_gid_gname)
+{
+ char *reference, *data;
+ size_t s;
+
+ assertUmask(0);
+ assertMakeFile("file", 0644, "1234567890");
+
+ /* Create archive with no special options. */
+ failure("Error invoking %s c", testprog);
+ assertEqualInt(0,
+ systemf("%s cf archive1 --format=ustar file >stdout1.txt 2>stderr1.txt",
+ testprog));
+ assertEmptyFile("stdout1.txt");
+ assertEmptyFile("stderr1.txt");
+ reference = slurpfile(&s, "archive1");
+
+ /* Again with both --gid and --gname */
+ failure("Error invoking %s c", testprog);
+ assertEqualInt(0,
+ systemf("%s cf archive2 --gid=17 --gname=foofoofoo --format=ustar file >stdout2.txt 2>stderr2.txt",
+ testprog));
+ assertEmptyFile("stdout2.txt");
+ assertEmptyFile("stderr2.txt");
+ data = slurpfile(&s, "archive2");
+ /* Should force gid and gname fields in ustar header. */
+ assertEqualMem(data + 116, "000021 \0", 8);
+ assertEqualMem(data + 297, "foofoofoo\0", 10);
+
+ /* Again with just --gname */
+ failure("Error invoking %s c", testprog);
+ assertEqualInt(0,
+ systemf("%s cf archive4 --gname=foofoofoo --format=ustar file >stdout4.txt 2>stderr4.txt",
+ testprog));
+ assertEmptyFile("stdout4.txt");
+ assertEmptyFile("stderr4.txt");
+ data = slurpfile(&s, "archive4");
+ /* Gid should be unchanged from original reference. */
+ assertEqualMem(data + 116, reference + 116, 8);
+ assertEqualMem(data + 297, "foofoofoo\0", 10);
+
+ /* Again with --gid and force gname to empty. */
+ failure("Error invoking %s c", testprog);
+ assertEqualInt(0,
+ systemf("%s cf archive3 --gid=17 --gname= --format=ustar file >stdout3.txt 2>stderr3.txt",
+ testprog));
+ assertEmptyFile("stdout3.txt");
+ assertEmptyFile("stderr3.txt");
+ data = slurpfile(&s, "archive3");
+ assertEqualMem(data + 116, "000021 \0", 8);
+ /* Gname field in ustar header should be empty. */
+ assertEqualMem(data + 297, "\0", 1);
+
+ /* TODO: It would be nice to verify that --gid= by itself
+ * will look up the associated gname and use that, but
+ * that requires some system-specific code. */
+
+ /* TODO: It would be nice to verify that --gid= will
+ * leave the gname field blank if the specified gid
+ * isn't used on the local system. */
+}
diff --git a/tar/test/test_option_k.c b/tar/test/test_option_k.c
new file mode 100644
index 000000000000..e57cc274cfc4
--- /dev/null
+++ b/tar/test/test_option_k.c
@@ -0,0 +1,107 @@
+/*-
+ * Copyright (c) 2010 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+DEFINE_TEST(test_option_k)
+{
+ /*
+ * Create an archive with a couple of different versions of the
+ * same file.
+ */
+
+ assertMakeFile("foo", 0644, "foo1");
+
+ assertEqualInt(0, systemf("%s -cf archive.tar foo", testprog));
+
+ assertMakeFile("foo", 0644, "foo2");
+
+ assertEqualInt(0, systemf("%s -rf archive.tar foo", testprog));
+
+ assertMakeFile("bar", 0644, "bar1");
+
+ assertEqualInt(0, systemf("%s -rf archive.tar bar", testprog));
+
+ assertMakeFile("foo", 0644, "foo3");
+
+ assertEqualInt(0, systemf("%s -rf archive.tar foo", testprog));
+
+ assertMakeFile("bar", 0644, "bar2");
+
+ assertEqualInt(0, systemf("%s -rf archive.tar bar", testprog));
+
+ /*
+ * Now, try extracting from the test archive with various
+ * combinations of -k
+ */
+
+ /* Test 1: No option */
+ assertMakeDir("test1", 0755);
+ assertChdir("test1");
+ assertEqualInt(0,
+ systemf("%s -xf ../archive.tar >test.out 2>test.err", testprog));
+ assertFileContents("foo3", 4, "foo");
+ assertFileContents("bar2", 4, "bar");
+ assertEmptyFile("test.out");
+ assertEmptyFile("test.err");
+ assertChdir("..");
+
+ /* Test 2: With -k, we should just get the first versions. */
+ assertMakeDir("test2", 0755);
+ assertChdir("test2");
+ assertEqualInt(0,
+ systemf("%s -xf ../archive.tar -k >test.out 2>test.err", testprog));
+ assertFileContents("foo1", 4, "foo");
+ assertFileContents("bar1", 4, "bar");
+ assertEmptyFile("test.out");
+ assertEmptyFile("test.err");
+ assertChdir("..");
+
+ /* Test 3: Without -k, existing files should get overwritten */
+ assertMakeDir("test3", 0755);
+ assertChdir("test3");
+ assertMakeFile("bar", 0644, "bar0");
+ assertMakeFile("foo", 0644, "foo0");
+ assertEqualInt(0,
+ systemf("%s -xf ../archive.tar >test.out 2>test.err", testprog));
+ assertFileContents("foo3", 4, "foo");
+ assertFileContents("bar2", 4, "bar");
+ assertEmptyFile("test.out");
+ assertEmptyFile("test.err");
+ assertChdir("..");
+
+ /* Test 4: With -k, existing files should not get overwritten */
+ assertMakeDir("test4", 0755);
+ assertChdir("test4");
+ assertMakeFile("bar", 0644, "bar0");
+ assertMakeFile("foo", 0644, "foo0");
+ assertEqualInt(0,
+ systemf("%s -xf ../archive.tar -k >test.out 2>test.err", testprog));
+ assertFileContents("foo0", 4, "foo");
+ assertFileContents("bar0", 4, "bar");
+ assertEmptyFile("test.out");
+ assertEmptyFile("test.err");
+ assertChdir("..");
+}
diff --git a/tar/test/test_option_keep_newer_files.c b/tar/test/test_option_keep_newer_files.c
new file mode 100644
index 000000000000..089898cc27e0
--- /dev/null
+++ b/tar/test/test_option_keep_newer_files.c
@@ -0,0 +1,56 @@
+/*-
+ * Copyright (c) 2010 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+DEFINE_TEST(test_option_keep_newer_files)
+{
+ const char *reffile = "test_option_keep_newer_files.tar.Z";
+
+ /* Reference file has one entry "file" with a very old timestamp. */
+ extract_reference_file(reffile);
+
+ /* Test 1: Without --keep-newer-files */
+ assertMakeDir("test1", 0755);
+ assertChdir("test1");
+ assertMakeFile("file", 0644, "new");
+ assertEqualInt(0,
+ systemf("%s -xf ../%s >test.out 2>test.err", testprog, reffile));
+ assertFileContents("old\n", 4, "file");
+ assertEmptyFile("test.out");
+ assertEmptyFile("test.err");
+ assertChdir("..");
+
+ /* Test 2: With --keep-newer-files */
+ assertMakeDir("test2", 0755);
+ assertChdir("test2");
+ assertMakeFile("file", 0644, "new");
+ assertEqualInt(0,
+ systemf("%s -xf ../%s --keep-newer-files >test.out 2>test.err", testprog, reffile));
+ assertFileContents("new", 3, "file");
+ assertEmptyFile("test.out");
+ assertEmptyFile("test.err");
+ assertChdir("..");
+}
diff --git a/tar/test/test_option_keep_newer_files.tar.Z.uu b/tar/test/test_option_keep_newer_files.tar.Z.uu
new file mode 100644
index 000000000000..74a0f1ece003
--- /dev/null
+++ b/tar/test/test_option_keep_newer_files.tar.Z.uu
@@ -0,0 +1,7 @@
+begin 644 test_option_keep_newer_files.tar.Z
+M'YV09M*P*0.@H,&#"!,J7,BPH<.'$!'"F&B#!@T0`";&N%$#!D:-'#UFG$BR
+MY$48,F38F&$CY8P8)V/$F,$2``@8$7/JW,FS)X`Z<^B$D3.23IHV/AD:19I4
+M8<F)'Y]B;$JUJM6K6'V^84-&0=:O8,.*'4NVK-FS:-.J7<NVK=NW<./*G4NW
+.KMV[>//JW<NWK]^_/0$`
+`
+end
diff --git a/tar/test/test_option_n.c b/tar/test/test_option_n.c
new file mode 100644
index 000000000000..4017dd9f01fd
--- /dev/null
+++ b/tar/test/test_option_n.c
@@ -0,0 +1,61 @@
+/*-
+ * Copyright (c) 2010 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+DEFINE_TEST(test_option_n)
+{
+ assertMakeDir("d1", 0755);
+ assertMakeFile("d1/file1", 0644, "d1/file1");
+
+ /* Test 1: -c without -n */
+ assertMakeDir("test1", 0755);
+ assertChdir("test1");
+ assertEqualInt(0,
+ systemf("%s -cf archive.tar -C .. d1 >c.out 2>c.err", testprog));
+ assertEmptyFile("c.out");
+ assertEmptyFile("c.err");
+ assertEqualInt(0,
+ systemf("%s -xf archive.tar >x.out 2>x.err", testprog));
+ assertEmptyFile("x.out");
+ assertEmptyFile("x.err");
+ assertFileContents("d1/file1", 8, "d1/file1");
+ assertChdir("..");
+
+ /* Test 2: -c with -n */
+ assertMakeDir("test2", 0755);
+ assertChdir("test2");
+ assertEqualInt(0,
+ systemf("%s -cnf archive.tar -C .. d1 >c.out 2>c.err", testprog));
+ assertEmptyFile("c.out");
+ assertEmptyFile("c.err");
+ assertEqualInt(0,
+ systemf("%s -xf archive.tar >x.out 2>x.err", testprog));
+ assertEmptyFile("x.out");
+ assertEmptyFile("x.err");
+ assertIsDir("d1", 0755);
+ assertFileNotExists("d1/file1");
+ assertChdir("..");
+}
diff --git a/tar/test/test_option_newer_than.c b/tar/test/test_option_newer_than.c
new file mode 100644
index 000000000000..c9432dcb5f75
--- /dev/null
+++ b/tar/test/test_option_newer_than.c
@@ -0,0 +1,75 @@
+/*-
+ * Copyright (c) 2010 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+DEFINE_TEST(test_option_newer_than)
+{
+ struct stat st;
+
+ /*
+ * Basic test of --newer-than.
+ * First, create three files with different mtimes.
+ * Create test1.tar with --newer-than, test2.tar without.
+ */
+ assertMakeDir("test1in", 0755);
+ assertChdir("test1in");
+ assertMakeDir("a", 0755);
+ assertMakeDir("a/b", 0755);
+ assertMakeFile("old.txt", 0644, "old.txt");
+ assertEqualInt(0, stat("old.txt", &st));
+ sleepUntilAfter(st.st_mtime);
+ assertMakeFile("middle.txt", 0644, "middle.txt");
+ assertEqualInt(0, stat("middle.txt", &st));
+ sleepUntilAfter(st.st_mtime);
+ assertMakeFile("new.txt", 0644, "new");
+ assertMakeFile("a/b/new.txt", 0644, "new file in old directory");
+
+ /* Test --newer-than on create */
+ assertEqualInt(0, systemf("%s -cf ../test1.tar --newer-than middle.txt *.txt a", testprog));
+ assertEqualInt(0, systemf("%s -cf ../test2.tar *.txt a", testprog));
+ assertChdir("..");
+
+ /* Extract test1.tar to a clean dir and verify what got archived. */
+ assertMakeDir("test1out", 0755);
+ assertChdir("test1out");
+ assertEqualInt(0, systemf("%s xf ../test1.tar", testprog));
+ assertFileExists("new.txt");
+ assertFileExists("a/b/new.txt");
+ assertFileNotExists("middle.txt");
+ assertFileNotExists("old.txt");
+ assertChdir("..");
+
+ /* Extract test2.tar to a clean dir with --newer-than and verify. */
+ assertMakeDir("test2out", 0755);
+ assertChdir("test2out");
+ assertEqualInt(0, systemf("%s xf ../test2.tar --newer-than ../test1in/middle.txt", testprog));
+ assertFileExists("new.txt");
+ assertFileExists("a/b/new.txt");
+ assertFileNotExists("middle.txt");
+ assertFileNotExists("old.txt");
+ assertChdir("..");
+
+}
diff --git a/tar/test/test_option_q.c b/tar/test/test_option_q.c
index 68867b52a82a..287e67afa518 100644
--- a/tar/test/test_option_q.c
+++ b/tar/test/test_option_q.c
@@ -27,7 +27,6 @@ __FBSDID("$FreeBSD: src/usr.bin/tar/test/test_option_q.c,v 1.3 2008/08/22 01:35:
DEFINE_TEST(test_option_q)
{
- FILE *f;
int r;
/*
@@ -40,38 +39,23 @@ DEFINE_TEST(test_option_q)
* what we use to build up the test archive.
*/
- f = fopen("foo", "w");
- assert(f != NULL);
- fprintf(f, "foo1");
- fclose(f);
+ assertMakeFile("foo", 0644, "foo1");
assertEqualInt(0, systemf("%s -cf archive.tar foo", testprog));
- f = fopen("foo", "w");
- assert(f != NULL);
- fprintf(f, "foo2");
- fclose(f);
+ assertMakeFile("foo", 0644, "foo2");
assertEqualInt(0, systemf("%s -rf archive.tar foo", testprog));
- f = fopen("bar", "w");
- assert(f != NULL);
- fprintf(f, "bar1");
- fclose(f);
+ assertMakeFile("bar", 0644, "bar1");
assertEqualInt(0, systemf("%s -rf archive.tar bar", testprog));
- f = fopen("foo", "w");
- assert(f != NULL);
- fprintf(f, "foo3");
- fclose(f);
+ assertMakeFile("foo", 0644, "foo3");
assertEqualInt(0, systemf("%s -rf archive.tar foo", testprog));
- f = fopen("bar", "w");
- assert(f != NULL);
- fprintf(f, "bar2");
- fclose(f);
+ assertMakeFile("bar", 0644, "bar2");
assertEqualInt(0, systemf("%s -rf archive.tar bar", testprog));
diff --git a/tar/test/test_option_r.c b/tar/test/test_option_r.c
index 516a8307936c..70c2087c9f6f 100644
--- a/tar/test/test_option_r.c
+++ b/tar/test/test_option_r.c
@@ -30,29 +30,20 @@ __FBSDID("$FreeBSD$");
*/
DEFINE_TEST(test_option_r)
{
- char buff[15];
+ char *buff;
char *p0, *p1;
- size_t s;
- FILE *f;
- int r;
+ size_t buff_size = 35000;
+ size_t s, buff_size_rounded;
+ int r, i;
- /* Create a file */
- f = fopen("f1", "w");
- if (!assert(f != NULL))
- return;
- assertEqualInt(3, fwrite("abc", 1, 3, f));
- fclose(f);
-
- /* Archive that one file. */
+ /* Create an archive with one file. */
+ assertMakeFile("f1", 0644, "abc");
r = systemf("%s cf archive.tar --format=ustar f1 >step1.out 2>step1.err", testprog);
failure("Error invoking %s cf archive.tar f1", testprog);
assertEqualInt(r, 0);
-
- /* Verify that nothing went to stdout or stderr. */
assertEmptyFile("step1.out");
assertEmptyFile("step1.err");
-
/* Do some basic validation of the constructed archive. */
p0 = slurpfile(&s, "archive.tar");
if (!assert(p0 != NULL))
@@ -66,52 +57,74 @@ DEFINE_TEST(test_option_r)
assertEqualMem(p0 + 1024, "\0\0\0\0\0\0\0\0", 8);
assertEqualMem(p0 + 1536, "\0\0\0\0\0\0\0\0", 8);
- /* Edit that file */
- f = fopen("f1", "w");
- if (!assert(f != NULL))
- return;
- assertEqualInt(3, fwrite("123", 1, 3, f));
- fclose(f);
-
- /* Update the archive. */
+ /* Edit that file with a lot more data and update the archive with a new copy. */
+ buff = malloc(buff_size);
+ assert(buff != NULL);
+ for (i = 0; i < (int)buff_size; ++i)
+ buff[i] = "abcdefghijklmnopqrstuvwxyz"[rand() % 26];
+ buff[buff_size - 1] = '\0';
+ assertMakeFile("f1", 0644, buff);
r = systemf("%s rf archive.tar --format=ustar f1 >step2.out 2>step2.err", testprog);
failure("Error invoking %s rf archive.tar f1", testprog);
assertEqualInt(r, 0);
-
- /* Verify that nothing went to stdout or stderr. */
assertEmptyFile("step2.out");
assertEmptyFile("step2.err");
- /* Do some basic validation of the constructed archive. */
+ /* The constructed archive should just have the new entry appended. */
p1 = slurpfile(&s, "archive.tar");
if (!assert(p1 != NULL)) {
free(p0);
return;
}
- assert(s >= 3072);
+ buff_size_rounded = ((buff_size + 511) / 512) * 512;
+ assert(s >= 2560 + buff_size_rounded);
/* Verify first entry is unchanged. */
assertEqualMem(p0, p1, 1024);
/* Verify that second entry is correct. */
assertEqualMem(p1 + 1024, "f1", 3);
- assertEqualMem(p1 + 1536, "123", 3);
+ assertEqualMem(p1 + 1536, buff, buff_size);
+ /* Verify end-of-archive marker. */
+ assertEqualMem(p1 + 1536 + buff_size_rounded, "\0\0\0\0\0\0\0\0", 8);
+ assertEqualMem(p1 + 2048 + buff_size_rounded, "\0\0\0\0\0\0\0\0", 8);
+
+ free(p0);
+ p0 = p1;
+
+ /* Update the archive by adding a different file. */
+ assertMakeFile("f2", 0644, "f2");
+ r = systemf("%s rf archive.tar --format=ustar f2 >step3.out 2>step3.err", testprog);
+ failure("Error invoking %s rf archive.tar f2", testprog);
+ assertEqualInt(r, 0);
+ assertEmptyFile("step3.out");
+ assertEmptyFile("step3.err");
+
+ /* Validate the constructed archive. */
+ p1 = slurpfile(&s, "archive.tar");
+ if (!assert(p1 != NULL)) {
+ free(p0);
+ return;
+ }
+ assert(s >= 3584 + buff_size_rounded);
+ /* Verify first two entries are unchanged. */
+ assertEqualMem(p0, p1, 1536 + buff_size_rounded);
+ /* Verify that new entry is correct. */
+ assertEqualMem(p1 + 1536 + buff_size_rounded, "f2", 3);
+ assertEqualMem(p1 + 2048 + buff_size_rounded, "f2", 3);
/* Verify end-of-archive marker. */
- assertEqualMem(p1 + 2048, "\0\0\0\0\0\0\0\0", 8);
- assertEqualMem(p1 + 2560, "\0\0\0\0\0\0\0\0", 8);
+ assertEqualMem(p1 + 2560 + buff_size_rounded, "\0\0\0\0\0\0\0\0", 8);
+ assertEqualMem(p1 + 3072 + buff_size_rounded, "\0\0\0\0\0\0\0\0", 8);
free(p0);
free(p1);
- /* Unpack both items */
- assertMakeDir("step3", 0775);
- assertChdir("step3");
- r = systemf("%s xf ../archive.tar", testprog);
+ /* Unpack everything */
+ assertMakeDir("extract", 0775);
+ assertChdir("extract");
+ r = systemf("%s xf ../archive.tar >extract.out 2>extract.err", testprog);
failure("Error invoking %s xf archive.tar", testprog);
assertEqualInt(r, 0);
+ assertEmptyFile("extract.out");
+ assertEmptyFile("extract.err");
- /* Verify that the second one overwrote the first. */
- f = fopen("f1", "r");
- if (assert(f != NULL)) {
- assertEqualInt(3, fread(buff, 1, 3, f));
- assertEqualMem(buff, "123", 3);
- fclose(f);
- }
+ /* Verify that the second copy of f1 overwrote the first. */
+ assertFileContents(buff, strlen(buff), "f1");
}
diff --git a/tar/test/test_option_s.c b/tar/test/test_option_s.c
index 701f07c3cd32..f643f1878136 100644
--- a/tar/test/test_option_s.c
+++ b/tar/test/test_option_s.c
@@ -25,21 +25,6 @@
#include "test.h"
__FBSDID("$FreeBSD: src/usr.bin/tar/test/test_option_T.c,v 1.3 2008/08/15 06:12:02 kientzle Exp $");
-static int
-mkfile(const char *fn, const char *contents)
-{
- FILE *f = fopen(fn, "w");
- failure("Couldn't create file '%s', errno=%d (%s)\n",
- fn, errno, strerror(errno));
- if (!assert(f != NULL))
- return (1); /* Failure. */
- if (contents != NULL)
- assertEqualInt(strlen(contents),
- fwrite(contents, 1, strlen(contents), f));
- assertEqualInt(0, fclose(f));
- return (0); /* Success */
-}
-
DEFINE_TEST(test_option_s)
{
struct stat st;
@@ -47,10 +32,16 @@ DEFINE_TEST(test_option_s)
/* Create a sample file hierarchy. */
assertMakeDir("in", 0755);
assertMakeDir("in/d1", 0755);
- assertEqualInt(0, mkfile("in/d1/foo", "foo"));
- assertEqualInt(0, mkfile("in/d1/bar", "bar"));
+ assertMakeFile("in/d1/foo", 0644, "foo");
+ assertMakeFile("in/d1/bar", 0644, "bar");
+ if (canSymlink()) {
+ assertMakeFile("in/d1/realfile", 0644, "realfile");
+ assertMakeSymlink("in/d1/symlink", "realfile");
+ }
+ assertMakeFile("in/d1/hardlink1", 0644, "hardlinkedfile");
+ assertMakeHardlink("in/d1/hardlink2", "in/d1/hardlink1");
- /* Does bsdtar support -s option ? */
+ /* Does tar support -s option ? */
systemf("%s -cf - -s /foo/bar/ in/d1/foo > NUL 2> check.err",
testprog);
assertEqualInt(0, stat("check.err", &st));
@@ -71,7 +62,6 @@ DEFINE_TEST(test_option_s)
testprog, testprog);
assertFileContents("foo", 3, "test1/in/d2/foo");
-
/*
* Test 2: Basic substitution when extracting archive.
*/
@@ -104,4 +94,160 @@ DEFINE_TEST(test_option_s)
testprog, testprog);
assertFileContents("foo", 3, "test5/in/d1/bar");
assertFileContents("bar", 3, "test5/in/d1/foo");
+
+ /*
+ * Test 6: symlinks get renamed by default
+ */
+ if (canSymlink()) {
+ /* At extraction time. */
+ assertMakeDir("test6a", 0755);
+ systemf("%s -cf - in/d1 | %s -xf - -s /d1/d2/ -C test6a",
+ testprog, testprog);
+ assertFileContents("realfile", 8, "test6a/in/d2/realfile");
+ assertFileContents("realfile", 8, "test6a/in/d2/symlink");
+ assertIsSymlink("test6a/in/d2/symlink", "realfile");
+ /* At creation time. */
+ assertMakeDir("test6b", 0755);
+ systemf("%s -cf - -s /d1/d2/ in/d1 | %s -xf - -C test6b",
+ testprog, testprog);
+ assertFileContents("realfile", 8, "test6b/in/d2/realfile");
+ assertFileContents("realfile", 8, "test6b/in/d2/symlink");
+ assertIsSymlink("test6b/in/d2/symlink", "realfile");
+ }
+
+ /*
+ * Test 7: selective renaming of symlink target
+ */
+ if (canSymlink()) {
+ /* At extraction. */
+ assertMakeDir("test7a", 0755);
+ systemf("%s -cf - in/d1 | %s -xf - -s /realfile/realfile-renamed/ -C test7a",
+ testprog, testprog);
+ assertFileContents("realfile", 8, "test7a/in/d1/realfile-renamed");
+ assertFileContents("realfile", 8, "test7a/in/d1/symlink");
+ assertIsSymlink("test7a/in/d1/symlink", "realfile-renamed");
+ /* At creation. */
+ assertMakeDir("test7b", 0755);
+ systemf("%s -cf - -s /realfile/realfile-renamed/ in/d1 | %s -xf - -C test7b",
+ testprog, testprog);
+ assertFileContents("realfile", 8, "test7b/in/d1/realfile-renamed");
+ assertFileContents("realfile", 8, "test7b/in/d1/symlink");
+ assertIsSymlink("test7b/in/d1/symlink", "realfile-renamed");
+ }
+
+ /*
+ * Test 8: hardlinks get renamed by default
+ */
+ /* At extraction time. */
+ assertMakeDir("test8a", 0755);
+ systemf("%s -cf - in/d1 | %s -xf - -s /d1/d2/ -C test8a",
+ testprog, testprog);
+ assertIsHardlink("test8a/in/d2/hardlink1", "test8a/in/d2/hardlink2");
+ /* At creation time. */
+ assertMakeDir("test8b", 0755);
+ systemf("%s -cf - -s /d1/d2/ in/d1 | %s -xf - -C test8b",
+ testprog, testprog);
+ assertIsHardlink("test8b/in/d2/hardlink1", "test8b/in/d2/hardlink2");
+
+ /*
+ * Test 9: selective renaming of hardlink target
+ */
+ /* At extraction. (assuming hardlink2 is the hardlink entry) */
+ assertMakeDir("test9a", 0755);
+ systemf("%s -cf - in/d1 | %s -xf - -s /hardlink1/hardlink1-renamed/ -C test9a",
+ testprog, testprog);
+ assertIsHardlink("test9a/in/d1/hardlink1-renamed", "test9a/in/d1/hardlink2");
+ /* At extraction. (assuming hardlink1 is the hardlink entry) */
+ assertMakeDir("test9b", 0755);
+ systemf("%s -cf - in/d1 | %s -xf - -s /hardlink2/hardlink2-renamed/ -C test9b",
+ testprog, testprog);
+ assertIsHardlink("test9b/in/d1/hardlink1", "test9b/in/d1/hardlink2-renamed");
+ /* At creation. (assuming hardlink2 is the hardlink entry) */
+ assertMakeDir("test9c", 0755);
+ systemf("%s -cf - -s /hardlink1/hardlink1-renamed/ in/d1 | %s -xf - -C test9c",
+ testprog, testprog);
+ assertIsHardlink("test9c/in/d1/hardlink1-renamed", "test9c/in/d1/hardlink2");
+ /* At creation. (assuming hardlink1 is the hardlink entry) */
+ assertMakeDir("test9d", 0755);
+ systemf("%s -cf - -s /hardlink2/hardlink2-renamed/ in/d1 | %s -xf - -C test9d",
+ testprog, testprog);
+ assertIsHardlink("test9d/in/d1/hardlink1", "test9d/in/d1/hardlink2-renamed");
+
+ /*
+ * Test 10: renaming symlink target without repointing symlink
+ */
+ if (canSymlink()) {
+ /* At extraction. */
+ assertMakeDir("test10a", 0755);
+ systemf("%s -cf - in/d1 | %s -xf - -s /realfile/foo/S -s /foo/realfile/ -C test10a",
+ testprog, testprog);
+ assertFileContents("realfile", 8, "test10a/in/d1/foo");
+ assertFileContents("foo", 3, "test10a/in/d1/realfile");
+ assertFileContents("foo", 3, "test10a/in/d1/symlink");
+ assertIsSymlink("test10a/in/d1/symlink", "realfile");
+ /* At creation. */
+ assertMakeDir("test10b", 0755);
+ systemf("%s -cf - -s /realfile/foo/S -s /foo/realfile/ in/d1 | %s -xf - -C test10b",
+ testprog, testprog);
+ assertFileContents("realfile", 8, "test10b/in/d1/foo");
+ assertFileContents("foo", 3, "test10b/in/d1/realfile");
+ assertFileContents("foo", 3, "test10b/in/d1/symlink");
+ assertIsSymlink("test10b/in/d1/symlink", "realfile");
+ }
+
+ /*
+ * Test 11: repointing symlink without renaming file
+ */
+ if (canSymlink()) {
+ /* At extraction. */
+ assertMakeDir("test11a", 0755);
+ systemf("%s -cf - in/d1 | %s -xf - -s /realfile/foo/sR -C test11a",
+ testprog, testprog);
+ assertFileContents("foo", 3, "test11a/in/d1/foo");
+ assertFileContents("realfile", 8, "test11a/in/d1/realfile");
+ assertFileContents("foo", 3, "test11a/in/d1/symlink");
+ assertIsSymlink("test11a/in/d1/symlink", "foo");
+ /* At creation. */
+ assertMakeDir("test11b", 0755);
+ systemf("%s -cf - -s /realfile/foo/R in/d1 | %s -xf - -C test11b",
+ testprog, testprog);
+ assertFileContents("foo", 3, "test11b/in/d1/foo");
+ assertFileContents("realfile", 8, "test11b/in/d1/realfile");
+ assertFileContents("foo", 3, "test11b/in/d1/symlink");
+ assertIsSymlink("test11b/in/d1/symlink", "foo");
+ }
+
+ /*
+ * Test 12: renaming hardlink target without changing hardlink.
+ * (Requires a pre-built archive, since we otherwise can't know
+ * which element will be stored as the hardlink.)
+ */
+ extract_reference_file("test_option_s.tar.Z");
+ assertMakeDir("test12a", 0755);
+ systemf("%s -xf test_option_s.tar.Z -s /hardlink1/foo/H -s /foo/hardlink1/ -C test12a",
+ testprog);
+ assertFileContents("foo", 3, "test12a/in/d1/hardlink1");
+ assertFileContents("hardlinkedfile", 14, "test12a/in/d1/foo");
+ assertFileContents("foo", 3, "test12a/in/d1/hardlink2");
+ assertIsHardlink("test12a/in/d1/hardlink1", "test12a/in/d1/hardlink2");
+ /* TODO: Expand this test to verify creation as well.
+ * Since either hardlink1 or hardlink2 might get stored as a hardlink,
+ * this will either requiring testing both cases and accepting either
+ * pass, or some very creative renames that can be tested regardless.
+ */
+
+ /*
+ * Test 13: repoint hardlink without changing files
+ * (Requires a pre-built archive, since we otherwise can't know
+ * which element will be stored as the hardlink.)
+ */
+ extract_reference_file("test_option_s.tar.Z");
+ assertMakeDir("test13a", 0755);
+ systemf("%s -xf test_option_s.tar.Z -s /hardlink1/foo/Rh -s /foo/hardlink1/Rh -C test13a",
+ testprog);
+ assertFileContents("foo", 3, "test13a/in/d1/foo");
+ assertFileContents("hardlinkedfile", 14, "test13a/in/d1/hardlink1");
+ assertFileContents("foo", 3, "test13a/in/d1/hardlink2");
+ assertIsHardlink("test13a/in/d1/foo", "test13a/in/d1/hardlink2");
+ /* TODO: See above; expand this test to verify renames at creation. */
}
diff --git a/tar/test/test_option_s.tar.Z.uu b/tar/test/test_option_s.tar.Z.uu
new file mode 100644
index 000000000000..df690bfa1837
--- /dev/null
+++ b/tar/test/test_option_s.tar.Z.uu
@@ -0,0 +1,16 @@
+begin 644 test_option_s.tar.Z
+M'YV0:=R\(!/C!8"#"!,J7,BPH<.'$"-*1`BCXHT:-4``J`CCAHV,&SG*H*&1
+MHTF3(&+$^%@C!HT8,&C(``%#Y0T9,P"`J#&QI\^?0(,"J#.'3A@Y(>FD:2/4
+M8=$P9LPT77@21LF3&J=JW<JUJU>A`0<6%'/TJ]FS"3G:H$$R9,>/5RN.C%L5
+MQHR4*S&ZA"F39HR1=G7"0$NX<$*B1I%65,KTZ].H7JO2K9C5L.7+F+>219JY
+ML^?/H$.+'DVZM&G+80F^,//FS6G0:MG&]0C2Y%RW=>^J9+DWYLR:(V7($/SZ
+M->*RBY>:?2RUJV3<E(M+GQZ1M6OJV+-KW\Z]NW?3J0NB.4J&3<`U,;YKC=V6
+M(VVZM^M67(F7]TO??F?4D#&8IGK,QRD&`V/+&069<UA!9]5_#'8VGASEG5<&
+M&6:DP489#6:HX88<=NAA3^&]\&"$;JPQW(<0L3<;7+C%)Q]EN^EU7U\UV2!<
+M3BF%.*)Y)::'XD,!)J6<8P8VQ]5SS_VHI$\ARE%&&&Q4>.&2#JGHUGLMMB<?
+M3/7)R-=O,<P@4W^#4=E4D,DUYA5SD268I)EP,N0DE%)B&.>=>.:IYYX'A3A'
+M'FWPN`:?[F&T8FTB:?EBERW-"&8-=N$HPYQ16F@GGPBA.>"0:Q;9)DH*5H;I
+MJ*26:NJIJ*:JZJJLMNKJJ[#&*NNLM-9JZZVXYJKKKKSVZNNOP`8K[+#$%FOL
+)L<@FJ^RRS.X)
+`
+end
diff --git a/tar/test/test_option_uid_uname.c b/tar/test/test_option_uid_uname.c
new file mode 100644
index 000000000000..83ea5f1ecbbf
--- /dev/null
+++ b/tar/test/test_option_uid_uname.c
@@ -0,0 +1,80 @@
+/*-
+ * Copyright (c) 2003-2010 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+DEFINE_TEST(test_option_uid_uname)
+{
+ char *reference, *data;
+ size_t s;
+
+ assertUmask(0);
+ assertMakeFile("file", 0644, "1234567890");
+
+ /* Create archive with no special options. */
+ failure("Error invoking %s c", testprog);
+ assertEqualInt(0,
+ systemf("%s cf archive1 --format=ustar file >stdout1.txt 2>stderr1.txt",
+ testprog));
+ assertEmptyFile("stdout1.txt");
+ assertEmptyFile("stderr1.txt");
+ reference = slurpfile(&s, "archive1");
+
+ /* Again with both --uid and --uname */
+ failure("Error invoking %s c", testprog);
+ assertEqualInt(0,
+ systemf("%s cf archive2 --uid=17 --uname=foofoofoo --format=ustar file >stdout2.txt 2>stderr2.txt",
+ testprog));
+ assertEmptyFile("stdout2.txt");
+ assertEmptyFile("stderr2.txt");
+ data = slurpfile(&s, "archive2");
+ /* Should force uid and uname fields in ustar header. */
+ assertEqualMem(data + 108, "000021 \0", 8);
+ assertEqualMem(data + 265, "foofoofoo\0", 10);
+
+ /* Again with just --uid */
+ failure("Error invoking %s c", testprog);
+ assertEqualInt(0,
+ systemf("%s cf archive3 --uid=17 --format=ustar file >stdout3.txt 2>stderr3.txt",
+ testprog));
+ assertEmptyFile("stdout3.txt");
+ assertEmptyFile("stderr3.txt");
+ data = slurpfile(&s, "archive3");
+ assertEqualMem(data + 108, "000021 \0", 8);
+ /* Uname field in ustar header should be empty. */
+ assertEqualMem(data + 265, "\0", 1);
+
+ /* Again with just --uname */
+ failure("Error invoking %s c", testprog);
+ assertEqualInt(0,
+ systemf("%s cf archive4 --uname=foofoofoo --format=ustar file >stdout4.txt 2>stderr4.txt",
+ testprog));
+ assertEmptyFile("stdout4.txt");
+ assertEmptyFile("stderr4.txt");
+ data = slurpfile(&s, "archive4");
+ /* Uid should be unchanged from original reference. */
+ assertEqualMem(data + 108, reference + 108, 8);
+ assertEqualMem(data + 265, "foofoofoo\0", 10);
+}
diff --git a/tar/test/test_patterns.c b/tar/test/test_patterns.c
index fee98be9b270..e1449008b6e1 100644
--- a/tar/test/test_patterns.c
+++ b/tar/test/test_patterns.c
@@ -122,6 +122,7 @@ DEFINE_TEST(test_patterns)
char file_b1[] = "tmp/server/share/fileXX";
char file_b2[] = "tmp/server\\share\\fileXX";
char file_c[] = "tmp/../fileXX";
+ char file_d[] = "tmp/../../fileXX";
char *filex;
int xsize;
@@ -169,8 +170,13 @@ DEFINE_TEST(test_patterns)
* \/?\UnC\../file54
*/
assertFileNotExists(filex);
- filex = file_c;
- xsize = sizeof(file_c);
+ if (r == 6 || r == 26 || r == 43) {
+ filex = file_d;
+ xsize = sizeof(file_d);
+ } else {
+ filex = file_c;
+ xsize = sizeof(file_c);
+ }
filex[xsize-3] = '0' + r / 10;
filex[xsize-2] = '0' + r % 10;
assertFileNotExists(filex);
diff --git a/tar/test/test_print_longpath.c b/tar/test/test_print_longpath.c
new file mode 100644
index 000000000000..4bac1679cc97
--- /dev/null
+++ b/tar/test/test_print_longpath.c
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 2011 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+DEFINE_TEST(test_print_longpath)
+{
+ const char *reffile = "test_print_longpath.tar.Z";
+ char buff[2048];
+ int i, j, k;
+
+ /* Reference file has one entry "file" with a very old timestamp. */
+ extract_reference_file(reffile);
+
+ /* Build long path pattern. */
+ memset(buff, 0, sizeof(buff));
+ for (k = 0; k < 4; k++) {
+ for (j = 0; j < k+1; j++) {
+ for (i = 0; i < 10; i++)
+ strncat(buff, "0123456789",
+ sizeof(buff) - strlen(buff) -1);
+ strncat(buff, "/", sizeof(buff) - strlen(buff) -1);
+ }
+ strncat(buff, "\n", sizeof(buff) - strlen(buff) -1);
+ }
+ buff[sizeof(buff)-1] = '\0';
+
+ assertEqualInt(0,
+ systemf("%s -tf %s >test.out 2>test.err", testprog, reffile));
+ assertTextFileContents(buff, "test.out");
+ assertEmptyFile("test.err");
+}
diff --git a/tar/test/test_print_longpath.tar.Z.uu b/tar/test/test_print_longpath.tar.Z.uu
new file mode 100644
index 000000000000..05658ffcc649
--- /dev/null
+++ b/tar/test/test_print_longpath.tar.Z.uu
@@ -0,0 +1,24 @@
+begin 644 test_print_longpath.tar.Z
+M'YV04,+@05(F#)DR<E[`B"%C!HT:-F[@R+&PX<.($RLZA"B1(L.-&#U:Y)CQ
+MX\6.&D^6'!DR)4<``&#(O%&C!HB8"VG&N"DSADZ>,H/*E$$31(P8$6_0"$H4
+M!`R+-&@``($'IM6K6+-JW<JUJ]>O8+O6F4,GC!R<8^J4"<LV[5JV8(7*!"KT
+M)MR[>//JW<NWK]>C.^&$H8.FA\N6)DF*!(DR,6*6C2&O9#Q9Y6++ASN^4"`#
+M!H@Q=-*T*=,CQ@P9-638\%B#L^?!HDF;1JV:M8(9.$`P22(DB)0A2))8*>)B
+MC)R"H=^X"3VZ].G4-B;FP*'`K_7KV+-KW\Z]N_?O5S-75BS^,GG'D2F;?ZR^
+M?.87.&'0M(G39XV=]7_&EQO4*-(;2C%U@U,RH`;15#6`IZ!V8Y5UEDQN:1=A
+M=OS1U=^"&&:H85@!#53000FYA]YX[&$VXGKIF2@9BC`%-1]0]N'7DW[\R125
+M#/XEM91,-3DU`T0TS#!551L6"5>#9J&EEH1+4BB7A7/%=**(*U+9WI185IFE
+M>D;Z)0-#(`A&F&%;JGBEEFB>J::9;"JF4)GGI=EFB7&N6>><FKGV&7.R/5<;
+M##/<H"=LS<T&'44U4(>;;KSY!IQPQ!F'7!K*\>D<;:M55%V7G';J:896XDEB
+MBG>62N>II$8$GXL]YG<?C#36V-]1.@;5(Z`TW&!##`A^ZJM52#X(PX38$7M=
+MA?M%&:JIJ38[ZK,H0EO>KW=U2)!!"+TI)[/2PHEJMY"U.%.K,[[JJHPUVB!?
+MC@#N&$-J/@(I%574^AJLDF\5VR1VR/;KK;/1!KSLMP*?6"];,Y@6YF"%#0RP
+MP^#:27!YVDK\\+\1BUKPBA5K#/'&%F?,;0Z;=;9G;)<>"L-T@UIJZ)\RY'!;
+M;KOU]EMPPQ5W'&R5HOQRIC%O>O#07WUL-,8@>XS>JN/25RZZ,4)9(:WM]@0O
+MKC3=T"O17=X+X;[7&6M=OT]*N>W$2!]]-L!<>V7MA]FJ'7+2(SLLKGSDYF3N
+MTU+/!(,-[`:X4)#QVA#5D&T;Z?6P8%LGME]DUV7VW'(KO;;((27.%0TQT+#P
+MF)77G?;HEY,<.MJEGPYPQZ*G3CKE2+...NRNUSYWR9Z!YK.?F>800\N[8TJ1
+M[T(3K3KF%]N.)]-X.ZTWU+'*ZAG5@G<^@X^YUJ`U"`EJKN'BC_<5/E^17W@\
+:W;-;/K?W[+?O_OOPQR___/37;__]^.>OOU<`
+`
+end
diff --git a/tar/test/test_strip_components.c b/tar/test/test_strip_components.c
index c9028a4d7661..d195af1b3526 100644
--- a/tar/test/test_strip_components.c
+++ b/tar/test/test_strip_components.c
@@ -25,18 +25,6 @@
#include "test.h"
__FBSDID("$FreeBSD: src/usr.bin/tar/test/test_strip_components.c,v 1.2 2008/11/10 05:24:13 kientzle Exp $");
-static int
-touch(const char *fn)
-{
- FILE *f = fopen(fn, "w");
- failure("Couldn't create file '%s', errno=%d (%s)\n",
- fn, errno, strerror(errno));
- if (!assert(f != NULL))
- return (0); /* Failure. */
- fclose(f);
- return (1); /* Success */
-}
-
DEFINE_TEST(test_strip_components)
{
assertMakeDir("d0", 0755);
@@ -44,7 +32,7 @@ DEFINE_TEST(test_strip_components)
assertMakeDir("d1", 0755);
assertMakeDir("d1/d2", 0755);
assertMakeDir("d1/d2/d3", 0755);
- assertEqualInt(1, touch("d1/d2/f1"));
+ assertMakeFile("d1/d2/f1", 0644, "");
assertMakeHardlink("l1", "d1/d2/f1");
assertMakeHardlink("d1/l2", "d1/d2/f1");
if (canSymlink()) {
@@ -53,7 +41,15 @@ DEFINE_TEST(test_strip_components)
}
assertChdir("..");
- assertEqualInt(0, systemf("%s -cf test.tar d0", testprog));
+ /*
+ * Test 1: Strip components when extracting archives.
+ */
+ if (canSymlink())
+ assertEqualInt(0, systemf("%s -cf test.tar d0/l1 d0/s1 d0/d1",
+ testprog));
+ else
+ assertEqualInt(0, systemf("%s -cf test.tar d0/l1 d0/d1",
+ testprog));
assertMakeDir("target", 0755);
assertEqualInt(0, systemf("%s -x -C target --strip-components 2 "
@@ -63,6 +59,8 @@ DEFINE_TEST(test_strip_components)
assertFileNotExists("target/d0");
failure("d0/d1/ is too short and should not get restored");
assertFileNotExists("target/d1");
+ failure("d0/s1 is too short and should not get restored");
+ assertFileNotExists("target/s1");
failure("d0/d1/s2 is a symlink to something that won't be extracted");
/* If platform supports symlinks, target/s2 is a broken symlink. */
/* If platform does not support symlink, target/s2 doesn't exist. */
@@ -73,6 +71,8 @@ DEFINE_TEST(test_strip_components)
assertIsDir("target/d2", -1);
/*
+ * Test 1b: Strip components extracting archives involving hardlinks.
+ *
* This next is a complicated case. d0/l1, d0/d1/l2, and
* d0/d1/d2/f1 are all hardlinks to the same file; d0/l1 can't
* be extracted with --strip-components=2 and the other two
@@ -82,18 +82,11 @@ DEFINE_TEST(test_strip_components)
* which these three names get archived. If d0/l1 is first,
* none of the three can be restored. If either of the longer
* names are first, then the two longer ones can both be
- * restored.
- *
- * The tree-walking code used by bsdtar always visits files
- * before subdirectories, so bsdtar's behavior is fortunately
- * deterministic: d0/l1 will always get stored first and the
- * other two will be stored as hardlinks to d0/l1. Since
- * d0/l1 can't be extracted, none of these three will be
- * extracted.
+ * restored. Note that the "tar -cf" command above explicitly
+ * lists d0/l1 before d0/d1.
*
- * It may be worth extending this test to force a particular
- * archiving order so as to exercise both of the cases described
- * above.
+ * It may be worth extending this test to exercise other
+ * archiving orders.
*
* Of course, this is all totally different for cpio and newc
* formats because the hardlink management is different.
@@ -106,4 +99,41 @@ DEFINE_TEST(test_strip_components)
assertFileNotExists("target/l2");
failure("d0/d1/d2/f1 is a hardlink to file whose name was too short");
assertFileNotExists("target/d2/f1");
+
+ /*
+ * Test 2: Strip components when creating archives.
+ */
+ if (canSymlink())
+ assertEqualInt(0, systemf("%s --strip-components 2 -cf test2.tar "
+ "d0/l1 d0/s1 d0/d1", testprog));
+ else
+ assertEqualInt(0, systemf("%s --strip-components 2 -cf test2.tar "
+ "d0/l1 d0/d1", testprog));
+
+ assertMakeDir("target2", 0755);
+ assertEqualInt(0, systemf("%s -x -C target2 -f test2.tar", testprog));
+
+ failure("d0/ is too short and should not have been archived");
+ assertFileNotExists("target2/d0");
+ failure("d0/d1/ is too short and should not have been archived");
+ assertFileNotExists("target2/d1");
+ failure("d0/s1 is too short and should not get restored");
+ assertFileNotExists("target/s1");
+ /* If platform supports symlinks, target/s2 is included. */
+ if (canSymlink()) {
+ failure("d0/d1/s2 is a symlink to something included in archive");
+ assertIsSymlink("target2/s2", "d2/f1");
+ }
+ failure("d0/d1/d2 should be archived");
+ assertIsDir("target2/d2", -1);
+
+ /*
+ * Test 2b: Strip components creating archives involving hardlinks.
+ */
+ failure("d0/l1 is too short and should not have been archived");
+ assertFileNotExists("target/l1");
+ failure("d0/d1/l2 is a hardlink to file whose name was too short");
+ assertFileNotExists("target/l2");
+ failure("d0/d1/d2/f1 is a hardlink to file whose name was too short");
+ assertFileNotExists("target/d2/f1");
}
diff --git a/tar/test/test_symlink_dir.c b/tar/test/test_symlink_dir.c
index aa80ba68e315..f6e99662bf11 100644
--- a/tar/test/test_symlink_dir.c
+++ b/tar/test/test_symlink_dir.c
@@ -31,38 +31,22 @@ __FBSDID("$FreeBSD: src/usr.bin/tar/test/test_symlink_dir.c,v 1.1 2008/09/14 02:
* way of a dir extraction.
*/
-static int
-mkfile(const char *name, int mode, const char *contents, size_t size)
-{
- FILE *f = fopen(name, "wb");
- size_t written;
-
- (void)mode; /* UNUSED */
- if (f == NULL)
- return (-1);
- written = fwrite(contents, 1, size, f);
- fclose(f);
- if (size != written)
- return (-1);
- return (0);
-}
-
DEFINE_TEST(test_symlink_dir)
{
assertUmask(0);
assertMakeDir("source", 0755);
- assertEqualInt(0, mkfile("source/file", 0755, "a", 1));
- assertEqualInt(0, mkfile("source/file2", 0755, "ab", 2));
+ assertMakeFile("source/file", 0755, "a");
+ assertMakeFile("source/file2", 0755, "ab");
assertMakeDir("source/dir", 0755);
assertMakeDir("source/dir/d", 0755);
- assertEqualInt(0, mkfile("source/dir/f", 0755, "abc", 3));
+ assertMakeFile("source/dir/f", 0755, "abc");
assertMakeDir("source/dir2", 0755);
assertMakeDir("source/dir2/d2", 0755);
- assertEqualInt(0, mkfile("source/dir2/f2", 0755, "abcd", 4));
+ assertMakeFile("source/dir2/f2", 0755, "abcd");
assertMakeDir("source/dir3", 0755);
assertMakeDir("source/dir3/d3", 0755);
- assertEqualInt(0, mkfile("source/dir3/f3", 0755, "abcde", 5));
+ assertMakeFile("source/dir3/f3", 0755, "abcde");
assertEqualInt(0,
systemf("%s -cf test.tar -C source dir dir2 dir3 file file2",
@@ -82,11 +66,11 @@ DEFINE_TEST(test_symlink_dir)
skipping("some symlink checks");
}
/* "dir3" is a symlink to an existing "non_dir3" */
- assertEqualInt(0, mkfile("dest1/non_dir3", 0755, "abcdef", 6));
+ assertMakeFile("dest1/non_dir3", 0755, "abcdef");
if (canSymlink())
assertMakeSymlink("dest1/dir3", "non_dir3");
/* "file" is a symlink to existing "real_file" */
- assertEqualInt(0, mkfile("dest1/real_file", 0755, "abcdefg", 7));
+ assertMakeFile("dest1/real_file", 0755, "abcdefg");
if (canSymlink()) {
assertMakeSymlink("dest1/file", "real_file");
/* "file2" is a symlink to non-existing "real_file2" */
@@ -122,11 +106,11 @@ DEFINE_TEST(test_symlink_dir)
if (canSymlink())
assertMakeSymlink("dest2/dir2", "real_dir2");
/* "dir3" is a symlink to an existing "non_dir3" */
- assertEqualInt(0, mkfile("dest2/non_dir3", 0755, "abcdefgh", 8));
+ assertMakeFile("dest2/non_dir3", 0755, "abcdefgh");
if (canSymlink())
assertMakeSymlink("dest2/dir3", "non_dir3");
/* "file" is a symlink to existing "real_file" */
- assertEqualInt(0, mkfile("dest2/real_file", 0755, "abcdefghi", 9));
+ assertMakeFile("dest2/real_file", 0755, "abcdefghi");
if (canSymlink())
assertMakeSymlink("dest2/file", "real_file");
/* "file2" is a symlink to non-existing "real_file2" */
diff --git a/tar/tree.c b/tar/tree.c
index da8962bc3111..54cd4c2d5bae 100644
--- a/tar/tree.c
+++ b/tar/tree.c
@@ -104,9 +104,9 @@ struct tree_entry {
/* Definitions for tree_entry.flags bitmap. */
#define isDir 1 /* This entry is a regular directory. */
#define isDirLink 2 /* This entry is a symbolic link to a directory. */
-#define needsFirstVisit 4 /* This is an initial entry. */
+#define needsFirstVisit 4 /* This is an initial entry. */
#define needsDescent 8 /* This entry needs to be previsited. */
-#define needsOpen 16 /* This is a directory that needs to be opened. */
+#define needsOpen 16 /* This is a directory that needs to be opened. */
#define needsAscent 32 /* This entry needs to be postvisited. */
/*
@@ -122,15 +122,15 @@ struct tree_entry {
struct tree {
struct tree_entry *stack;
struct tree_entry *current;
-#if defined(HAVE_WINDOWS_H) && !defined(__CYGWIN__)
+#if defined(_WIN32) && !defined(__CYGWIN__)
HANDLE d;
BY_HANDLE_FILE_INFORMATION fileInfo;
-#define INVALID_DIR_HANDLE INVALID_HANDLE_VALUE
+#define INVALID_DIR_HANDLE INVALID_HANDLE_VALUE
WIN32_FIND_DATA _findData;
WIN32_FIND_DATA *findData;
#else
DIR *d;
-#define INVALID_DIR_HANDLE NULL
+#define INVALID_DIR_HANDLE NULL
struct dirent *de;
#endif
int flags;
@@ -154,8 +154,8 @@ struct tree {
};
/* Definitions for tree.flags bitmap. */
-#define hasStat 16 /* The st entry is valid. */
-#define hasLstat 32 /* The lst entry is valid. */
+#define hasStat 16 /* The st entry is valid. */
+#define hasLstat 32 /* The lst entry is valid. */
#define hasFileInfo 64 /* The Windows fileInfo entry is valid. */
#if defined(_WIN32) && !defined(__CYGWIN__)
@@ -168,9 +168,9 @@ tree_dir_next_posix(struct tree *t);
#ifdef HAVE_DIRENT_D_NAMLEN
/* BSD extension; avoids need for a strlen() call. */
-#define D_NAMELEN(dp) (dp)->d_namlen
+#define D_NAMELEN(dp) (dp)->d_namlen
#else
-#define D_NAMELEN(dp) (strlen((dp)->d_name))
+#define D_NAMELEN(dp) (strlen((dp)->d_name))
#endif
#include <stdio.h>
@@ -289,15 +289,42 @@ tree_open(const char *path)
#elif defined(_WIN32) && !defined(__CYGWIN__)
struct tree *t;
char *cwd = _getcwd(NULL, 0);
- char *pathname = strdup(path), *p, *base;
-
- if (pathname == NULL)
+ char *pathname, *p, *base;
+ wchar_t *wcs, *wp;
+ size_t l, wlen;
+
+ /* Take care of '\' character in multi-byte character-set.
+ * Some multi-byte character-set have been using '\' character
+ * for a part of its character code. */
+ l = MultiByteToWideChar(CP_OEMCP, 0, path, strlen(path), NULL, 0);
+ if (l == 0)
+ abort();
+ wcs = malloc(sizeof(*wcs) * (l+1));
+ if (wcs == NULL)
abort();
- for (p = pathname; *p != '\0'; ++p) {
- if (*p == '\\')
- *p = '/';
+ l = MultiByteToWideChar(CP_OEMCP, 0, path, strlen(path), wcs, l);
+ wcs[l] = L'\0';
+ wlen = l;
+ for (wp = wcs; *wp != L'\0'; ++wp) {
+ if (*wp == L'\\')
+ *wp = L'/';
}
+ l = WideCharToMultiByte(CP_OEMCP, 0, wcs, wlen, NULL, 0, NULL, NULL);
+ if (l == 0)
+ abort();
+ pathname = malloc(l+1);
+ if (pathname == NULL)
+ abort();
+ l = WideCharToMultiByte(CP_OEMCP, 0, wcs, wlen, pathname, l, NULL, NULL);
+ pathname[l] = '\0';
+ free(wcs);
base = pathname;
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ /* ASCII version APIs do not accept the path which begin with
+ * "//?/" prefix. */
+ if (strncmp(base, "//?/", 4) == 0)
+ base += 4;
+#endif
t = malloc(sizeof(*t));
memset(t, 0, sizeof(*t));
@@ -305,8 +332,8 @@ tree_open(const char *path)
/* printf("Looking for wildcard in %s\n", path); */
/* TODO: wildcard detection here screws up on \\?\c:\ UNC names */
if (strchr(base, '*') || strchr(base, '?')) {
- // It has a wildcard in it...
- // Separate the last element.
+ /* It has a wildcard in it... */
+ /* Separate the last element. */
p = strrchr(base, '/');
if (p != NULL) {
*p = '\0';
@@ -428,13 +455,13 @@ tree_next(struct tree *t)
continue;
return (r);
}
- // Not a pattern, handle it as-is...
+ /* Not a pattern, handle it as-is... */
#endif
/* Top stack item needs a regular visit. */
t->current = t->stack;
tree_append(t, t->stack->name, strlen(t->stack->name));
- //t->dirname_length = t->path_length;
- //tree_pop(t);
+ /* t->dirname_length = t->path_length; */
+ /* tree_pop(t); */
t->stack->flags &= ~needsFirstVisit;
return (t->visit_type = TREE_REGULAR);
} else if (t->stack->flags & needsDescent) {
@@ -611,7 +638,7 @@ tree_current_stat(struct tree *t)
return (&t->st);
}
-#if defined(HAVE_WINDOWS_H) && !defined(__CYGWIN__)
+#if defined(_WIN32) && !defined(__CYGWIN__)
const BY_HANDLE_FILE_INFORMATION *
tree_current_file_information(struct tree *t)
{
@@ -740,7 +767,7 @@ tree_current_is_physical_link(struct tree *t)
#if defined(_WIN32) && !defined(__CYGWIN__)
#ifndef IO_REPARSE_TAG_SYMLINK
/* Old SDKs do not provide IO_REPARSE_TAG_SYMLINK */
-#define IO_REPARSE_TAG_SYMLINK 0xA000000CL
+#define IO_REPARSE_TAG_SYMLINK 0xA000000CL
#endif
if (t->findData)
return ((t->findData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
diff --git a/tar/util.c b/tar/util.c
index 2a3d9a03b544..7e705c2be228 100644
--- a/tar/util.c
+++ b/tar/util.c
@@ -56,7 +56,7 @@ __FBSDID("$FreeBSD: src/usr.bin/tar/util.c,v 1.23 2008/12/15 06:00:25 kientzle E
#include <wctype.h>
#else
/* If we don't have wctype, we need to hack up some version of iswprint(). */
-#define iswprint isprint
+#define iswprint isprint
#endif
#include "bsdtar.h"
@@ -66,14 +66,14 @@ static size_t bsdtar_expand_char(char *, size_t, char);
static const char *strip_components(const char *path, int elements);
#if defined(_WIN32) && !defined(__CYGWIN__)
-#define read _read
+#define read _read
#endif
/* TODO: Hack up a version of mbtowc for platforms with no wide
* character support at all. I think the following might suffice,
* but it needs careful testing.
* #if !HAVE_MBTOWC
- * #define mbtowc(wcp, p, n) ((*wcp = *p), 1)
+ * #define mbtowc(wcp, p, n) ((*wcp = *p), 1)
* #endif
*/
@@ -115,8 +115,21 @@ safe_fprintf(FILE *f, const char *fmt, ...)
va_end(ap);
/* If the result was too large, allocate a buffer on the heap. */
- if (length >= fmtbuff_length) {
- fmtbuff_length = length+1;
+ while (length < 0 || length >= fmtbuff_length) {
+ if (length >= fmtbuff_length)
+ fmtbuff_length = length+1;
+ else if (fmtbuff_length < 8192)
+ fmtbuff_length *= 2;
+ else {
+ int old_length = fmtbuff_length;
+ fmtbuff_length += fmtbuff_length / 4;
+ if (old_length > fmtbuff_length) {
+ length = old_length;
+ fmtbuff_heap[length-1] = '\0';
+ break;
+ }
+ }
+ free(fmtbuff_heap);
fmtbuff_heap = malloc(fmtbuff_length);
/* Reformat the result into the heap buffer if we can. */
@@ -129,6 +142,7 @@ safe_fprintf(FILE *f, const char *fmt, ...)
/* Leave fmtbuff pointing to the truncated
* string in fmtbuff_stack. */
length = sizeof(fmtbuff_stack) - 1;
+ break;
}
}
@@ -267,12 +281,19 @@ yes(const char *fmt, ...)
* about -C with non-existent directories; such requests will only
* fail if the directory must be accessed.
*
- * TODO: Make this handle Windows paths correctly.
*/
void
set_chdir(struct bsdtar *bsdtar, const char *newdir)
{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ if (newdir[0] == '/' || newdir[0] == '\\' ||
+ /* Detect this type, for example, "C:\" or "C:/" */
+ (((newdir[0] >= 'a' && newdir[0] <= 'z') ||
+ (newdir[0] >= 'A' && newdir[0] <= 'Z')) &&
+ newdir[1] == ':' && (newdir[2] == '/' || newdir[2] == '\\'))) {
+#else
if (newdir[0] == '/') {
+#endif
/* The -C /foo -C /bar case; dump first one. */
free(bsdtar->pending_chdir);
bsdtar->pending_chdir = NULL;
@@ -362,10 +383,8 @@ edit_pathname(struct bsdtar *bsdtar, struct archive_entry *entry)
#if HAVE_REGEX_H
char *subst_name;
int r;
-#endif
-#if HAVE_REGEX_H
- r = apply_substitution(bsdtar, name, &subst_name, 0);
+ r = apply_substitution(bsdtar, name, &subst_name, 0, 0);
if (r == -1) {
lafe_warnc(0, "Invalid substitution, skipping entry");
return 1;
@@ -381,7 +400,7 @@ edit_pathname(struct bsdtar *bsdtar, struct archive_entry *entry)
}
if (archive_entry_hardlink(entry)) {
- r = apply_substitution(bsdtar, archive_entry_hardlink(entry), &subst_name, 1);
+ r = apply_substitution(bsdtar, archive_entry_hardlink(entry), &subst_name, 0, 1);
if (r == -1) {
lafe_warnc(0, "Invalid substitution, skipping entry");
return 1;
@@ -392,7 +411,7 @@ edit_pathname(struct bsdtar *bsdtar, struct archive_entry *entry)
}
}
if (archive_entry_symlink(entry) != NULL) {
- r = apply_substitution(bsdtar, archive_entry_symlink(entry), &subst_name, 1);
+ r = apply_substitution(bsdtar, archive_entry_symlink(entry), &subst_name, 1, 0);
if (r == -1) {
lafe_warnc(0, "Invalid substitution, skipping entry");
return 1;
@@ -507,14 +526,13 @@ const char *
tar_i64toa(int64_t n0)
{
static char buff[24];
- int64_t n = n0 < 0 ? -n0 : n0;
+ uint64_t n = n0 < 0 ? -n0 : n0;
char *p = buff + sizeof(buff);
*--p = '\0';
do {
*--p = '0' + (int)(n % 10);
- n /= 10;
- } while (n > 0);
+ } while (n /= 10);
if (n0 < 0)
*--p = '-';
return p;
diff --git a/tar/write.c b/tar/write.c
index 47f676ad2eca..8c102d0ec13b 100644
--- a/tar/write.c
+++ b/tar/write.c
@@ -50,6 +50,9 @@ __FBSDID("$FreeBSD: src/usr.bin/tar/write.c,v 1.79 2008/11/27 05:49:52 kientzle
#ifdef HAVE_IO_H
#include <io.h>
#endif
+#ifdef HAVE_LIBGEN_H
+#include <libgen.h>
+#endif
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
@@ -67,6 +70,9 @@ __FBSDID("$FreeBSD: src/usr.bin/tar/write.c,v 1.79 2008/11/27 05:49:52 kientzle
/* This header exists but is broken on Cygwin. */
#include <ext2fs/ext2_fs.h>
#endif
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#endif
#ifdef HAVE_PWD_H
#include <pwd.h>
#endif
@@ -89,18 +95,10 @@ __FBSDID("$FreeBSD: src/usr.bin/tar/write.c,v 1.79 2008/11/27 05:49:52 kientzle
#include "line_reader.h"
#include "tree.h"
-/* Size of buffer for holding file data prior to writing. */
-#define FILEDATABUFLEN 65536
-
-/* Fixed size of uname/gname caches. */
-#define name_cache_size 101
-
#ifndef O_BINARY
-#define O_BINARY 0
+#define O_BINARY 0
#endif
-static const char * const NO_NAME = "(noname)";
-
struct archive_dir_entry {
struct archive_dir_entry *next;
time_t mtime_sec;
@@ -112,16 +110,6 @@ struct archive_dir {
struct archive_dir_entry *head, *tail;
};
-struct name_cache {
- int probes;
- int hits;
- size_t size;
- struct {
- id_t id;
- const char *name;
- } cache[name_cache_size];
-};
-
static void add_dir_list(struct bsdtar *bsdtar, const char *path,
time_t mtime_sec, int mtime_nsec);
static int append_archive(struct bsdtar *, struct archive *,
@@ -138,10 +126,12 @@ static void report_write(struct bsdtar *, struct archive *,
struct archive_entry *, int64_t progress);
static void test_for_append(struct bsdtar *);
static void write_archive(struct archive *, struct bsdtar *);
-static void write_entry_backend(struct bsdtar *, struct archive *,
+static void write_entry(struct bsdtar *, struct archive *,
+ struct archive_entry *);
+static void write_file(struct bsdtar *, struct archive *,
struct archive_entry *);
static int write_file_data(struct bsdtar *, struct archive *,
- struct archive_entry *, int fd);
+ struct archive_entry *, int fd, size_t align);
static void write_hierarchy(struct bsdtar *, struct archive *,
const char *);
@@ -156,10 +146,10 @@ seek_file(int fd, int64_t offset, int whence)
return (SetFilePointerEx((HANDLE)_get_osfhandle(fd),
distance, NULL, FILE_BEGIN) ? 1 : -1);
}
-#define open _open
-#define close _close
-#define read _read
-#define lseek seek_file
+#define open _open
+#define close _close
+#define read _read
+#define lseek seek_file
#endif
void
@@ -187,25 +177,15 @@ tar_mode_c(struct bsdtar *bsdtar)
usage();
}
- /*
- * If user explicitly set the block size, then assume they
- * want the last block padded as well. Otherwise, use the
- * default block size and accept archive_write_open_file()'s
- * default padding decisions.
- */
- if (bsdtar->bytes_per_block != 0) {
- archive_write_set_bytes_per_block(a, bsdtar->bytes_per_block);
- archive_write_set_bytes_in_last_block(a,
- bsdtar->bytes_per_block);
- } else
- archive_write_set_bytes_per_block(a, DEFAULT_BYTES_PER_BLOCK);
+ archive_write_set_bytes_per_block(a, bsdtar->bytes_per_block);
+ archive_write_set_bytes_in_last_block(a, bsdtar->bytes_in_last_block);
if (bsdtar->compress_program) {
archive_write_set_compression_program(a, bsdtar->compress_program);
} else {
switch (bsdtar->create_compression) {
case 0:
- r = archive_write_set_compression_none(a);
+ r = ARCHIVE_OK;
break;
case 'j': case 'y':
r = archive_write_set_compression_bzip2(a);
@@ -213,6 +193,9 @@ tar_mode_c(struct bsdtar *bsdtar)
case 'J':
r = archive_write_set_compression_xz(a);
break;
+ case OPTION_LZIP:
+ r = archive_write_set_compression_lzip(a);
+ break;
case OPTION_LZMA:
r = archive_write_set_compression_lzma(a);
break;
@@ -269,7 +252,7 @@ tar_mode_r(struct bsdtar *bsdtar)
"Cannot open %s", bsdtar->filename);
a = archive_read_new();
- archive_read_support_compression_all(a);
+ archive_read_support_filter_all(a);
archive_read_support_format_tar(a);
archive_read_support_format_gnutar(a);
r = archive_read_open_fd(a, bsdtar->fd, 10240);
@@ -279,7 +262,7 @@ tar_mode_r(struct bsdtar *bsdtar)
archive_error_string(a));
while (0 == archive_read_next_header(a, &entry)) {
if (archive_compression(a) != ARCHIVE_COMPRESSION_NONE) {
- archive_read_finish(a);
+ archive_read_free(a);
close(bsdtar->fd);
lafe_errc(1, 0,
"Cannot append to compressed archive.");
@@ -289,11 +272,10 @@ tar_mode_r(struct bsdtar *bsdtar)
}
end_offset = archive_read_header_position(a);
- archive_read_finish(a);
+ archive_read_free(a);
/* Re-open archive for writing */
a = archive_write_new();
- archive_write_set_compression_none(a);
/*
* Set the format to be used for writing. To allow people to
* extend empty files, we need to allow them to specify the format,
@@ -319,9 +301,6 @@ tar_mode_r(struct bsdtar *bsdtar)
* Just preserve the current format, with a little care
* for formats that libarchive can't write.
*/
- if (format == ARCHIVE_FORMAT_TAR_GNUTAR)
- /* TODO: When gtar supports pax, use pax restricted. */
- format = ARCHIVE_FORMAT_TAR_USTAR;
if (format == ARCHIVE_FORMAT_EMPTY)
format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED;
archive_write_set_format(a, format);
@@ -363,12 +342,11 @@ tar_mode_u(struct bsdtar *bsdtar)
"Cannot open %s", bsdtar->filename);
a = archive_read_new();
- archive_read_support_compression_all(a);
+ archive_read_support_filter_all(a);
archive_read_support_format_tar(a);
archive_read_support_format_gnutar(a);
- if (archive_read_open_fd(a, bsdtar->fd,
- bsdtar->bytes_per_block != 0 ? bsdtar->bytes_per_block :
- DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) {
+ if (archive_read_open_fd(a, bsdtar->fd, bsdtar->bytes_per_block)
+ != ARCHIVE_OK) {
lafe_errc(1, 0,
"Can't open %s: %s", bsdtar->filename,
archive_error_string(a));
@@ -377,7 +355,7 @@ tar_mode_u(struct bsdtar *bsdtar)
/* Build a list of all entries and their recorded mod times. */
while (0 == archive_read_next_header(a, &entry)) {
if (archive_compression(a) != ARCHIVE_COMPRESSION_NONE) {
- archive_read_finish(a);
+ archive_read_free(a);
close(bsdtar->fd);
lafe_errc(1, 0,
"Cannot append to compressed archive.");
@@ -391,24 +369,17 @@ tar_mode_u(struct bsdtar *bsdtar)
}
end_offset = archive_read_header_position(a);
- archive_read_finish(a);
+ archive_read_free(a);
/* Re-open archive for writing. */
a = archive_write_new();
- archive_write_set_compression_none(a);
/*
- * Set format to same one auto-detected above, except that
- * we don't write GNU tar format, so use ustar instead.
+ * Set format to same one auto-detected above.
*/
- if (format == ARCHIVE_FORMAT_TAR_GNUTAR)
- format = ARCHIVE_FORMAT_TAR_USTAR;
archive_write_set_format(a, format);
- if (bsdtar->bytes_per_block != 0) {
- archive_write_set_bytes_per_block(a, bsdtar->bytes_per_block);
- archive_write_set_bytes_in_last_block(a,
- bsdtar->bytes_per_block);
- } else
- archive_write_set_bytes_per_block(a, DEFAULT_BYTES_PER_BLOCK);
+ archive_write_set_bytes_per_block(a, bsdtar->bytes_per_block);
+ archive_write_set_bytes_in_last_block(a, bsdtar->bytes_in_last_block);
+
if (lseek(bsdtar->fd, end_offset, SEEK_SET) < 0)
lafe_errc(1, errno, "Could not seek to archive end");
if (ARCHIVE_OK != archive_write_set_options(a, bsdtar->option_options))
@@ -440,8 +411,15 @@ write_archive(struct archive *a, struct bsdtar *bsdtar)
const char *arg;
struct archive_entry *entry, *sparse_entry;
+ /* Choose a suitable copy buffer size */
+ bsdtar->buff_size = 64 * 1024;
+ while (bsdtar->buff_size < (size_t)bsdtar->bytes_per_block)
+ bsdtar->buff_size *= 2;
+ /* Try to compensate for space we'll lose to alignment. */
+ bsdtar->buff_size += 16 * 1024;
+
/* Allocate a buffer for file data. */
- if ((bsdtar->buff = malloc(FILEDATABUFLEN)) == NULL)
+ if ((bsdtar->buff = malloc(bsdtar->buff_size)) == NULL)
lafe_errc(1, 0, "cannot allocate memory");
if ((bsdtar->resolver = archive_entry_linkresolver_new()) == NULL)
@@ -468,6 +446,12 @@ write_archive(struct archive *a, struct bsdtar *bsdtar)
bsdtar->return_value = 1;
goto cleanup;
}
+ if (*arg == '\0') {
+ lafe_warnc(0,
+ "Meaningless argument for -C: ''");
+ bsdtar->return_value = 1;
+ goto cleanup;
+ }
}
set_chdir(bsdtar, arg);
} else {
@@ -486,7 +470,7 @@ write_archive(struct archive *a, struct bsdtar *bsdtar)
entry = NULL;
archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry);
while (entry != NULL) {
- write_entry_backend(bsdtar, a, entry);
+ write_file(bsdtar, a, entry);
archive_entry_free(entry);
entry = NULL;
archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry);
@@ -502,7 +486,7 @@ cleanup:
free(bsdtar->buff);
archive_entry_linkresolver_free(bsdtar->resolver);
bsdtar->resolver = NULL;
- archive_read_finish(bsdtar->diskreader);
+ archive_read_free(bsdtar->diskreader);
bsdtar->diskreader = NULL;
if (bsdtar->option_totals) {
@@ -510,7 +494,7 @@ cleanup:
tar_i64toa(archive_position_compressed(a)));
}
- archive_write_finish(a);
+ archive_write_free(a);
}
/*
@@ -531,7 +515,13 @@ archive_names_from_file(struct bsdtar *bsdtar, struct archive *a)
lr = lafe_line_reader(bsdtar->names_from_file, bsdtar->option_null);
while ((line = lafe_line_reader_next(lr)) != NULL) {
if (bsdtar->next_line_is_dir) {
- set_chdir(bsdtar, line);
+ if (*line != '\0')
+ set_chdir(bsdtar, line);
+ else {
+ lafe_warnc(0,
+ "Meaningless argument for -C: ''");
+ bsdtar->return_value = 1;
+ }
bsdtar->next_line_is_dir = 0;
} else if (!bsdtar->option_null && strcmp(line, "-C") == 0)
bsdtar->next_line_is_dir = 1;
@@ -557,9 +547,10 @@ archive_names_from_file(struct bsdtar *bsdtar, struct archive *a)
*/
static int
append_archive_filename(struct bsdtar *bsdtar, struct archive *a,
- const char *filename)
+ const char *raw_filename)
{
struct archive *ina;
+ const char *filename = raw_filename;
int rc;
if (strcmp(filename, "-") == 0)
@@ -567,8 +558,8 @@ append_archive_filename(struct bsdtar *bsdtar, struct archive *a,
ina = archive_read_new();
archive_read_support_format_all(ina);
- archive_read_support_compression_all(ina);
- if (archive_read_open_file(ina, filename, 10240)) {
+ archive_read_support_filter_all(ina);
+ if (archive_read_open_file(ina, filename, bsdtar->bytes_per_block)) {
lafe_warnc(0, "%s", archive_error_string(ina));
bsdtar->return_value = 1;
return (0);
@@ -578,10 +569,10 @@ append_archive_filename(struct bsdtar *bsdtar, struct archive *a,
if (rc != ARCHIVE_OK) {
lafe_warnc(0, "Error reading archive %s: %s",
- filename, archive_error_string(ina));
+ raw_filename, archive_error_string(ina));
bsdtar->return_value = 1;
}
- archive_read_finish(ina);
+ archive_read_free(ina);
return (rc);
}
@@ -642,7 +633,7 @@ copy_file_data(struct bsdtar *bsdtar, struct archive *a,
ssize_t bytes_written;
int64_t progress = 0;
- bytes_read = archive_read_data(ina, bsdtar->buff, FILEDATABUFLEN);
+ bytes_read = archive_read_data(ina, bsdtar->buff, bsdtar->buff_size);
while (bytes_read > 0) {
if (need_report())
report_write(bsdtar, a, entry, progress);
@@ -654,8 +645,7 @@ copy_file_data(struct bsdtar *bsdtar, struct archive *a,
return (-1);
}
progress += bytes_written;
- bytes_read = archive_read_data(ina, bsdtar->buff,
- FILEDATABUFLEN);
+ bytes_read = archive_read_data(ina, bsdtar->buff, bsdtar->buff_size);
}
return (0);
@@ -870,7 +860,7 @@ write_hierarchy(struct bsdtar *bsdtar, struct archive *a, const char *path)
continue;
#endif
-#if defined(EXT2_IOC_GETFLAGS) && defined(EXT2_NODUMP_FL)
+#if defined(EXT2_IOC_GETFLAGS) && defined(EXT2_NODUMP_FL) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)
/* Linux uses ioctl to read flags. */
if (bsdtar->option_honor_nodump) {
int fd = open(name, O_RDONLY | O_NONBLOCK | O_BINARY);
@@ -884,6 +874,22 @@ write_hierarchy(struct bsdtar *bsdtar, struct archive *a, const char *path)
}
#endif
+#ifdef __APPLE__
+ if (bsdtar->enable_copyfile) {
+ /* If we're using copyfile(), ignore "._XXX" files. */
+ const char *bname = strrchr(name, '/');
+ if (bname == NULL)
+ bname = name;
+ else
+ ++bname;
+ if (bname[0] == '.' && bname[1] == '_')
+ continue;
+ } else {
+ /* If not, drop the copyfile() data. */
+ archive_entry_copy_mac_metadata(entry, NULL, 0);
+ }
+#endif
+
/*
* If the user vetoes this file/directory, skip it.
* We want this to be fairly late; if some other
@@ -917,7 +923,7 @@ write_hierarchy(struct bsdtar *bsdtar, struct archive *a, const char *path)
archive_entry_linkify(bsdtar->resolver, &entry, &spare_entry);
while (entry != NULL) {
- write_entry_backend(bsdtar, a, entry);
+ write_file(bsdtar, a, entry);
archive_entry_free(entry);
entry = spare_entry;
spare_entry = NULL;
@@ -931,18 +937,36 @@ write_hierarchy(struct bsdtar *bsdtar, struct archive *a, const char *path)
}
/*
- * Backend for write_entry.
+ * Write a single file (or directory or other filesystem object) to
+ * the archive.
+ */
+static void
+write_file(struct bsdtar *bsdtar, struct archive *a,
+ struct archive_entry *entry)
+{
+ write_entry(bsdtar, a, entry);
+}
+
+/*
+ * Write a single entry to the archive.
*/
static void
-write_entry_backend(struct bsdtar *bsdtar, struct archive *a,
+write_entry(struct bsdtar *bsdtar, struct archive *a,
struct archive_entry *entry)
{
int fd = -1;
int e;
+ size_t align = 4096;
if (archive_entry_size(entry) > 0) {
const char *pathname = archive_entry_sourcepath(entry);
+ /* TODO: Use O_DIRECT here and set 'align' to the
+ * actual filesystem block size. As of July 2010, new
+ * directory-traversal code is going in that will make
+ * it much easier to track filesystem properties like
+ * this during the traversal. */
fd = open(pathname, O_RDONLY | O_BINARY);
+ align = 4096;
if (fd == -1) {
bsdtar->return_value = 1;
if (!bsdtar->verbose)
@@ -974,7 +998,7 @@ write_entry_backend(struct bsdtar *bsdtar, struct archive *a,
* that case, just skip the write.
*/
if (e >= ARCHIVE_WARN && fd >= 0 && archive_entry_size(entry) > 0) {
- if (write_file_data(bsdtar, a, entry, fd))
+ if (write_file_data(bsdtar, a, entry, fd, align))
exit(1);
}
@@ -1018,19 +1042,26 @@ report_write(struct bsdtar *bsdtar, struct archive *a,
/* Helper function to copy file to archive. */
static int
write_file_data(struct bsdtar *bsdtar, struct archive *a,
- struct archive_entry *entry, int fd)
+ struct archive_entry *entry, int fd, size_t align)
{
ssize_t bytes_read;
ssize_t bytes_written;
int64_t progress = 0;
-
- bytes_read = read(fd, bsdtar->buff, FILEDATABUFLEN);
+ size_t buff_size;
+ char *buff = bsdtar->buff;
+
+ /* Round 'buff' up to the next multiple of 'align' and reduce
+ * 'buff_size' accordingly. */
+ buff = (char *)((((uintptr_t)buff + align - 1) / align) * align);
+ buff_size = bsdtar->buff + bsdtar->buff_size - buff;
+ buff_size = (buff_size / align) * align;
+
+ bytes_read = read(fd, buff, buff_size);
while (bytes_read > 0) {
if (need_report())
report_write(bsdtar, a, entry, progress);
- bytes_written = archive_write_data(a, bsdtar->buff,
- bytes_read);
+ bytes_written = archive_write_data(a, buff, bytes_read);
if (bytes_written < 0) {
/* Write failed; this is bad */
lafe_warnc(0, "%s", archive_error_string(a));
@@ -1044,7 +1075,7 @@ write_file_data(struct bsdtar *bsdtar, struct archive *a,
return (0);
}
progress += bytes_written;
- bytes_read = read(fd, bsdtar->buff, FILEDATABUFLEN);
+ bytes_read = read(fd, buff, buff_size);
}
if (bytes_read < 0) {
lafe_warnc(errno,
@@ -1066,7 +1097,7 @@ new_enough(struct bsdtar *bsdtar, const char *path, const struct stat *st)
/*
* If this file/dir is excluded by a time comparison, skip it.
*/
- if (bsdtar->newer_ctime_sec > 0) {
+ if (bsdtar->newer_ctime_filter) {
if (st->st_ctime < bsdtar->newer_ctime_sec)
return (0); /* Too old, skip it. */
if (st->st_ctime == bsdtar->newer_ctime_sec
@@ -1074,7 +1105,7 @@ new_enough(struct bsdtar *bsdtar, const char *path, const struct stat *st)
<= bsdtar->newer_ctime_nsec)
return (0); /* Too old, skip it. */
}
- if (bsdtar->newer_mtime_sec > 0) {
+ if (bsdtar->newer_mtime_filter) {
if (st->st_mtime < bsdtar->newer_mtime_sec)
return (0); /* Too old, skip it. */
if (st->st_mtime == bsdtar->newer_mtime_sec